Ⅰ 单片机串口中断执行流程
流程是:(主程序中)发送数据―等待中断―发送成功产生中断―进入中断清除TL,再次发送―中断返回―等待中断―发送成功产生中断―进入中断清除TL,再次发送。。。。循环而已。
Ⅱ 51单片机串口的原理和过程
单片机C51串口中断接收和发送测试例程(含通信协议的实现)
通信协议:第1字节,MSB为1,为第1字节标志,第2字节,MSB为0,为非第一字节标志,其余类推……,最后一个字节为前几个字节后7位的异或校验和。
测试方法:可以将串口调试助手的发送框写上 95 10 20 25,并选上16进制发送,接收框选上16进制显示,如果每发送一次就接收到95 10 20 25,说明测试成功。
//这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收
//和查询发送,另外我觉得发送没有必要用中断,因为程序的开销是一样的
//程序编写: 龚建伟 [email protected]
//技术主页:http://www.gjwtech.com
//您有这方面的问题可以和我讨论
#include <reg51.h>
#include <string.h>
#define INBUF_LEN 4 //数据长度
unsigned char inbuf1[INBUF_LEN];
unsigned char checksum,count3;
bit read_flag=0;
void init_serialcomm(void)
{
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x20; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80; //SMOD=1;
TH1 = 0xF4; //Baud:4800 fosc=11.0592MHz
IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; // timer 1 run
// TI=1;
}
//向串口发送一个字符
void send_char_com(unsigned char ch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com(unsigned char *str,unsigned int strlen)
{
unsigned int k=0;
do
{
send_char_com(*(str + k));
k++;
} while(k < strlen);
}
//串口接收中断函数
void serial () interrupt 4 using 3
{
if(RI)
{
unsigned char ch;
RI = 0;
ch=SBUF;
if(ch>127)
{
count3=0;
inbuf1[count3]=ch;
checksum= ch-128;
}
else
{
count3++;
inbuf1[count3]=ch;
checksum ^= ch;
if( (count3==(INBUF_LEN-1)) && (!checksum) )
{
read_flag=1; //如果串口接收的数据达到INBUF_LEN个,且校验没错,
//就置位取数标志
}
}
}
}
main()
{
init_serialcomm(); //初始化串口
while(1)
{
if(read_flag) //如果取数标志已置位,就将读到的数从串口发出
{
read_flag=0; //取数标志清0
send_string_com(inbuf1,INBUF_LEN);
}
}
}
Ⅲ 单片机串口中断问题
楼主的问题我觉得应该出在这里:该中断函数是将接收的数据加一然后回显,方法简单明了,不错。但是进入了死循环。
void serial(void) interrupt 4 using 3
{
uchar i;
if(RI)
{i=SBUF;
SBUF=i+1;}//中断内再出中断,打乱了中断服务程序的返回。
if(TI)
{TI=0;}
}
修改的如下,希望楼主看完后明白这个是同步互斥的问题。
void serial(void) interrupt 4 using 3
{
uchar i;
if(RI)
{i=SBUF;
ES=0;//关串行中断
SBUF=i+1;}//中断内再出中断,打乱了中断服务程序的返回。
ES=1;//开穿行中断
if(TI)
{TI=0;}
}
完整而完善的串口服务函数可以给楼主参考:
#include<reg51.h>
unsigned char UART_RX; //定义串口接收数据变量
unsigned char RX_flag; //定义穿行接收标记
/*********************************************************************************************
函数名:UART串口初始化函数
调 用:UART_init();
参 数:无
返回值:无
结 果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
备 注:振荡晶体为11.0592MHz,PC串口端设置 [ 2400,8,无,1,无 ]
/**********************************************************************************************/
void UART_init (void){
EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
ES = 1; //允许UART串口的中断
TMOD = 0x20; //定时器T/C1工作方式2
SCON = 0x50; //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
TH1 = 0xE8; //定时器初值高8位设置
TL1 = 0xE8; //定时器初值低8位设置
PCON = 0x80; //波特率倍频(屏蔽本句波特率为1200)
TR1 = 1; //定时器启动
}
/**********************************************************************************************/
/*********************************************************************************************
函数名:UART串口接收中断处理函数
调 用:[SBUF收到数据后中断处理]
参 数:无
返回值:无
结 果:UART串口接收到数据时产生中断,用户对数据进行处理(并发送回去)
备 注:过长的处理程序会影响后面数据的接收
/**********************************************************************************************/
void UART_R (void) interrupt 4 using 1{ //切换寄存器组到1
RI = 0; //令接收中断标志位为0(软件清零)
UART_RX = SBUF; //将接收到的数据送入变量 UART_data
RX_flag=1; //标记接收
//用户函数内容(用户可使用UART_data做数据处理)
//SBUF = UART_data; //将接收的数据发送回去(删除//即生效)
//while(TI == 0); //检查发送中断标志位
//TI = 0; //令发送中断标志位为0(软件清零)
}
/**********************************************************************************************/
/*********************************************************************************************
函数名:UART串口发送函数
调 用:UART_T (?);
参 数:需要UART串口发送的数据(8位/1字节)
返回值:无
结 果:将参数中的数据发送给UART串口,确认发送完成后退出,采用非中断方式
备 注:
/**********************************************************************************************/
void UART_T (unsigned char UART_data){ //定义串口发送数据变量
ES=0; //禁止穿行中断
SBUF = UART_data; //将接收的数据发送回去
while(TI == 0); //检查发送中断标志位
TI = 0; //令发送中断标志位为0(软件清零)
ES=1; //打开穿行中断
}
/*********************************************************************************************
函数名:UART串口发送字符串函数
调 用:UART_S (?);
参 数:需要UART串口发送的数据(8位/1字节)
返回值:无
结 果:将参数中的数据发送给UART串口,确认发送完成后退出,采用非中断方式
备 注:
/**********************************************************************************************/
void UART_S(unsigned char *str)
{
while(1)
{
if(*str=='\0') break;
UART_T(*str++);
}
}
/*********************************************************************************************
函数名:主函数
调 用:main();
参 数:
返回值:无
结 果:
备 注:
/**********************************************************************************************/
void main()
{
unsigned char Buf_data[]={" welcome to MCU world. \n\r"};
UART_init();
UART_S(Buf_data);
while(1){
if(RX_flag==1)
{
UART_T(UART_RX);
RX_flag=0;
}
}
}
Ⅳ 51单片机串口通信不用设置IE开关吗
你对51的串口部分了解还不够透彻。51的串口默认是使用Timer1作为波特率发生器的,利用8位自动重载模式产生串口波特率的32或16倍频。如果你开启了Timer1中断、又没有修改串口波特率发生器的选择,那么由于Timer1不停进入中断就会导致串口部分根本无法正常工作。
简而言之,默认状况下,串口要吃掉Timer1。牢记。
Ⅳ 怎么用51单片机的一个串口实现与外设两个串口通信
只有单串口的单片机如何实现与两个串口模块通信
--可以分时工作。
--分别和两个串口外设,通信。
--但是,外部电路,需要好好设计。
Ⅵ 单片机 串口 中断 C程序
void
ser_com1(void)
interrupt
5
using
3
串口中断的优先级虽然是
5
,但应用
interrupt
4~因为01234~~
这个与错误无关哈~
一般syntax
error都是标点有错,不知你的回车处有没有空格~~~
Ⅶ 51单片机串口通信中IE=0x90;是什么意思
IE: EA X X ES ET1 EX1 ET0 EX0
EA:总允许位
ES:串口中断允许位
ET1:定时计数器1中断允许位
EX1:外部中断1中断允许位
ET0:定时计数器0中断允许位
EX0:外部中断0中断允许位
IE化为二进制 就是 1001 0000 开总中断和串口中断
Ⅷ 单片机串口如何接收
在主程序中对接收到的数据串进行处理,查找帧头、提取有效数据、进行业务判断。
首先,要知道中断应当尽量简洁,所以中断里面只做数据接收和下标移动。
其次,要知道每帧的最大长度。帧长度要是毫无限制那缓冲区就不好开了,得采用适用性更强的缓冲技术,这里就不提了。举例假定数据量最多10字节,则最长帧为13字节,可开辟16字节缓冲区。
再次,要知道通信协议是怎么样的,传输速率如何(与单片机处理能力相比),每帧的数据之间有多少间隔,帧与帧之间有多少间隔。
间隔太短的话需要增加许多额外的处理,例如帧头识别、帧分割,必要时又得用较大容量的循环缓冲区……这里也不提了。举例假定帧间有足够多的间隔时间。
Ⅸ 单片机串口通信需要用哪些寄存器
51单片机串口工作时,涉及到以下三个寄存器:
1.SCON:串行口工作寄存器
2.IE:中断允许寄存器(如果用到中断方式的话)
3.PCON:其中最高位SMOD与波特率有关
另外还有定时器T1在方式1,方式3时需要用到,以改变波特率。
Ⅹ 51单片机串口通信问题: 最近做一个温度采集系统需要把采集到得温度发送到VB上
#define UART_BUADRATE 19200//9600
#define OCS 11059200//12000000
void init_uart(void)
{
EA=0;
SCON = 0x50;
T2CON &= 0x3f; //TF2=0 EXF2=0
T2CON |= 0x30; //串口1选择T2为波特率时钟
T2CON &= 0xf7;//EXEN2=0
T2CON &= 0xfb;//TR2 = 0;//关闭定时器2
T2CON &= 0xfd;//定时器工作方式
T2CON &= 0xfe;//自动重载
PCON = PCON | 0x80;//SMOD=1
//baudrate = 9600;
//OCS = 22118400;
TH2 = (65536 - OCS/32/UART_BUADRATE)/256;
TL2 = (65536 - OCS/32/UART_BUADRATE)%256;
RCAP2H = (65536 - OCS/32/UART_BUADRATE)/256;
RCAP2L = (65536 - OCS/32/UART_BUADRATE)%256;
//ET2= 0;//禁止T2中断
ES = 1;//启动串口1
TR2 = 1;//启动定时器2
EA=1;
}