51单片机串口通信的注记

最近折腾51单片机,当然学到的都是比较基础的东西,可能我认为比较复杂的概念有“中断” 和“串口通信”,这篇主要是讲串口通信

使用的自然是山大王STC89C52RC的芯片来学习

串口通信主要是C51单片机的RXD 和TXD 与上位机进行通信,由于上位机一般是电脑,所以要TTL转成电脑能读出的RS232的电路来支持   一般使用MAX232 芯片   串口通信电路如下

image

之后就可以电脑的串口与这里的串口头子接了,注意   串口先要交叉一下    即电脑的TXD 对应下位机的RXD

C51单片机串口通信模式有4种,最常用的是第一种  

方式0       同步移位寄存器方式 ,一般用来扩展I/O口,

方式1       10位异步收发(8位数据),波特率可变(由定时器1的溢出率控制)

方式2       11位异步收发(9位数据),波特率固定

方式4       11位异步收发,波特率可变(定时器1溢出率决定)

image

各种需要配置的参数如下所示

ScreenClip

TI
发送中断标志位
当发送一帧完毕后,由硬件使TI=1,向外部发送中断申请,在中断服务程序中,必须用软件手动TI = 0,否则一直卡在中断里(测试一下)

RI
接受中断标志位 
当接收一帧完毕后,由硬件使RI = 1, 向外部发送中断申请,也必须要在中断服务程序中,用软件将其清0,取消此次中断申请

ES 
串行中断允许位
1 为开打   0为关闭

REN
允许串行接受位
1 为打开   0 为关闭

SBUF
串口缓存 
在读写完毕后,存储的是相应的读/写值(注意,SUBF实际有两个寄存器,一个放写一个放读)

SM0/1
串口设置工作方式
设置4种工作方式,注意,最好是设置好工作方式再开串口传授

EA
终端总开关

TR1
定时器1开关

TH1/TL1
定时器初值
为了满足9600 的波特率   所以需要将TH1  TL1 设置为0xfd

TMOD
定时器运行模式
在串口通信的1号方式的时候  需要打开T1的串口通信    TMOD= 0x20 ,即第二种方式,8位自动重装

ET0/1
中断允许开关
time0 time1

之后是我的印象笔记的两篇关于串口通信笔记的分享

http://app.yinxiang.com/shard/s20/sh/6abe8da0-d4b8-4407-9848-3142dde1bed5/ba2a0a6debaab317aaca09185ce65c71
http://app.yinxiang.com/shard/s20/sh/0faa2671-1e95-4d08-9d12-b1bdedc0eadd/13e7a915ea347b0daf3aca30fd9a6a74

我自己写的个简单的串口通信  

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[] = "Hi ";

uchar receiveFlag=0;

void init(){   
    TMOD = 0x20;
    TH1 = 0xfd;
    TL1 = 0xfd;
   

    SM0 = 0;
    SM1 = 1;
    REN = 1;


    EA = 1;
    TR1 = 1;
}

void main(){
    uchar serVal,i;
    init();
    receiveFlag = 1;
   
    while(1){
        if(receiveFlag == 1){
            ES = 1;
            while(RI==0);
            serVal = SBUF;
           
            RI = 0;
            receiveFlag = 0;
        }
        if(receiveFlag==0){  //need to send msg;
            for(i =0;i<3;i++){
                SBUF = table[i];
                while(TI==0);
                TI = 0;
            }
            SBUF = serVal;
            while(TI ==0);
            TI = 0;
            receiveFlag = 1;
        }
    }
   
}


void receive_data() interrupt 4{
    RI = 0;//手动清0
    ES = 0;
    receiveFlag = 0;

}

posted @ 2013-09-05 16:31  Atpking  阅读(962)  评论(0编辑  收藏  举报