《《《《《正文》》》》》
《前言》
本文主要介绍128x64点阵液晶屏的开发,本文是基于拓普微LM6029AC液晶模块显示屏开发的,兼容12864cog HFG12864-438液晶屏,驱动芯片为ST7565R ;通信串口采用4SPI;
《液晶模块》
首先来区别液晶模块和驱动芯片;
驱动芯片:其实我在《数码管是如何亮起来的?跟液晶屏又有什么关系?》这篇文章提过,因为128x64的com口以及seg口过多,如果使用单片机IO口直接驱动太费IO资源,二来IO口驱动能力也未必够;因此设计一款专门驱动128x64的芯片,这样使用spi等串口由单片机控制来实现对液晶屏的控制;
而液晶屏加驱动芯片以及一些必要的外围电路,留出单片机与驱动芯片的通信口的组合模块我们称为液晶模块;
《开发手册获取》
对于软件开发来讲,我们一般不太需要过多了解驱动芯片的手册,驱动芯片的手册更全面,也因此很多不是软件的知识,当然多了解总没错,往往只需要了解模块的开发手册,其实模块手册往往包含在驱动芯片手册里;只是模块手册写得已经足够软件开发的;
而模块手册,个人觉得只需了解下面几部分:
1、模块对外的接口定义
2、模块的命令
3、通信方式
驱动芯片手册 和 模块手册资源在最后下载;
1)通信方式:一般通信方式会有多种选择,往往通过硬件的IO电平组合来实现,我选择4SPI,需要P/S脚拉低;
对应实际模块需要焊接如下图:
传输时序:
黑色箭头的意思就是SCL由低拉高的时候,传输数据;
2)接口定义:这里唯一需要注意的就是当使用4SPI时,SCL为D6引脚,SI为D7引脚;RES是用来复位操作的,就是拉低一段时间,一般10ms,在驱动手册里有;CS1是片选;RS是控制传输的是命令数据还是显示数据;还有BLA背光控制脚;
3)模块命令:这个一般模块手册有;没有去找驱动手册;这个是总的命令表格,详细的我们在后面开发介绍;
《硬件接口》
使用stm32f103c8t6芯片,引脚接线如下:
《软件开发》
1)开发环境:这个自己解决!可参考以下文章
2)SysTick延时函数:(网上到处都是)
《一文透析SYSTICK的寄存器》参考本文;
void Delay_Init(void);
void Delay_us(uint32_t nus);
void Delay_ms(uint32_t nms);
3)LCD驱动口初始化函数:
/**********
硬件接口:
BAL CS1 RST SID SCLK RS
PA0 PA3 PA4 PA2 PA1 PA5
********************/
/******************************************************************************
* 函 数:
* 功 能:LCD12864引脚初始化
* 参 数:无
* 返回值:无
* 备 注:无
*******************************************************************************/
void LCD_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_4|GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
}
并宏定义IO电平的操作函数:
/******************************************************************************
* 函 数:
* 功 能:IO口操作宏定义
* 参 数:电平:Bit_RESET表示输出低;Bit_SET表示输出高;
* 返回值:无
* 备 注:无
*******************************************************************************/
#define BLA(x) GPIO_WriteBit(GPIOA,GPIO_Pin_0,x)
#define CS1(x) GPIO_WriteBit(GPIOA,GPIO_Pin_3,x)
#define RST(x) GPIO_WriteBit(GPIOA,GPIO_Pin_4,x)
#define SID(x) GPIO_WriteBit(GPIOA,GPIO_Pin_2,x)
#define SCLK(x) GPIO_WriteBit(GPIOA,GPIO_Pin_1,x)
#define RS(x) GPIO_WriteBit(GPIOA,GPIO_Pin_5,x)
4)4SPI发送8bit数据函数
/******************************************************************************
* 函 数:
* 功 能:LCD12864的4SPI发送8bit数据函数
* 参 数:数据
* 返回值:无
* 备 注:无
*******************************************************************************/
void SendByte(uint8_t dat)
{
uint8_t i;
for(i = 0;i < 8;i++)
{
if((dat << i) & 0x80) //0x80(1000 0000) 只会保留最高位
{
SID(Bit_SET); // 引脚输出高电平,代表发送1
}
else
{
SID(Bit_RESET); // 引脚输出低电平,代表发送0
}
SCLK(Bit_RESET); //时钟线置低 允许SID变化
Delay_us(5); //延时使数据写入
SCLK(Bit_SET); //拉高时钟,让从机读SID
}
}
5)写命令函数
/******************************************************************************
* 函 数:
* 功 能:LCD12864写命令函数
* 参 数:数据
* 返回值:无
* 备 注:无
*******************************************************************************/
void Lcd_WriteCmd(uint8_t cmd)
{
RS(Bit_RESET); //拉低表示命令
Delay_ms(1);
SendByte(cmd);
}
6)写数据函数
/******************************************************************************
* 函 数:
* 功 能:LCD12864写数据函数
* 参 数:数据
* 返回值:无
* 备 注:无
*******************************************************************************/
void Lcd_WriteData(uint8_t data)
{
RS(Bit_SET);//拉高表示数据
Delay_ms(1);
SendByte(data);
}
7)LCD12864初始化函数
/******************************************************************************
* 函 数:
* 功 能:LCD12864初始化函数
* 参 数:数据
* 返回值:无
* 备 注:无
*******************************************************************************/
void HFG12864_Init(void)
{
BLA(Bit_SET); //打开背光
CS1(Bit_RESET); //使能片选
SID(Bit_SET); //释放SID
SCLK(Bit_SET); //释放SCLK
RST(Bit_RESET); //复位LCD
Delay_ms(100);
RST(Bit_SET);
Lcd_WriteCmd(0xa0); //seg方向选择
Lcd_WriteCmd(0xc8); //com方向选择
Lcd_WriteCmd(0xa2); //偏压比设置
Lcd_WriteCmd(0x2C);
Lcd_WriteCmd(0x2e);
Lcd_WriteCmd(0x2f);
Lcd_WriteCmd(0xa6);
Lcd_WriteCmd(0x24);
Lcd_WriteCmd(0x81); //对比度电流量设置
Lcd_WriteCmd(0x20); //对比度电流量设置
//Delay_ms(100);
Lcd_WriteCmd(0xAF); //开显示
//Lcd_WriteCmd(0xa5); //开显示
//Delay_ms(10);
}
8)设置显示页函数
/******************************************************************************
* 函 数:
* 功 能:设置显示页函数
* 参 数:页数
* 返回值:无
* 备 注:无
*******************************************************************************/
void HFG12864_SetPage(uint8_t page)
{
page = page&0x0F;
page = page|0xB0;
Lcd_WriteCmd(page);
}
9)设置显示列函数
/******************************************************************************
* 函 数:
* 功 能:设置显示列函数
* 参 数:列数
* 返回值:无
* 备 注:无
*******************************************************************************/
void HFG12864_SetColumn(uint8_t column)
{
uint8_t tmp;
tmp = column;
column = column&0x0F;
column = column|0x00;
Lcd_WriteCmd(column);
tmp = tmp>>4;
column = tmp&0x0F;
column = column|0x10;
Lcd_WriteCmd(column);
}
10)清屏函数
/******************************************************************************
* 函 数:
* 功 能:清屏函数
* 参 数:无
* 返回值:无
* 备 注:无
*******************************************************************************/
void HFG12864_ClearScr(void)
{
uint8_t i,j;
for(i=0;i<8;i++)
{
HFG12864_SetPage(i);
HFG12864_SetColumn(0);
for(j=0;j<128;j++)
{
Lcd_WriteData(0x00);
}
}
}
《测试效果》
我把清屏函数数据改为0x0f;
效果如下:
资源获取:
链接:https://pan.baidu.com/s/1ZHrAEaiJ6g7Z6Rb7UHLpgw
关注公众号,发送1234获取提取码;
《《《《《END》》》》》