STM32F072 NUCLEO笔记3-移植12864液晶程序

时间:2021-10-23 06:36:43

STM32F072笔记3-移植12864液晶程序

本文例子用到:

1.  STM32F072 Nucleo开发板

STM32F072 NUCLEO笔记3-移植12864液晶程序

2.  12864液晶

STM32F072 NUCLEO笔记3-移植12864液晶程序


3.  STM32CubeMX软件Version4.3.0

STM32F072 NUCLEO笔记3-移植12864液晶程序

4.  Keil MDK 软件Version5.12.0.0

STM32F072 NUCLEO笔记3-移植12864液晶程序


下面开始讲解:

         首先讲一下思路。本文将MSP430单片机(16位)控制12864的程序移植到STM32F072控制12864。其实控制12864实际上就是对IO口进行写0或者写1的操作,不同单片机控制IO口输出0或1方法不同,比如MSP430将IO口置一为P1OUT|=BIT0;将IO口清零则为P1OUT~=BIT0;(此处是将MSP430的P10进行置一与清零);而STM32利用库函数将IO口置一为HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET);将IO清零则为HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_RESET);(此处是将STM32的PB13置一与清零);只需要将MSP430控制IO口的程序改为STM32控制IO口的程序就行,另外,由于不同单片机时钟频率不一样,运行速度不一样,因此可能需要改一下移植程序中的延时。(另外,IO口配置输入输出的方式也需要改)

         12864液晶有并行和串行两种接线方式,本文采用串行控制。串行控制至少需要将液晶的三个IO口连到STM32的IO口。分别是片选信号CS(RS),数据信号SID(RW),时钟信号SCLK(E),PSB直接接到GND,RST可以不接。

 

         接下来开始讲讲实际怎么操作。

1.      通过STM32CubeMX软件配置IO口。本文IO口接法:

PB13------------------CS(RS)

PB14------------------SID(RW)

PB15------------------SCLK(E)

GND-------------------PSB

GND-------------------VSS

+5V--------------------VDD

GND-------------------LEDK

+5V--------------------LEDA

STM32Cube配置如下:

STM32F072 NUCLEO笔记3-移植12864液晶程序

2.      STM32Cube其他配置默认,生成Keil工程。

3.      首先看看要移植的lcd12864程序:

#define uchar unsigned char
#define uint unsigned int
#define LCD12864_CS_OUT P1DIR|=BIT4
#define LCD12864_CS_H P1OUT|=BIT4
#define LCD12864_CS_L P1OUT&=~BIT4

#define LCD12864_SID_OUT P1DIR|=BIT2
#define LCD12864_SID_H P1OUT|=BIT2
#define LCD12864_SID_L P1OUT&=~BIT2

#define LCD12864_SCLK_OUT P1DIR|=BIT3
#define LCD12864_SCLK_H P1OUT|=BIT3
#define LCD12864_SCLK_L P1OUT&=~BIT3

//PSB由硬件置低,故省去
//#define LED12864_PSB_OUT P1DIR|=BIT5
//#define LED12864_PSB_L P1OUT&=~BIT5
//RST不接也行
//#define LCD12864_RST_OUT P1DIR|=BIT6
//#define LCD12864_RST_H P1OUT|=BIT6
//#define LCD12864_RST_L P1OUT&=~BIT6


/********************************************************************
* 名称 : delay()
* 功能 : 软件延时
* 输入 : t
* 输出 : 无
***********************************************************************/
void delay(unsigned int t)
{
unsigned int i,j;
for(i=0; i<t; i++)
for(j=0; j<3; j++);
}

/********************************************************************
* 名称 : sendbyte()
* 功能 : 按照液晶的串口通信协议,发送数据
* 输入 : zdata
* 输出 : 无
***********************************************************************/
void sendbyte(unsigned char zdata)
{
unsigned int i;
for(i=0; i<8; i++)
{
if((zdata << i) & 0x80)
{
LCD12864_SID_H;//SID=1
}
else
{
LCD12864_SID_L ;
}
LCD12864_SCLK_L;//SCLK = 0;
LCD12864_SCLK_H;//SCLK = 1;
}
}

/********************************************************************
* 名称 : write_com()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_com(unsigned char cmdcode)
{
LCD12864_CS_H ;//CS = 1;
sendbyte(0xf8);
sendbyte(cmdcode & 0xf0);
sendbyte((cmdcode << 4) & 0xf0);
delay(1);
}

/********************************************************************
* 名称 : write_data()
* 功能 : 写串口数据
* 输入 : Dispdata
* 输出 : 无
***********************************************************************/
void write_data(unsigned char Dispdata)
{
LCD12864_CS_H ;//CS = 1;
sendbyte(0xfa);
sendbyte(Dispdata & 0xf0);
sendbyte((Dispdata << 4) & 0xf0);
delay(1);
}

/********************************************************************
* 名称 : init()
* 功能 : 初始化函数
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void lcd12864_init()
{
LCD12864_CS_OUT ;
LCD12864_SID_OUT ;
LCD12864_SCLK_OUT ;
//LED12864_PSB_OUT ;
//LCD12864_RST_OUT ;
//LED12864_PSB_L;
//LCD12864_RST_L;//RST = 0;
//delay_ms(100);
//LCD12864_RST_H;//RST = 1;
//delay_ms(5);
write_com(0x30);
delay(2000);
write_com(0x0c);
delay(2000);
write_com(0x01);
}

// *清除图像显示
void clearLCD(void)
{

uchar i, j;

write_com(0x36);// 8位,扩充指令集,图形显示开
for (i = 0; i < 32; i++)// 32行,12864=25632
{
write_com(0x80 + i);// 绘图区的Y地址
write_com(0x80);// 绘图区的X地址
for (j = 0; j < 32; j++) {
write_data(0x00);// 清除
}
}
write_com(0x30);// 8位,基本指令集
}


void pos(uchar x,uchar y) //*设定LCD写位置
{
uchar pos;
if(x==0) x=0x80;
else if(x==1) x=0x90;
else if(x==2) x=0x88;
else if(x==3) x=0x98;
pos=x+y;
write_com(pos);
}


4.上面的程序写的比较规范,IO口控制都是通过宏定义,我们只需要将

#define LCD12864_CS_OUT P1DIR|=BIT4
#define LCD12864_CS_H P1OUT|=BIT4
#define LCD12864_CS_L P1OUT&=~BIT4


改为

#define LCD12864_CS_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_SET)
#define LCD12864_CS_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_RESET)


由于在STM32Cube中我们已经将对于IO口配置为输出,故

#define LCD12864_CS_OUT P1DIR|=BIT4可以不用理会。

其他IO配置相同。总的配置如下:


#define LCD12864_CS_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_SET)
#define LCD12864_CS_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_RESET)

#define LCD12864_SID_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,GPIO_PIN_SET)
#define LCD12864_SID_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,GPIO_PIN_RESET)

#define LCD12864_SCLK_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15,GPIO_PIN_SET)
#define LCD12864_SCLK_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15,GPIO_PIN_RESET)

再看看lcd12864初始化函数:

void lcd12864_init()
{
LCD12864_CS_OUT ;
LCD12864_SID_OUT ;
LCD12864_SCLK_OUT ;
//LED12864_PSB_OUT ;
//LCD12864_RST_OUT ;
//LED12864_PSB_L;
//LCD12864_RST_L;//RST = 0;
//delay_ms(100);
//LCD12864_RST_H;//RST = 1;
//delay_ms(5);
write_com(0x30);
delay(2000);
write_com(0x0c);
delay(2000);
write_com(0x01);
}

由于我们在STM32Cube中已经将IO口设置为输出,故可以将

   LCD12864_CS_OUT;

   LCD12864_SID_OUT;

   LCD12864_SCLK_OUT;

这三句删除。


5.      由于12864液晶对延时要求不是很严格,故此处不用改延时,如果出现问题,可以尝试改改延时程序。

6.      将修改好的程序放入生成的keil工程中,放在

/* USER CODE BEGIN 0 */与/* USER CODE END 0*/之间

7.      最后,写个小程序测试一下。

main函数如下:

int main(void)
{
/* USER CODE BEGIN 1 */
int i=0;
unsigned char a[]="--Hello Nucleo!-";
unsigned char b[]="--Hello World!--";
unsigned char c[]="--Hello STMCU!--";
unsigned char d[]=" ~@^_^@~ ";
/* USER CODE END 1 */

/* MCU Configuration----------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

/* Initialize all configured peripherals */
MX_GPIO_Init();

/* USER CODE BEGIN 2 */
lcd12864_init();//lcd12864液晶初始化
delay(10000);//适当延时
pos(0,0);//设置显示起始位置
for(i=0;i<16;i++)//设置显示内容
{
write_data(a[i]);
}
pos(1,0);
for(i=0;i<16;i++)
{
write_data(b[i]);
}
pos(2,0);
for(i=0;i<16;i++)
{
write_data(c[i]);
}
pos(3,0);
for(i=0;i<16;i++)
{
write_data(d[i]);
}
/* USER CODE END 2 */

/* USER CODE BEGIN 3 */
/* Infinite loop */
while (1)
{

}
/* USER CODE END 3 */

}

显示效果如下:

STM32F072 NUCLEO笔记3-移植12864液晶程序



                                                                                                                                HJL

                                                                                                                                2015.1.20