单片机串口中断问题
接受PC端字节,查询方法没问题。可是一用中断。仿真的时候接受不到也发送不了,这是问什么呀#include<reg52.h>#defineucharunsignedchar...
接受PC端字节,查询方法没问题。可是一用中断。仿真的时候接受不到也发送不了,这是问什么呀
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar idata t[6]={'M','C','U','-',0xf2,0x00};
uchar idata buffer[32];
void serial(void) interrupt 4 using 3
{
uchar i;
if(RI)
{i=SBUF;
SBUF=i+1;}
if(TI)
{TI=0;}
}
init()
{
T2CON=0x30; //T2波特率发生器/ TF2 |EXF2 |RCLK |TCLK |EXEN2 |TR2 |C\T2 |CP\RL /
RCAP2H=0xff; //常数装载 9600,8bit,12MHz
RCAP2L=0xd9;
SCON=0x50; //方式1 / SM0 |SM1 |SM2 |REN |TB8 |RB8 |TI |RI /
//PCON=0x00;
TR2=1;
IE=0xd0; //开中断
//ET2=1;
//ES=1;
//EA=1;
}
main()
{
uint j,len;
init();
while(1)
{}
} 展开
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar idata t[6]={'M','C','U','-',0xf2,0x00};
uchar idata buffer[32];
void serial(void) interrupt 4 using 3
{
uchar i;
if(RI)
{i=SBUF;
SBUF=i+1;}
if(TI)
{TI=0;}
}
init()
{
T2CON=0x30; //T2波特率发生器/ TF2 |EXF2 |RCLK |TCLK |EXEN2 |TR2 |C\T2 |CP\RL /
RCAP2H=0xff; //常数装载 9600,8bit,12MHz
RCAP2L=0xd9;
SCON=0x50; //方式1 / SM0 |SM1 |SM2 |REN |TB8 |RB8 |TI |RI /
//PCON=0x00;
TR2=1;
IE=0xd0; //开中断
//ET2=1;
//ES=1;
//EA=1;
}
main()
{
uint j,len;
init();
while(1)
{}
} 展开
4个回答
展开全部
楼主的问题我觉得应该出在这里:该中断函数是将接收的数据加一然后回显,方法简单明了,不错。但是进入了死循环。
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;
}
}
}
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;
}
}
}
展开全部
串口中断处理里RI没清,只能收第一个字节,以后就卡住了。
另外ES=1别给注释掉,要不有数据不进串口中断
另外ES=1别给注释掉,要不有数据不进串口中断
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
1,只要,RI和TI中有一个为1就会马上进入中断服务子程序。
2,开了中断,不会先进入IF(RI)的。
3,不会在DELAY停留。会再次从WHILE(1)开始。
4,先串口初始化,进入动态扫描和判断RI(也就是WHILE(1)中。如果RI为1,则向外发送RECEIVING
DATA
。发送完后就再打开中断。
在中断服务程序中,先取出数据,并关中断。
5,SBUF是同一地址。根据RI和TI可以判断是发送还是接收。
大概就是这样了。。
2,开了中断,不会先进入IF(RI)的。
3,不会在DELAY停留。会再次从WHILE(1)开始。
4,先串口初始化,进入动态扫描和判断RI(也就是WHILE(1)中。如果RI为1,则向外发送RECEIVING
DATA
。发送完后就再打开中断。
在中断服务程序中,先取出数据,并关中断。
5,SBUF是同一地址。根据RI和TI可以判断是发送还是接收。
大概就是这样了。。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
if(RI)
{i=SBUF;
SBUF=i+1;}
要加入 RI = 0;
{i=SBUF;
SBUF=i+1;}
要加入 RI = 0;
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询