关于单片机串口中断问题,请教。

2020-02-05 09:04发布

本帖最后由 lidakemaki 于 2012-6-15 09:45 编辑

大家好,如题。

不知道大家有没有遇到一种情况,就是单片机做“中转站”,把接收到的数据再发出去。

当然我知道可以用扫描的方法实现。

但是今天我试验了,用中断的方法,大意是接收到一组数据后,在接收中断中直接调用2个处理数据的函数,数据处理完毕,又在接收中断里,启动了发送中断。我这样试验后,发现时不时的会死机,而且有时数据处理明显不正确(因为处理后的结果都一样了!)。

请问,确实不能这样写吗?


其实我想问的问题是:

在单片机中,接收中断里调用2个函数,处理数据,并且在接收中断没有退出的情况下,申请发送中断。这样的做法,会不会造成单片机“死机”和函数处理数据不正确(数据结果一定)(函数一定是没问题的,因为我拿出中断来执行,数据都OK)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
24条回答
jswd0810
1楼-- · 2020-02-05 11:50
设置两个接收缓冲区,一个用于接收完成的,一个用于现在接收的,不知道可行不
lcw_swust
2楼-- · 2020-02-05 17:03
本帖最后由 lcw_swust 于 2012-6-15 09:40 编辑

软件模拟FIFO,接收时只往FIFO里存数据,主循环(或可被串口打断的低优先级的中断里)读取FIFO数据进行处理
lidakemaki
3楼-- · 2020-02-05 19:25
 精彩回答 2  元偷偷看……
lidakemaki
4楼-- · 2020-02-05 22:53
lcw_swust 发表于 2012-6-15 09:39
软件模拟FIFO,接收时只往FIFO里存数据,主循环(或可被串口打断的低优先级的中断里)读取FIFO数据进行处理 ...

你好,感谢你的回答,但是能说的详细一点吗?
软件模拟的FIFO指的是什么?是我自己申请的缓冲区吗?
再一个,我的程序中,有2个中断,一个是时间中断,另一个是串口中断,时间中断的优先级更高,现在说明一下,望你继续回答。
lcw_swust
5楼-- · 2020-02-06 00:00
本帖最后由 lcw_swust 于 2012-6-15 10:01 编辑

//FIFO工作模式
#define DTYPE INT16S
//数据类型

//--------------------------------------------------
//全局变量定义定义
//--------------------------------------------------
DTYPE quebuf[QUESIZE];
INT8U que_count=0;//队列元素计数
INT8U que_front=0;//队头
INT8U que_rear=0;//队尾
//--------------------------------------------------
//写队列
//①当头尾指针相等时,队列为空。
//②在非空队列里,队头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置。
//--------------------------------------------------
void QueWrite(DTYPE din)
{
que_count++;
quebuf[que_rear]=din;
que_rear=(que_rear+1)%QUESIZE;//可写成que_rear++;if(que_rear>=QUESIZE)que_rear=0;

}
//--------------------------------------------------
//读取队列
//--------------------------------------------------
DTYPE QueRead(void)
{
DTYPE ret;
  //FIFO模式
que_count--;
ret=quebuf[que_front];
que_front=(que_front+1)%QUESIZE;;//可写成que_front++;if(que_front>=QUESIZE)que_front=0;
return ret;
}
//--------------------------------------------------
//队列满(返回1)
//--------------------------------------------------
INT8U QueFull(void)
{
return (que_count==QUESIZE);
}
//--------------------------------------------------
//队列空(返回1)
//--------------------------------------------------
INT8U QueEmpt(void)
{
return (que_count==0);
}


串口中断里:
  if(QueFull()==0)QueWrite(drx);//FIFO未满,则写入串口数据

主循环里
  if(QueEmpt()==0)dtx=QueRead();//FIFO未空,则读取数据
jswd0810
6楼-- · 2020-02-06 04:51
lidakemaki 发表于 2012-6-15 09:42
感谢你的回答。

但是你回答的意思,我没有理解,2个接收缓冲区,对程序有什么帮助?我现在的程序接收当 ...

你如果是用51单片机的话,看这样行不,在通讯中断里不要启动发送,而是改用在主程序中用查询的方式发送数据,发送完成一个以后再继续发送第2个

一周热门 更多>