很久没来CSDN这更新了,最近因为需要用到STM32F103R6来控制LCD12864显示屏,手中没有材料,就尝试用了Protues来仿真
现在Protues8.3版本已经支持STM32的仿真,但目前编译器支持GCC,所以我是创建了一个没有固件的工程,程序之后用Keil编写后导入。如何创建一个新的工程,我这里就不说了,网上有很多。
创建好工程后,从元件库里导入STM32F103R6和LCD12864,连接好电路,连接如下图所示
之后呢我们要配置供电网,在设计里面,把未连接到网络的GND,VCC接入网络,更改时钟频率,右击芯片选择编辑属性,我这里选的是常用的72M。
这样我们的仿真电路就弄好了,接下来开始写程序。
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++;
}
对了,有一点,因为我这个是仿真的,LCD只能显示汉字,所以可能跟实际有一点差别,要自己调整。