刚调好LCD1602之后,又做了个PC串口与单片机的通讯的程序,完成了根本的COM口的功用,从PC机上经过串口发出来的字符,能够在1602液晶上面显现出来。
完成的根本功用是:
1,BACKSPACE功用,支撑删去键,可是仅限于本行;
2,ENTER功用,回车&换行功用,当一行输入的时分按下ENTER键,即可切换并且清空新行;
3,ESC键功用,一切的显现铲除,光标清零;
4,单行循环显现,具有主动回车功用,当一行中的字符到结尾是主动清空本行,并且在本行的最初显现输入的字符;
5,回显字母A,表明接纳的数据顺畅。
拟定添加的功用有:
1,连续添加方向键(Up,Down,left,right),PageDown,PageUp,Insert,Home,End等按键;
2,添加欢迎和协助功用;
3,添加显现字符的主动挑选功用;
4,添加按键字符上传到PC串口。
现在已知的bug:
1,只承受单字节的按键;
2,关于ESC功用,其它有0x1B的按键均能完成此功用,需求另加鉴别;
源程序如下:
160的配置文件:
————————————1602.h开端———————————————
#define uchar unsigned char
#define uint unsigned int
#define RS 5 //PA5
#define RW 6 //PA6
#define EN 7 //PA7
#define INDATA PIND //data port
#define OUTDATA PORTD //data port
/
uchar lcd_bz(void)
{
uchar result = 1;
PORTA &= ~(1< //RS = 0
PORTA |= (1< //RW = 1
DDRD = 0x00; //PORTD as input
PORTD = 0xff; //pull-up enable
PORTA |= (1< //EN = 1
_delay_ms(2);
if((INDATA & 0x80)==0x80)
result = 1;
else
result = 0;
PORTA &= ~(1< //EN = 0
DDRD = 0xff; //PORTD as output
return result;
}
/
void lcd_write(uchar cmd)
{
PORTA &= ~(1< //RS = 0
PORTA &= ~(1< //RW = 0
OUTDATA = cmd;
PORTA &= ~(1< //EN = 0
PORTA |= (1< //EN = 1
_delay_ms(1);
PORTA &= ~(1< //EN = 0
}
/
void lcd_write_cmd(uchar cmd)
{
while(!lcd_bz()) {;} //wait when busy?
PORTA &= ~(1< //RS = 0
PORTA &= ~(1< //RW = 0
OUTDATA = cmd;
PORTA &= ~(1< //EN = 0
//_delay_ms(1);
PORTA |= (1< //EN = 1
_delay_ms(2);
PORTA &= ~(1< //EN = 0
}
/
void lcd_write_data(uchar data)
{
while(!lcd_bz()) {;} //wait when busy?
PORTA |= (1< //RS = 1
PORTA &= ~(1< //RW = 0
OUTDATA = data;
PORTA &= ~(1< //EN = 0
PORTA |= (1< //EN = 1
_delay_ms(2);
PORTA &= ~(1< //EN = 0
}
//
void lcd_setxy(uchar x, uchar y)
{
if (x > 15)
x = 0;
switch (y)
{
case 1: lcd_write_cmd(x | 0xc0); break; //set line 2
default: //Set to line 1 when y > 2
case 0: lcd_write_cmd(x | 0x80); break; //set line 1
}
}
/
void lcd_init(void)
{
DDRA = 0xff;
DDRD = 0xff;
_delay_ms(10);
lcd_write(0x38);
lcd_write(0x38);
lcd_write(0x38);
_delay_ms(2);
lcd_write_cmd(0x38); //display mode setting
lcd_write_cmd(0x01); //display off,
lcd_write_cmd(0x08); //dispaly clean
lcd_write_cmd(0x06); //cursor increase add. by 1.
lcd_write_cmd(0x0e); //display on, cursor disappear
_delay_ms(1);
}
/
void lcd_clean(uchar lcd_line)
{
uchar lcd_pos;
lcd_setxy(0, lcd_line);
for(lcd_pos = 0; lcd_pos < 16; lcd_pos++)
{
lcd_setxy(lcd_pos, lcd_line);
lcd_write_data(0x20); //display mode setting
_delay_ms(1);
}
}
————————————1602.h完毕——————————————–
串口设置的头文件
————————————com.h开端——————————————–
#define uchar unsigned char
#define uint unsigned int
#define FOSC 16000000 //CLOCK SPEED
#define BAUD 9600
/
case 0x0d:
{
line = ~(line|0xfe); //chang the other line
lcd_clean(line); //clean this line
lcd_setxy(0, line); //set position to 0
pre_pos = i;
i = 0; //reset postion i
break;
}
case 0x08:
{
if(i != 0) //disable BackSpace when i = 0
{
i–;
lcd_setxy(i, line); //backspace a position in current line
lcd_write_data(0x20); //clean current character, position add 1
lcd_setxy(i, line); //set the position back
}
break;
}
case 0x1b:
{
_delay_ms(10);
lcd_clean(0); //clean line 0
lcd_clean(1); //clean line 1
lcd_setxy(0, 0); //reset (0,0)
i = 0;
line = 0;
pre_pos = 0;
break;
}
default:
{
lcd_setxy(i&0x0f, line);
if(i > 15)
{
lcd_clean(line); //auto clean current line
lcd_setxy(0, line); //reset the position back to (0, $(line))
i = 0; //reset the position i
}
lcd_write_data(temp);
i++;
break;
}
}
USART_Status(1); //Enable COM
}
}
————————————main.c完毕——————————————–
这个程序写在新的1602的驱动之前,所以有关1602的部分子程序并没有选用新的代码和函数,并且在backspace的部分是选用的逻辑的方法来完成的,所以感觉有点不太完美,好在处理的东西还不算太多,履行的速度仍是能够承受的。我在后来再深化开掘datasheet的时分才发现,1602有指针AC增减的指令,写入相关的指令就能够了:(
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ceping/261877.html