在紧张的工作中,现在对单片机的串口通信编程有了一个新的认识,下面就针对下面不同的几个工程程序文件的区别做一个比较详细的总结。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
本次小结的主要目的是更加明确单片机的串口中断是如何发生的。即:是如何触发串口中断的发送功能的。在说明中我使用特殊的字体颜色来强调重点部分和注意事项。
程序一:
本程序是使用软件设置TI来实现串口中断的触发,如果在初始化函数中不增加“TI=1;”这条语句,那么是不会触发中断的
#include <STC<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />89C5X.h> //包含51单片机的头文件
#define uint unsigned int
#define uchar unsigned char
/* 串口通讯接口定义
RXD-------P3.0 数据接收端
TXD-------P3.1 数据发送端
*/
/*============================================================================
//函 数 名: void InitUart(void)
//参 数: 无
//返 回 值: 无
//函数功能: 串口初始化函数
==============================================================================*/
void InitUart(void)
{
//使用定时器1作为波特率发生器
TMOD|=0x20;//T1工作为方式2
SCON=0x50;//方式1:10位异步同通讯,串口允许接收
PCON|=0x80;//波特率倍增,SMOD='1'
TH1=0xfa;
TL1=0xfa;
TR1=1;
TI=1;//使用软件触发首次串口中断的发生
ES=1;//串口中断允许
EA=1;//总中断允许
}
/*============================================================================
//函 数 名: main()
//参 数: 无
//返 回 值: 无
//函数功能: 串口通信工程的主函数
==============================================================================*/
main()
{
InitUart();//串口设置初始化
while(1);//死循环等待哦!
}
/*============================================================================
//函 数 名: void uart(void) interrupt 4
//参 数: 无
//返 回 值: 无
//函数功能: 串口中断处理函数
==============================================================================*/
void uart(void) interrupt 4
{ /*接收数据中断处理*/
if(RI)
{
RI=0;//接收语句放在本语句前面,本语句是软件复位接收中断标志
}
/*发送数据中断处理*/
if(TI)
{
TI=0;//复位TI
SBUF = 'B';
}
}
程序二:
本程序是使用在软件的初始化时在串口缓冲区SBUF中先放一个数据来实现串口中断的触发,如果在初始化函数中不增加“SBUF = 0x00;”这条语句,那么是不会触发中断的
#include <STC89C5X.h> //包含51单片机的头文件
#define uint unsigned int
#define uchar unsigned char
/* 串口通讯接口定义
RXD-------P3.0 数据接收端
TXD-------P3.1 数据发送端
*/
/*============================================================================
//函 数 名: void InitUart(void)
//参 数: 无
//返 回 值: 无
//函数功能: 串口初始化函数
==============================================================================*/
void InitUart(void)
{
//使用定时器1作为波特率发生器
TMOD|=0x20;//T1工作为方式2
SCON=0x50;//方式1:10位异步同通讯,串口允许接收
PCON|=0x80;//波特率倍增,SMOD='1'
TH1=0xfa;
TL1=0xfa;
TR1=1;
SBUF = 0x00;//初始化是来实现串口中断的触发,在这里你也可以将TI复位为’0’不会影响串口中断的数据发送,任意的值都可以放到SBUF中,不一定非是0x00哦
ES=1;//串口中断允许
EA=1;//总中断允许
}
/*============================================================================
//函 数 名: main()
//参 数: 无
//返 回 值: 无
//函数功能: 串口通信工程的主函数
==============================================================================*/
main()
{
InitUart();//串口设置初始化
while(1);//死循环等待哦!
}
/*============================================================================
//函 数 名: void uart(void) interrupt 4
//参 数: 无
//返 回 值: 无
//函数功能: 串口中断处理函数
==============================================================================*/
void uart(void) interrupt 4
{ /*接收数据中断处理*/
if(RI)
{
RI=0;//接收语句放在本语句前面,本语句是软件复位接收中断标志
}
/*发送数据中断处理*/
if(TI)
{
TI=0;//复位TI
SBUF = 'B';
}
}
程序三:
在初始化函数中即不要“TI=1;”语句,也不要“SBUF=0x00;”语句就形成了程序三,这个程序是用来与上面的两个程序对比说明的。程序三是不能正确的发送数据的,串口中断服务程序一直都不会进去的!
不知道说明白没有,希望大家可以好好的看看!
自己动手调试一下就会有很深的体会!!!!
用户377235 2013-12-5 11:47
帮大忙了,把串口接收改为中断方式后不通了,按楼主的方法认为置IT=1;,解决了。 还有,关于51的UART中断,发送和接收都用中断方式时,当你不发送数据时,程序还是会进入中断(因为满足发送缓冲器空的条件)。这样很占用CPU时间啊,不停地进中断。 关于这个问题,AVR单片机就解决的挺好,它是发送、接收中断有分别的设置位和分别的中断函数(ISR),这样在不发送数据是,就可以把发送中断关闭了。其他有些单片机也有不同的设置位,但ISR还是在同一个函数里,如:NIOS。