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

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

本文例子用到:

1.  STM32F072 Nucleo开发板

STM32F072 NUCLEO笔记3-移植12864液晶程序_第1张图片

2.  12864液晶

STM32F072 NUCLEO笔记3-移植12864液晶程序_第2张图片


3.  STM32CubeMX软件Version4.3.0

STM32F072 NUCLEO笔记3-移植12864液晶程序_第3张图片

4.  Keil MDK 软件Version5.12.0.0



下面开始讲解:

         首先讲一下思路。本文将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液晶程序_第4张图片

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液晶程序_第5张图片



                                                                                                                                HJL

                                                                                                                                2015.1.20


你可能感兴趣的:(单片机,stm32,12864液晶,nucleo)