【STM32学习】(17)STM32实现LCD12864显示 - 串行实现

源码下载链接:(1条消息) STM32实现LCD12864显示-串行实现-电信文档类资源-CSDN下载

关于LCD12864的资料,我先给大家贴一点出来。

工作于并行模式时的引脚定义:

PIN1------------------GND   电源接入-,一般接0V(视具体液晶型号)

PIN2------------------电源接入+,一般接5V(视具体液晶型号)

PIN3------------------对比度调整端,VDD和GND接可调电阻两端,中间抽头接至V0

PIN4------------------RS指令/数据选择

PIN5------------------R/W读写选择

PIN6------------------E,使能信号

PIN7------------------D0,数据位0

PIN8------------------D1,数据位1

PIN9------------------D2,数据位2

PIN10------------------D3,数据位3

PIN11------------------D4,数据位4

PIN12------------------D5,数据位5

PIN13------------------D6,数据位6

PIN14------------------D7,数据位7

PIN15------------------PSB  并行:PSB=1,可以接VCC,串行:PSB=0,一般接GND

PIN16------------------NC,不连接

PIN17------------------~RST,模块复位,可不连接

PIN18------------------NC,不连接

PIN19------------------LED+,背光+,一般接5V(视具体液晶型号)

PIN20------------------LED-,背光-,一般接GND

工作于串行模式时的引脚定义:

PIN1------------------GND   电源接入-,一般接0V(视具体液晶型号)

PIN2------------------电源接入+,一般接5V(视具体液晶型号)

PIN3------------------对比度调整端,VDD和GND接可调电阻两端,中间抽头接至V0

PIN4------------------RS(CS),片选

PIN5------------------R/W(SID),数据

PIN6------------------E(SCK),脉冲

PIN7------------------NC,不连接

PIN8------------------NC,不连接

PIN9------------------NC,不连接

PIN10------------------NC,不连接

PIN11------------------NC,不连接

PIN12------------------NC,不连接

PIN13------------------NC,不连接

PIN14------------------NC,不连接

PIN15------------------PSB  并行:PSB=1,可以接VCC,串行:PSB=0,一般接GND

PIN16------------------NC,不连接

PIN17------------------~RST,模块复位,可不连接

PIN18------------------NC,不连接

PIN19------------------LED+,背光+,一般接5V(视具体液晶型号)

PIN20------------------LED-,背光-,一般接GND

12864液晶并口驱动程序用的比较多,但是考虑到有的时候单片机或者MCU的IO口有限时就可以使用串行驱动方法。以下是12864液晶串行时序图,下面就根据这个图来分析一下12864串行时序的实现,只有真正弄清楚了时序图才能真正了解串行传输的原理。

从图上可以看出串行传输时需要用到CS,SCLK,SID三根信号线,但是由于CS是高电平有效,所以也可以把CS长接高电平,那样就只需要两根线就OK了,当然当使用12864串行模式时,PSB引脚必须接低电平,复位RST引脚可以悬空不接,因为12864内部有上电复位电路。

由于数据是传输是以一个字节8bits为单位,所以下面贴出传输一个字节的函数实现

从时序图上可以看出,要想完整的把一个字节的数据传出去,需要传送三次才能实现,也就是需要传送三个字节,这三个字节分别是:命令控制字,字节的高四位+低四位0组成的字节,字节的低四位+高四位0组成的字节。

                                                                    命令控制字11111RWRS0

RW代表读还是写液晶,为0代表写,为1代表读。RS代表写命令还是数据,为0代表写命令,为1代表写数据,其余6位固定。所以假设要向液晶写数据,就必须首先发送11111010,写命令就发送11111000。

下面是程序的具体实现,这是关键!
硬件:

单片机型号:STM32L052K8*     其实不管哪款单片机实现效果是一样的

液晶型号:LCD12864

接线:

PA0  接   RS(CS)

PA1  接   R/W(SID)

PA2  接   E(SCK)

PA3  接   RST    这个可以不接,悬空或接高电平(VCC),液晶内部有上电复位的功能,看自己的实现需要添加

lcd12864.c

#include "lcd12864.h"
#include "main.h"
/******************************************
*名称:void Write_8bits(uint8_t W_bits)
*功能:按照液晶的串口通信协议,发送数据
*输入:W_bits
*输出:无
*******************************************/
 
void Write_8bits(uint8_t W_bits)
{
	uint8_t i,Temp_data;
	for(i=0; i<8; i++)//总共移动八次,就可以把8bits数据全部传完
	{
		Temp_data = W_bits;
		Temp_data <<= i;//把数据依次左移
		if((Temp_data&0x80)==0)  //判断对应位是否为0
		{
			HAL_GPIO_WritePin(SID_GPIO_Port,SID_Pin,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(CLK_GPIO_Port,CLK_Pin,GPIO_PIN_RESET);	//SCLK = 0;//在时钟的下降沿把数据传输出去
			HAL_GPIO_WritePin(CLK_GPIO_Port,CLK_Pin,GPIO_PIN_SET);		// SCLK = 1;//置高电平,为下次传输做准备
		}
		else         //对应位为1
		{
			HAL_GPIO_WritePin(SID_GPIO_Port,SID_Pin,GPIO_PIN_SET);		//SID = 1;
			HAL_GPIO_WritePin(CLK_GPIO_Port,CLK_Pin,GPIO_PIN_RESET);	//SCLK = 0;//在时钟的下降沿把数据传输出去
			HAL_GPIO_WritePin(CLK_GPIO_Port,CLK_Pin,GPIO_PIN_SET);		// SCLK = 1;//置高电平,为下次传输做准备
		}
	}
}

 
/****************************************
*名称:void W_1byte(uint8_t RW, uint8_t RS, uint8_t W_data)
*功能:写串口数据,根据RW RS的配置,确定是传输命令还是传输数据
*输入:uint8_t RW, uint8_t RS, uint8_t W_data
*输出:无
******************************************/
void W_1byte(uint8_t RW, uint8_t RS, uint8_t W_data)
{ 
	uint8_t H_data,L_data,S_ID = 0xf8;  //11111RWRS0
	if(RW == 0)
	{
		S_ID &=~ 0x04;
	}
	else     //if(RW==1)
	{
		S_ID |= 0X04;
	}
	if(RS == 0)
	{
		S_ID &=~ 0x02;
	}                                                                                                                               
	else     //if(RS==1)
	{
		S_ID |= 0X02;
	}
	//以上是根据读写命令以及是发送数据还是命令来组合命令字
	H_data = W_data;
	H_data &= 0xf0;   //屏蔽低4位的数据
	L_data = W_data;    //xxxx0000格式
	L_data &= 0x0f;   //屏蔽高4位的数据
	L_data <<= 4;   //xxxx0000格式
	HAL_GPIO_WritePin(CS_GPIO_Port,CS_Pin,GPIO_PIN_SET);	//CS = 1; 时能发送
	Write_8bits(S_ID);   //发送命令字S_ID
	Write_8bits(H_data); //发送H_data
	Write_8bits(L_data); //发送L_data
	HAL_GPIO_WritePin(CS_GPIO_Port,CS_Pin,GPIO_PIN_RESET);	//CS = 0; 时能发送
} 

 
/*****************************************
*功能:lcdinit()
*功能:初始化函数
*输入:cmdcode
*输出:无
*****************************************/
 
void lcdinit(void)
{
	
	HAL_Delay(10);
	W_1byte(0,0,0x30);//功能设置 8位数据,基本指令;
	HAL_Delay(10);
	//W_1byte(0,0,0x02); //地址归位
	//HAL_Delay(10);
	//W_1byte(0,0,0x06); //游标及显示右移一位
	//HAL_Delay(10);
	W_1byte(0,0,0x0c); //显示状态 ON,游标OFF,反白OFF
	HAL_Delay(10);
	W_1byte(0,0,0x01);  //清除显示
	HAL_Delay(10);
}
 
 

 
/******************************************
*名称:void LCD_Wmessage(uint8_t* message,uint8_t address)
*功能:向LCD12864中写入一行数据(因为你不可能每次只发送一字节数据)
*输入:uint8_t* message,uint8_t address
*输出:无
******************************************/
 
void LCD_Wmessage(uint8_t* message,uint8_t address)
{
	W_1byte(0, 0, address);
	while(*message>0)//这个判断很关键,判断你的内容有没有发完
	{
		W_1byte(0,1,*message); //内核还是发字节函数
		message++; //指针挺好用的。。
	}
}

lcd12864.h

#include "main.h"

#define			LINE1		0x80 //第一行起始地址,下同
#define			LINE2 		0x90
#define			LINE3 		0x88
#define			LINE4 		0x98

void Write_8bits(uint8_t W_bits);
void W_1byte(uint8_t RW, uint8_t RS, uint8_t W_data);
void lcdinit(void);
void LCD_Wmessage(uint8_t *message,uint8_t address);

main.c

int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t dis3[]={"床前明月光,"};
	uint8_t dis4[]={"疑是地上霜,"};
	uint8_t dis5[]={"举头望明月,"};
	uint8_t dis6[]={"低头思故乡。"};
  /* USER CODE END 1 */

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

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

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

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

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
	MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	lcdinit();
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	LCD_Wmessage(dis3,LINE1);  
	LCD_Wmessage(dis4,LINE2);
	LCD_Wmessage(dis5,LINE3);
	LCD_Wmessage(dis6,LINE4);
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

效果如下:

代码下载链接:(1条消息) STM32实现LCD12864显示-串行实现-电信文档类资源-CSDN下载

 

 

 

 

 

 

  • 15
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小材大用

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值