STC12C5A60S2调试LCD1602
国庆假期,闲来无事,突然想起我还有几片STC12C5A60S2 [datasheet],还有一片STC12L5A60S2 [datasheet],对了,还有两片STC15FWA60S2 [datashet],其实,根据STC系列单片机命名方法,STCC5A60S2和STC12L5A60S2是一样的,只是供电电压有所不同,“C5”代表供电电压是5V,“L5”代表供电电压是3.3v的。芯片最高频率和芯片引脚的速度也有所不同。还有几片LCD1602,想来很久之前,没能驱动成功,这次再次发起挑战。
LCD1602接口定义:
1.RS——寄存器选择输入端
- RS=1:指向数据寄存器
- RS=0:指向指令寄存器
2.RW——读写控制输入端
- RW=1:读操作
- RW=0:写操作
3.E(EN)使能端
- 读操作时,高电平有效
- 写操作时,下降沿有效
4.D0-D7:数据输入输出端
LCD1602操作时序图:
底层函数
1.使能函数(必须使能LCD1602才能执行命令)
static void LCD_pulseEnable(void){
LCD_EN=0;
Delay_us(10);
LCD_EN=1;
Delay_us(10);
LCD_EN=0;
Delay_us(10);
// LCD_EN=1;
}
2.IO口操作函数
static void LCD_write4bits(unsigned char value){
DP=value&0xf0;
LCD_pulseEnable();
}
static void LCD_write8bits(unsigned char value){
DP=value&0xff;
LCD_pulseEnable();
}
3.数据输出函数
static void LCD_send(unsigned char value, unsigned char mode){
LCD_RW=1;
Delay_us(10);
LCD_RS=mode;
LCD_RW=0;
if(displayFunction&LCD_8BITMODE){
LCD_write8bits(value);
}else{
LCD_write4bits((value));
LCD_write4bits(value<<4);
}
LCD_RW=1;
LCD_RS=(!mode);
}
4.写命令
void LCD_Command(unsigned char value){
LCD_send(value, W_COMMAND);
}
5.写数据
char LCD_Write(unsigned char value){
LCD_send(value, W_DATA);
return 1;
}
硬件抽象层函数
1.初始化函数
- 初始化行数和列数
void LCD_Begin(unsigned char cols, unsigned char lines){
unsigned char dotsize=LCD_5x8DOTS;
pinInit(0, 0, PIN_MODE_OP);
portInit(1);
portInit(2);
if (lines > 1) {
displayFunction |= LCD_2LINE;
}
numLines = lines;
lcdCol=cols;
LCD_SetRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols);
// for some 1 line displays you can select a 10 pixel high font
if ((dotsize != LCD_5x8DOTS) && (lines == 1)) {
displayFunction |= LCD_5x10DOTS;
}
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
// according to datasheet, we need at least 40ms after power rises above 2.7V
// before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
Delay_ms(5);
LCD_RS=0;
LCD_EN=0;
LCD_RW=0;
//put the LCD into 4 bit or 8 bit mode
if (!(displayFunction & LCD_8BITMODE)){
// this is according to the hitachi HD44780 datasheet
// figure 24, pg 46
// we start in 8bit mode, try to set 4 bit mode
LCD_write4bits(0x03);
// delayMicroseconds(4500); // wait min 4.1ms
Delay_us(4500);
// second try
LCD_write4bits(0x03);
// delayMicroseconds(4500); // wait min 4.1ms
Delay_us(4500);
// third go!
LCD_write4bits(0x03);
// delayMicroseconds(150);
Delay_us(150);
// finally, set to 4-bit interface
LCD_write4bits(0x02);
}else{
// this is according to the hitachi HD44780 datasheet
// page 45 figure 23
// Send function set command sequence
LCD_Command(LCD_FUNCTIONSET | displayFunction);
// delayMicroseconds(4500); // wait more than 4.1ms
Delay_us(4500);
// second try
LCD_Command(LCD_FUNCTIONSET | displayFunction);
// delayMicroseconds(150);
Delay_us(150);
// third go
LCD_Command(LCD_FUNCTIONSET | displayFunction);
}
// finally, set # lines, font size, etc.
LCD_Command(LCD_FUNCTIONSET | displayFunction);
// turn the display on with no cursor or blinking default
displayControl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
LCD_Display();
// clear it off
LCD_Clear();
// Initialize to default text direction (for romance languages)
displayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
// set the entry mode
LCD_Command(LCD_ENTRYMODESET | displayMode);
}
- 初始化数据线(四线制或八线制)
void LCD_Init(unsigned char fourbitmode){
if(fourbitmode)
displayFunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
else
displayFunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
LCD_Begin(16, 1);
}
2.在指定位置显示一个字节
void LCD_DisplayChr(unsigned char col, unsigned char row, unsigned char value){
LCD_SetCursor(col,row);
LCD_Write(value);
}
3.在指定位置显示字符串
void LCD_DisplayStr(unsigned char col, unsigned char row, unsigned char code* str){
unsigned char i=0;
while(str[i]>=0x20){
LCD_DisplayChr(col+i, row, str[i]);
Delay_us(10);
if(i>(lcdCol-col) && ((numLines-row)>=1)){
LCD_DisplayChr((i-lcdCol+col-1), row+1, str[i]);
Delay_us(10);
}
i++;
}
}
测试
在main.c文件
void main(void){
unsigned char i,len=sizeof(t);
P00=0;
Delay_ms(1000);
P00=1;
LCD_Init(LINES_4);
LCD_Begin(16, 2);
LCD_Clear();
LCD_SetCursor(0,0);
LCD_DisplayChr(0, 0, 'A');
Delay_ms(100);
LCD_DisplayChr(1, 0, 'B');
Delay_ms(100);
LCD_DisplayChr(2, 0, 'C');
Delay_ms(100);
LCD_DisplayChr(3, 0, 'D');
Delay_ms(100);
LCD_DisplayChr(4, 0, 'E');
Delay_ms(100);
LCD_DisplayChr(0, 1, 'F');
Delay_ms(100);
LCD_DisplayChr(1, 1, 'G');
LCD_DisplayStr(0, 1, t); //通过
// LCD_DisplayStr(0, 1, "test,LCD!"; //通过
while(1);
}
code.zip 源码文件
2018/10/6 22:17:54 2018/10/6 22:17:55