最近因为需要用到STM32F103R6来控制LCD12864显示屏,手中没有材料,就尝试用了Protues来仿真
一、创建Protues工程文件
现在Protues8.3版本已经支持STM32的仿真,但目前编译器支持GCC,所以我是创建了一个没有固件的工程,程序之后用Keil编写后导入。如何创建一个新的工程,我这里就不说了,网上有很多。
创建好工程后,从元件库里导入STM32F103R6和LCD12864,连接好电路,连接如下图所示
之后呢我们要配置供电网,在设计里面,把未连接到网络的GND,VCC接入网络,更改时钟频率,右击芯片选择编辑属性,我这里选的是常用的72M。
这样我们的仿真电路就弄好了,接下来开始写程序。
二、LCD程序
lcd头文件
- #define LCD_RS_PIN GPIO_Pin_4
- #define LCD_RW_PIN GPIO_Pin_5
- #define LCD_EN_PIN GPIO_Pin_6
- #define LCD_SWE_PORT GPIOA
- #define LCD_RS(n) (n==1)? GPIO_SetBits(LCD_SWE_PORT,LCD_RS_PIN):GPIO_ResetBits(LCD_SWE_PORT,LCD_RS_PIN)
- #define LCD_RW(n) (n==1)? GPIO_SetBits(LCD_SWE_PORT,LCD_RW_PIN):GPIO_ResetBits(LCD_SWE_PORT,LCD_RW_PIN)
- #define LCD_EN(n) (n==1)? GPIO_SetBits(LCD_SWE_PORT,LCD_EN_PIN):GPIO_ResetBits(LCD_SWE_PORT,LCD_EN_PIN)
复制代码
lcd12864引脚初始化
- RCC->APB2ENR |= 1<<2; //使能A口时钟
-
- GPIOA->CRL &= 0x0000FFFF;
- GPIOA->CRL |= 0x33330000; //设置PA4(RS),PA(5)RW,PA(6)E.PA(7)RST为推挽输出50Mhz
-
- RCC->APB2ENR |= 1<<3; //使能B口时钟
-
- GPIOB->CRH &= 0;
- GPIOB->CRH |= 0x33333333;
复制代码
数据脚配置为输入或输出
- GPIO_InitTypeDef GPIO_Initstructure;
- GPIO_Initstructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
- GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(GPIOB,&GPIO_Initstructure);
- GPIOB->ODR |= 0xff<<8;
复制代码
- GPIO_InitTypeDef GPIO_Initstructure;
- GPIO_Initstructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
- GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&GPIO_Initstructure);
- GPIOB->ODR |= 0xFF<<8;
复制代码
LCD屏初始化
- LCD12864_GPIO_INIT();
- LCD_Write_cmd(0x30);
- LCD_Write_cmd(0x0C);
- LCD_Write_cmd(0x01);
复制代码
等待数据脚空闲
- LCD_RS(0);
- delay_us(1);
- LCD_RW(1);
- delay_us(1);
- do{
- LCD_EN(1);
- delay_us(1);
-
- LCD12864_Input();
- sta = GPIO_ReadInputData(GPIOB);
-
- LCD_EN(0);
- delay_us(1);
-
- LCD12864_Output();
- delay_us(1);
- }while(sta & 0x8000);
复制代码
写命令
- LCD_Wait_Ready();
- LCD_RS(0);
- delay_us(1);
- LCD_RW(0);
- delay_us(1);
- GPIOB->ODR &= 0X00FF;
- GPIOB->ODR |= cmd<<8;
- delay_us(10);
- LCD_EN(1);
- delay_us(1);
- LCD_EN(0);
- delay_us(1);
复制代码
写数据
- LCD_Wait_Ready();
- LCD_RS(1);
- delay_us(1);
- LCD_RW(0);
- delay_us(1);
- GPIOB->ODR &= 0X00FF;
- GPIOB->ODR |= data<<8;
- delay_us(10);
- LCD_EN(1);
- delay_us(1);
- LCD_EN(0);
- delay_us(1);
复制代码
起始位置设置
- unsigned char i;
- switch(x)
- {
- case 0x00: i=0x80;
- break;
- case 0x01: i=0x90;
- break;
- case 0x02: i=0x88;
- break;
- case 0x03: i=0x98;
- break;
- default: break;
- }
- i=y+i;
- //LCD_Write_cmd(0x30);
- LCD_Write_cmd(i);
复制代码
中文显示
- LCD_Set_Cursor(x,y);
- while(*data != '\0')
- {
- LCD_Write_data(*data);
- data++;
- }
复制代码
|