单片机
返回首页

PC机与单片机在串口通讯

2016-03-24 来源:eefocus

    刚调好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                      //PA5
#define RW                      //PA6
#define EN                      //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增减的指令,写入相关的命令就可以了:(
进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • CCD图像传感器在微光电视系统中的应用

  • 光控音效发生器电路

  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 优化电路板布局的简单方法

  • 如何使用LED驱动器LM3915制作振动计

  • 电谐波图形均衡器示意图

    相关电子头条文章