微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 52单片机串口中断知识

52单片机串口中断知识

时间:11-13 来源:互联网 点击:
1、单片机每“次”的确只能接收1个字节,但由于串口的速度实在太低,通常都在115200bps以下(即使用了同步方式也“只能”达到1Mbps)。注意,是bps,位/秒,而不是“字节/秒”,这就是“串”行通信,要至少8个“bps时间”才能接收一个完整的字符,事实上,加上起始位等,8个位往往传送不了一个字节(不知道我的理解是不是有偏差),这就是说,速度至少还要再慢上8倍。

2、带有USART的单片机里USART一般都是做为“外部设备”,独立于MCU进行收发工作,即其收发过程中的串-并和并-串转换以及数据IO过程都是“自主”和“自动”的,不需要CPU逐位进行收发处理,因此,在CPU将数据送到SBUF后,便可以放手不管了,USART收发器会自动将SBUF的内容转换成串行数据发送出去。接收时也是由USART将串行数据转成并行数据并存放到SBUF后才会通知MCU(产生接收中断)。MCU所需要做的只是往SBUF送数或从SBUF中取数(都只要1个指令周期)。

3、设置串口参数的时候应该能看出,为了适应串口的慢,不得不动用定时器进行延时,以“产生”所需要的波特率,而这个“延时”通常都要给8位甚至16位定时器设置初值,定时器每一次计数都需要一个指令周期,即CPU可以执行一条指令的时间,而定时器两次串口溢出才仅仅接收或发送一个“位”,接收一个字节需要数倍于此的时间,那么这么长的时间对CPU来说,足以从容地从SBUF里取出数据并对其进行处理了。

4、即使CPU的任务相当繁重,或对接收到的每个字节都需要进行相当复杂的处理,我们也完全可以通过建立接收缓冲区的方式将暂时来不及处理的数据暂存起来,等CPU空闲时再做处理。而从SBUF取出数据并保存到缓冲区只需要很少的几条指令就能完成,不会影响到串口继续接收。

5、标准的RS-232协议并非只有TX、RX和GND三个引脚,即便是最简单的9针插口,也专门设计了检测传输状态和收发请求的针脚。如果单片机真的实在无法及时完成收发动作,也完全可以利用一个口线作为状态标识,使PC能够知道单片机什么时候可以接收数据,而不会任由数据丢失。

6、为了增加数据传输的可靠性,大量数据传输时通常都会采用CRC校验方式,并以“包”或“帧”的方式发送有格式约定的字节流,而非单个字符,这样一来,完全可以通过约定一些“通信协议”的方式,使收发双方都能够及时知道接收的数据是否完整,并及时重发新发送出错的数据。

# include
#include
typedef unsigned char unchar ;
unsigned char ch;
bit read_flag= 0 ;

void init_serialcom( void ) //串口通信初始设定

{

SCON = 0x50 ; //UART为模式1,8位数据,允许接收

TMOD = 0x20 ; //定时器1为模式2,8位自动重装

PCON = 0x80 ; //SMOD=1;

TH1 = 0xFD ; //Baud:19200 fosc="11".0592MHz

TL1 = 0xFD ;
IE = 0x90 ; //Enable Serial Interrupt

TR1 = 1 ; // timer 1 run

// TI=1;

}

//向串口发送一个字符

void send_char_com( unchar ch)

{

SBUF=ch;

while (TI== 0);

TI= 0 ;

}

//串口接收中断函数 功能:串口中断。如果有数据从串口发送过来,首先从串口中读出数据,赋给串口缓冲数组,清中断标志(RI和TI中有一个为1就会马上进入中断服务子程序)

void serial () interrupt 4 using 3

{

if (RI)

{

RI = 0 ;

ch=SBUF;

read_flag= 1 ; //就置位取数标志

}

}

void main()

{

init_serialcom(); //初始化串口

while ( 1 )

{

if (read_flag) //如果取数标志已置位,就将读到的数从串口发出

{

read_flag= 0 ; //取数标志清0

send_char_com(ch);

}

}

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top