STM32开发系列之Protues仿真LCD12864

很久没来CSDN这更新了,最近因为需要用到STM32F103R6来控制LCD12864显示屏,手中没有材料,就尝试用了Protues来仿真

一、创建Protues工程文件

现在Protues8.3版本已经支持STM32的仿真,但目前编译器支持GCC,所以我是创建了一个没有固件的工程,程序之后用Keil编写后导入。如何创建一个新的工程,我这里就不说了,网上有很多。

创建好工程后,从元件库里导入STM32F103R6和LCD12864,连接好电路,连接如下图所示
STM32开发系列之Protues仿真LCD12864_第1张图片

之后呢我们要配置供电网,在设计里面,把未连接到网络的GND,VCC接入网络,更改时钟频率,右击芯片选择编辑属性,我这里选的是常用的72M。

STM32开发系列之Protues仿真LCD12864_第2张图片
STM32开发系列之Protues仿真LCD12864_第3张图片

这样我们的仿真电路就弄好了,接下来开始写程序。

二、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++;
 }

对了,有一点,因为我这个是仿真的,LCD只能显示汉字,所以可能跟实际有一点差别,要自己调整。

你可能感兴趣的:(STM32,LCD12864)