新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > PC機(jī)與單片機(jī)在串口通訊

        PC機(jī)與單片機(jī)在串口通訊

        作者: 時(shí)間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
        剛調(diào)好LCD1602之后,又做了個(gè)PC串口與單片機(jī)的通信的程序,實(shí)現(xiàn)了基本的COM口的功能,從PC機(jī)上通過串口發(fā)出來的字符,可以在1602液晶上面顯示出來。
        實(shí)現(xiàn)的基本功能是:
        1,BACKSPACE功能,支持刪除鍵,但是僅限于本行;
        2,ENTER功能,回車&換行功能,當(dāng)一行輸入的時(shí)候按下ENTER鍵,即可切換并且清空新行;
        3,ESC鍵功能,所有的顯示清除,光標(biāo)清零;
        4,單行循環(huán)顯示,擁有自動(dòng)回車功能,當(dāng)一行中的字符到末尾是自動(dòng)清空本行,并且在本行的開頭顯示輸入的字符;
        5,回顯字母A,表示接收的數(shù)據(jù)順利。

        擬定增加的功能有:
        1,陸續(xù)增加方向鍵(Up,Down,left,right),PageDown,PageUp,Insert,Home,End等按鍵;
        2,增加歡迎和幫助功能;
        3,增加顯示字符的自動(dòng)篩選功能;
        4,增加按鍵字符上傳到PC串口。

        目前已知的bug:
        1,只接受單字節(jié)的按鍵;
        2,對于ESC功能,其它有0x1B的按鍵均能實(shí)現(xiàn)此功能,需要另加甄別;

        源程序如下:
        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結(jié)束--------------------------------------------
        串口設(shè)置的頭文件
        ------------------------------------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結(jié)束--------------------------------------------
        這個(gè)程序?qū)懺谛碌?602的驅(qū)動(dòng)之前,所以有關(guān)1602的部分子程序并沒有采用新的代碼和函數(shù),而且在backspace的部分是采用的邏輯的辦法來實(shí)現(xiàn)的,所以感覺有點(diǎn)不太完美,好在處理的東西還不算太多,執(zhí)行的速度還是可以接受的。我在后來再深入發(fā)掘datasheet的時(shí)候才發(fā)現(xiàn),1602有指針AC增減的指令,寫入相關(guān)的命令就可以了:(


        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 方山县| 扶余县| 彩票| 舞阳县| 常熟市| 镇雄县| 郸城县| 昭苏县| 凤冈县| 嘉祥县| 讷河市| 万载县| 桐庐县| 宜川县| 黔西县| 黄陵县| 兴仁县| 彭州市| 四川省| 广东省| 南漳县| 共和县| 三台县| 本溪| 清苑县| 峨山| 宁陕县| 开远市| 景泰县| 涞水县| 东莞市| 奎屯市| 抚远县| 双桥区| 东台市| 秭归县| 龙里县| 宕昌县| 屯留县| 通榆县| 镇江市|