这里我们只讲解接线和代码实现,具体的原理在上一篇博客中已经讲解,如果想了解具体原理可以查看上一篇博客
《STM32 LCD12864 串行通信模式 (从原理让你理解)》https://blog.csdn.net/as480133937/article/details/97650805
下方代码的实现也是基于上一篇的讲解顺序来的
设备: STM32F407ZGT6
引脚接线:
VSS——GND
VDD——VCC(5V or 3.3V)
CS ——接VCC,持续高电平,一直选通。
SID ——接PE0
SCLK ——接PE1
PSB——接GND 串行模式 或者飞线与1脚相连
BLA——VCC(5V or 3.3V) 或者飞线与2脚相连
BLK——接GND 或者飞线与1脚相连
剩余引脚不接,留空
这样我们最少只会用到4根线 VCC电源 GND地线 SID串行输入 SCLK 时钟 便可以实现串行通信LCD写入一个字节:
#define WRITE_CMD 0xF8//写命令
#define WRITE_DAT 0xFA//写数据
/*!
* @brief LCD串行发送一个字节
* @since v1.0
* @param byte 写入字节
* @author Z小旋
*/
void SendByte(u8 byte)
{
u8 i;
for(i = 0;i < 8;i++)
{
if((byte << i) & 0x80) //0x80(1000 0000) 只会保留最高位
{
SID = 1; // 引脚输出高电平,代表发送1
}
else
{
SID = 0; // 引脚输出低电平,代表发送0
}
/*或
SID = (Dbyte << i) & 0x80;
上面那样为了方便理解
*/
SCLK = 0; //时钟线置低 允许SID变化
delay_us(5); //延时使数据写入
SCLK = 1; //拉高时钟,让从机读SID
}
}
/*!
* @brief LCD写指令
* @since v1.0
* @param Cmd 要写入的指令
* @author Z小旋
*/
void Lcd_WriteCmd(u8 Cmd )
{
delay_ms(1); //由于我们没有写LCD正忙的检测,所以直接延时1ms,使每次写入数据或指令间隔大于1ms 便可不用写忙状态检测
SendByte(WRITE_CMD); //11111,RW(0),RS(0),0
SendByte(0xf0&Cmd); //高四位
SendByte(Cmd<<4); //低四位(先执行<<)
}
/*!
* @brief LCD写数据
* @since v1.0
* @param Dat 要写入的数据
* @author Z小旋
*/
void Lcd_WriteData(u8 Dat )
{
delay_ms(1); //由于我们没有写LCD正忙的检测,所以直接延时1ms,使每次写入数据或指令间隔大于1ms 便可不用写忙状态检测
SendByte(WRITE_DAT); //11111,RW(0),RS(1),0
SendByte(0xf0&Dat); //高四位
SendByte(Dat<<4); //低四位(先执行<<)
}
向LCD发送一个字节,也就是SID引脚相对于高低电平 高电平=1 低电平=0 同时时钟线变化,使得数据可以读取和发送
结合第一篇原理介绍即可理解。
关于&运算与<< 参看 《C语言运算符与操作符的用法全面汇总(非常有用)》
LCD初始化:
这里为了方便移植,将GPIO的初始化与LCD初始化分为两个,使用时根据自己的引脚只修改GPIO初始化即可
宏定义和GPIO初始化:
#define WRITE_CMD 0xF8//写命令
#define WRITE_DAT 0xFA//写数据
//接口(SID: PE1 SCLK: PE0)
#define SID PEout(1)
#define SCLK PEout(0)/*!
* @brief GPIO_init
* @since v1.0
* @param None
* @author Z小旋
* 使用时自行修改这里的初始化即可
*/
void lcd_GPIO_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
//GPIOE0,E1初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化
SID=1;
SCLK=1;
}
根据不同的型号和管脚修改对应初始化即可
LCD初始化:
/*!
* @brief LCD初始化
* @since v1.0
* @param None
* @author Z小旋
*/
void Lcd_Init(void)
{
delay_ms(50); //等待液晶自检(延时>40ms)
Lcd_WriteCmd(0x30); //功能设定:选择基本指令集 ,选择8bit数据流
delay_ms(1);//延时>137us
Lcd_WriteCmd(0x0c); //开显示
delay_ms(1); //延时>100us
Lcd_WriteCmd(0x01); //清除显示,并且设定地址指针为00H
delay_ms(30); //延时>10ms
Lcd_WriteCmd(0x06); //每次地址自动+1,初始化完成
}
有点太多了,还要重新排版,有需要的话直接看下下面的把
欢迎光临 (http://www.51hei.com/bbs/) | Powered by Discuz! X3.1 |