PC机与单片机在串口通讯

发布者:Serendipity99最新更新时间:2016-03-24 来源: eefocus关键字:PC机  单片机  串口通讯 手机看文章 扫描二维码
随时随地手机看文章
    刚调好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增减的指令,写入相关的命令就可以了:(
关键字:PC机  单片机  串口通讯 引用地址:PC机与单片机在串口通讯

上一篇:STC12C5620AD系列A/D转换C语言程序
下一篇:STC52单片机的SD卡底层驱动——SPI

推荐阅读最新更新时间:2024-03-16 14:48

单片机系统的低功耗设计策略
在嵌入式应用中,系统的功耗越来越受到人们的重视,这一点对于需要电池供电的便携式系统尤其明显。降低系统功耗,延长电池的寿命,就是降低系统的运行成本。对于以单片机为核心的嵌入式应用,系统功耗的最小化需要从软、硬件设计两方面入手。 随着越来越多的嵌入式应用使用了实时操作系统,如何在操作系统层面上降低系统功耗也成为一个值得关注的问题。限于篇幅,本文仅从硬件设计和应用软件设计两个方面讨论。 1 硬件设计 选用具有低功耗特性的单片机可以大大降低系统功耗。可以从供电电压、单片机内部结构设计、系统时钟设计和低功耗模式等几方面考察一款单片机的低功耗特性。 1.1 选用尽量简单的CPU内核 在选择CPU内核时切忌一味追求性能。8位
[嵌入式]
新唐单片机keil驱动问题
1:新唐单片机keil编译工具,资料都可以在新唐官网下载。keil驱动软件要安装在keil安装的目录下,今天安装了很久,一直提示不成功,就是因为驱动Nu-link driver 没有安装到keil安装目录下。 2:刚开始项目选用M0518LC2AE单片机(36K FLASH),后来因程序存储区不够,又选用M0518LD2AE单片机(68K FLASH)。但keil编译时提示选用芯片的容量不够,keil重启无效,最后keil卸载后重装可以。
[单片机]
PIC8引脚带A/D的单片机的特点
PIC 8引脚带A/D的单片机12C6和12CE6系列是Microchip公司生产的一类PIC 8位单片机,其产品型号是12C671/672和12CE673/674,它们是PIC单片机中级型产品之一,其引脚功能如附图所示。   该类产品是一种8引脚带4路8位A/D转换器的超小型产品,是目前性价比极高的8位OTP(一次编程不可擦除)单片机。由于它们体积小巧,所以可嵌入几乎任何一种电子产品中,特别是便携式电子产品,如IC卡、充电器、计时器、智能传感器和儿童玩具等等都已广泛地应用了。   PIC12C6和12CE6系列单片机之间的差别,仅后者产品内部硬件带有E2PROM的数据存储器(16×8),它们的其它性能几乎完全一样。
[单片机]
PIC8引脚带A/D的<font color='red'>单片机</font>的特点
从零开始学单片机(九)串口通信
串口通信是单片机一个重要的部分,单片机和PC,单片机和单片机之间的通信大都用串口。单片机的串口是全双工异步串口通信方式。通过TXD(P3.1)发送,RXD(P3.0)引脚接收输入。串口传送数据是一帧一帧发送的,它有四种工作方式,同时也可以做并行I/O的扩展。 图上是串口的结构图。 SBUF是数据缓冲寄存器,发送和接收用的是一个地址,但是不用担心冲突,读只能从接收缓冲区,写只能在发送缓冲区里。 寄存器SCON(SM0 SM1 SM2 REN TB8 RB8 TI RI) SM0和SM1: 工作方式选择(0-3),方式1和方式3使用T1产生波特率,方式0和方式2是固定速率。 SM2 :在方式2和方式3的多级通信控制位 RE
[单片机]
从零开始学<font color='red'>单片机</font>(九)串口通信
基于单片机的FPGA并行配置方法
在当今变化的市场环境中,产品是否便于现场升级、是否便于灵活使用,已成为产品能否进入市场的关键因素。在这种背景下,Altera公司的基于SRAM LUT结构的FPGA器件得到了广泛的应用。这类器件的配置数据存储在SRAM中。由于SRAM的掉电易失性,系统每次上电时,必须重新配置数据,只有在数据配置正确的情况下系统才能正常工作。这种器件的优点是可在线重新配置ICR(In-Circuit Reconfigurability),在线配置方式一般有两类:一是通过下载电费由计算机直接对其进行配置;二是通过微处理器对其进行配置。前者调试时非常方便 ,但在应用现场是很不现实的。因此,如果系统重新上电时,系统本身具有自动加载可编程逻辑器件的编程文件
[单片机]
20课:单片机定时/计数器实验
前面我们做了定时器的实验,现在来看一看计数实验,在工作中计数常常会有两种要求:第一、将计数的值显示出来,第二、计数值到一定程度即中断报警。第一种如各种计数器、里程表,第二种如前面例中讲到的生产线上的计数。先看第一种吧。我们的硬件中是这样连线的:324组成的振荡器连到定时/计数器1的外部管脚T1上面,我们就利用这个来做一个计数实验,要将计数的值显示出来,当然最好用数码管了,可我们还没讲到这一部份,为了避免把问题复杂化,我们用P1口的8个LED来显示计到的数据。 程序如下: ORG 0000H ,http://www.51hei.com AJMP START ORG 30H START: MOV SP,#5FH MOV TMOD,
[单片机]
51单片机串口通信错误的原因
之前发过一篇博文《MCU-51串口通信程序》,程序挺好用的,之后一直把串口当做测试用途,像正在调试USB,用的是CH372,PC通过CH372(USB)发一个字符到单片机,单片机再通过串口回传这个字符,从而验证CH372是否收到字符,结果出现意想不到的错误,错误还挺有规律的。就是发16位字符0A,接收到字符用16位显示是8A;发2A,显示AA;发2B,显示AB,就是最高位(第8位)0变为1了,试验了几个都是一样。 之前老板也是同样的问题(可见这事是多么普遍),不过当时由于不是我的事,就没管。问了一下老板,才知道是晶振的问题,之前板子是用11.0952MHz晶振,现在的板子是12MHz,程序中串口通信也没改预置值,直接就下载了
[单片机]
51<font color='red'>单片机</font>串口通信错误的原因
单片机与plc的区别
1.PLC是建立在单片机之上的产品,单片机是一种集成电路,两者不具有可比性。 2.单片机可以构成各种各样的应用系统,从微型、小型到中型、大型都可,PLC是单片机应用系统的一个特例。 3.不同厂家的PLC有相同的工作原理,类似的功能和指标,有一定的互换性,质量有保证,编程软件正朝标准化方向迈进。这正是PLC获得广泛应用的基础。而单片机应用系统则是八仙过海,各显神通,功能千差万别,质量参差不齐,学习、使用和维护都很困难。 最后,从工程的角度,谈谈PLC与单片机系统的选用; 1.对单项工程或重复数极少的项目,采用PLC方案是明智、快捷的途径,成功率高,可*性好,手尾少,但成本较高。 2.对于量大的配套项目,采用单片机系统具
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved