**
LCD1602 STM32 HAl库
基于STM32F103C8T6实现lcd显示;
解决lcd1602老古董出现的系列问题
**
LCD简介
LCD模块原理相信各位已了解,在这里就不啰嗦了,直接进入分析代码部分
代码分析
纸上得来终觉浅,觉知此事需躬行。实践后才明白LCD1602能不能显示,关键在于数据是否通过IO口正确写入,也就是你要告诉LCD的话,传没传到它耳朵里。我这里采用较笨拙的方式,一位一位IO进行写入,能清晰的知道每一个字节的8位数据。
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, ((data>>7)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, ((data>>6)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, ((data>>5)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, ((data>>4)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, ((data>>3)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, ((data>>2)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, ((data>>1)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, ((data>>0)&0x01));
想过采用与或方式写入指令/数据信息,那样只需要一行代码即可,奈何本人对IO的操作没有那么熟练,故一位一位写入(这里这段代码稍微有点延时,也就是程序会有一丢丢的慢)
完整代码:(稍等片刻…)
仿真
实物图不易观察,这里采用proteus 8进行仿真。可实时观测到IO口状态,判断是屏幕显示问题还是代码数据/指令未正确写入。
老古董LCD1602显示问题
1、最主要问题,也就是LCD1602数据/指令的读取问题,若程序实在无法显示出字符,可采用这里的麻烦式代码,可能会帮到你
2、显示两排方块问题:
1)对比度未调节。VO脚接一定的电阻(2KΩ,方块淡化;3KΩ,方块无;4KΩ,方块无;4K以上暂未试过),这里建议接个滑动变阻器,也就是电位器,方便调试合适的显示度。
注:若是两排很暗的方块,直接接背光即可。
2)背光问题。A、K两脚接背光,背光一般会有点亮,但不影响屏幕显示,也可以接电位器调整亮度。
3、显示一排方块问题:
暂时未遇到,以我的理解可以尝试写指令0x38多次,在清一次屏试试看;至于是否与延时时长有关,本程序未使用忙检测、忙等待检测函数判断LCD状态,且延时函数采用自带的HAL_Delay()函数,对于单一LCD实验的情况,可能影响不大。
代码
#include "lcd1602.h"
#include "gpio.h"
#define uint unsigned int
#define uchar unsigned char
void send_to_lcd(char data,int rs)
{
RW(0);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, rs);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, ((data>>7)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, ((data>>6)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, ((data>>5)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, ((data>>4)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, ((data>>3)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, ((data>>2)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, ((data>>1)&0x01));
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, ((data>>0)&0x01));
EN(1);
HAL_Delay(2);
EN(0);
HAL_Delay(5);
}
int number_pow(char x,char y)
{
char i=0;
int result=1;
for(i=1;i<y;i++)
result*=x;
return result;
}
void write_cmd(char cmd)
{
char DATA;
DATA = ((cmd)&0xff);
send_to_lcd(DATA,0);
}
void write_data(char data)
{
char DATA;
DATA = ((data)&0xff);
send_to_lcd(DATA,1);
}
void lcd_clear(void)
{
write_cmd(0x01);
HAL_Delay(2);
}
void cursor_position(char x, char y)
{
char addr;
if (y == 0)
addr = 0x00 + x;
else
addr = 0x40 + x;
write_cmd(addr | 0x80);
}
void lcd_init()
{
write_cmd(0x38);
HAL_Delay(100);
write_cmd(0x38);
HAL_Delay(50);
write_cmd(0x38);
HAL_Delay(10);
write_cmd(0x0c);
HAL_Delay(10);
write_cmd(0x06);
HAL_Delay(10);
write_cmd(0x01);
}
void lcd_show(char x, char y,char *str)
{
cursor_position(x, y);
while(*str != '\0')
{
write_data(*str++);
}
while (*str) write_data (*str++);
}
void lcd_show2(char x, char y,char str)
{
cursor_position(x, y);
write_data(str);
while (*str) write_data (*str++);
}
void lcd_show3(char x,char y,int num,int len,int flag)
{
char i=0; cursor_position(x, y);
// for(i=len;i>0;i--)
// {
// if(flag) //1ÊÇʮ룬0ÊǸöλ
// {
// write_data('0'+num/number_pow(10,i-1)/10);
// }else write_data('0'+num/number_pow(10,i-1)%10);
// }
//}