搜索
bottom↓
回复: 24

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

[复制链接]

出0入0汤圆

发表于 2012-6-14 16:43:52 | 显示全部楼层 |阅读模式
本帖最后由 lidakemaki 于 2012-6-15 09:45 编辑

大家好,如题。

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

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

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

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


其实我想问的问题是:

在单片机中,接收中断里调用2个函数,处理数据,并且在接收中断没有退出的情况下,申请发送中断。这样的做法,会不会造成单片机“死机”和函数处理数据不正确(数据结果一定)(函数一定是没问题的,因为我拿出中断来执行,数据都OK)

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-6-15 09:39:27 | 显示全部楼层
本帖最后由 lcw_swust 于 2012-6-15 09:40 编辑

软件模拟FIFO,接收时只往FIFO里存数据,主循环(或可被串口打断的低优先级的中断里)读取FIFO数据进行处理

出0入0汤圆

 楼主| 发表于 2012-6-15 09:42:11 | 显示全部楼层
jswd0810 发表于 2012-6-15 08:55
设置两个接收缓冲区,一个用于接收完成的,一个用于现在接收的,不知道可行不 ...

感谢你的回答。

但是你回答的意思,我没有理解,2个接收缓冲区,对程序有什么帮助?我现在的程序接收当然是SUBF,接收以后我会放到其他变量中。

其实我想问的问题是:

在单片机中,接收中断里调用2个函数,处理数据,并且在接收中断没有退出的情况下,申请发送中断。这样的做法,会不会造成单片机“死机”和函数处理数据不正确(数据结果一定)(函数一定是没问题的,因为我拿出中断来执行,数据都OK)

出0入0汤圆

 楼主| 发表于 2012-6-15 09:45:26 | 显示全部楼层
lcw_swust 发表于 2012-6-15 09:39
软件模拟FIFO,接收时只往FIFO里存数据,主循环(或可被串口打断的低优先级的中断里)读取FIFO数据进行处理 ...

你好,感谢你的回答,但是能说的详细一点吗?
软件模拟的FIFO指的是什么?是我自己申请的缓冲区吗?
再一个,我的程序中,有2个中断,一个是时间中断,另一个是串口中断,时间中断的优先级更高,现在说明一下,望你继续回答。

出0入0汤圆

发表于 2012-6-15 09:59:09 | 显示全部楼层
本帖最后由 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未空,则读取数据

出0入0汤圆

 楼主| 发表于 2012-6-15 10:13:52 | 显示全部楼层
lcw_swust 发表于 2012-6-15 09:59
//FIFO工作模式
#define DTYPE INT16S
//数据类型

谢谢你的回答,
但是并没有回答我的问题。。。。。

我是想问在单片机中,在接收中断里调用了2个处理数据的函数,然后在接收中断没有退出的情况下,申请发送中断,会不会导致单片机死机或则函数结果不正确的现象。(前面提出的问题我已经从新编辑过了)

我找的不是解决方法和代码,谢谢你。

出0入0汤圆

 楼主| 发表于 2012-6-15 10:17:41 | 显示全部楼层
jswd0810 发表于 2012-6-15 10:01
你如果是用51单片机的话,看这样行不,在通讯中断里不要启动发送,而是改用在主程序中用查询的方式发送数 ...

感谢你的回答,这个方法,我是准备结合我的程序的特点做实验的。

但是我想清楚的知道我提的问题的答案,到底会不会导致MCU死机或则函数数据不正确··

出0入0汤圆

发表于 2012-6-15 10:29:50 | 显示全部楼层
lidakemaki 发表于 2012-6-15 10:13
谢谢你的回答,
但是并没有回答我的问题。。。。。

不知楼主用的哪种单片机?哪种编译器?

出0入0汤圆

发表于 2012-6-15 10:36:41 | 显示全部楼层
可以,逻辑处理对了就行

出0入0汤圆

 楼主| 发表于 2012-6-15 12:00:04 | 显示全部楼层
lcw_swust 发表于 2012-6-15 10:29
不知楼主用的哪种单片机?哪种编译器?

我用的是STC11系列的单片机,编译器是 韦弗。

出0入0汤圆

发表于 2012-6-15 13:40:47 | 显示全部楼层
lidakemaki 发表于 2012-6-15 12:00
我用的是STC11系列的单片机,编译器是 韦弗。

我用KEIL,不会死机

出0入0汤圆

 楼主| 发表于 2012-6-15 15:14:07 | 显示全部楼层
lcw_swust 发表于 2012-6-15 13:40
我用KEIL,不会死机

谢谢。

呵呵,明确一下问题。我说的死机是单片机死机,不是电脑死机哦。我是烧录芯片后,发现时不时的,单片机有死机的现象。

不知道keil和韦弗对编译后的程序还有影响吗?

出0入0汤圆

发表于 2012-6-15 15:15:22 | 显示全部楼层
lidakemaki 发表于 2012-6-15 15:14
谢谢。

呵呵,明确一下问题。我说的死机是单片机死机,不是电脑死机哦。我是烧录芯片后,发现时不时的, ...

我也说的是单片机...
同情楼主

出0入0汤圆

 楼主| 发表于 2012-6-15 15:16:03 | 显示全部楼层
mored 发表于 2012-6-15 10:36
可以,逻辑处理对了就行

我的逻辑应该是没有问题的。但是,时不时的会死机,不一定什么时候。

那函数在串口接收中断里被调用后,处理的数据结果变得都一样了。

是为什么呢?

同样的函数放在串口接收中断外就没有事了,这不是逻辑的问题了吧?!因为同一个函数哦。

出0入0汤圆

发表于 2012-6-15 15:29:51 | 显示全部楼层
lidakemaki 发表于 2012-6-15 15:16
我的逻辑应该是没有问题的。但是,时不时的会死机,不一定什么时候。

那函数在串口接收中断里被调用后, ...

比如函数有一句while(!TI){...}
放在外面不会影响接收中断,放在里面就有可能导致SBUF的溢出

出0入0汤圆

 楼主| 发表于 2012-6-15 16:02:04 | 显示全部楼层
lcw_swust 发表于 2012-6-15 15:15
我也说的是单片机...
同情楼主

兄弟,我真的不清楚。编译器不同,同一段程序。会造成编译后烧录芯片出现的结果不一样吗?求教!!!是因为什么造成的呢?

出0入0汤圆

 楼主| 发表于 2012-6-15 16:03:59 | 显示全部楼层
lcw_swust 发表于 2012-6-15 15:15
我也说的是单片机...
同情楼主

兄弟,我真的不清楚。编译器不同,同一段程序。会造成编译后烧录芯片出现的结果不一样吗?求教!!!是因为什么造成的呢?

出0入0汤圆

发表于 2012-6-15 16:34:34 | 显示全部楼层
有事时候还真可能是编译器问题

出0入0汤圆

 楼主| 发表于 2012-6-15 16:52:20 | 显示全部楼层
学生尧 发表于 2012-6-15 16:34
有事时候还真可能是编译器问题

那是为什么呢?

你以前也遇到过这种情况吗??

编译器为什么会影响到程序的编译结果呢??

出0入0汤圆

发表于 2012-6-16 07:10:07 | 显示全部楼层
我遇到过有的问题是编译器造成的,但不是你这个问题,不好意识

出0入0汤圆

 楼主| 发表于 2012-6-16 10:49:36 | 显示全部楼层
mored 发表于 2012-6-15 15:29
比如函数有一句while(!TI){...}
放在外面不会影响接收中断,放在里面就有可能导致SBUF的溢出 ...

我发送和接收都是中断模式,都是一个一个来的和发送的,是中断的话,应该不存在你说的那种,程序过快,而还没发送完毕,就被溢出的情况吧?!

出0入0汤圆

 楼主| 发表于 2012-6-16 10:50:06 | 显示全部楼层
学生尧 发表于 2012-6-16 07:10
我遇到过有的问题是编译器造成的,但不是你这个问题,不好意识

能说说你遇到的编译器情况吗?

出0入0汤圆

 楼主| 发表于 2012-6-16 10:53:37 | 显示全部楼层
学生尧 发表于 2012-6-16 07:10
我遇到过有的问题是编译器造成的,但不是你这个问题,不好意识

能说说你遇到的编译器情况吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 02:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表