6723|14

87

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

一个非常奇怪的keil c51串口中断问题! [复制链接]

一个非常奇怪的keil c51串口中断问题!
比如我的程序如下:
uchar b[10];
#define a4 0x03
void fun1(void) interrupt 4
{
fun2(2);
}
fun2(uchar a2)
{
while(a2--)
{
....
}
fun3(a4);
}

void fun3(uchar a3)//这个函数无论有没有设置重入函数 都有下面那个问题
{
b[0]=1;
a3+=b[0];   
b[1]=a3;  
}
问题:在keil仿真调试过程中 我关掉串口中断 在主程序运行fun3(4) 结果是对的b[0]=1
b[1]=4 但是我开了串口中断 并且进入了串口中断后 问题就有了 在fun1进入fun2的时候 参数传不进去 调试结果是a2=0x00 但是while循环又确实4次 并且又进入fun3的时候在fun3观看变量 a3=0,b[0]=1,b[1]=0;

调试一晚上 仍然极不明白  求助!!

最新回复

我也遭遇过类似的问题.被困扰了两天 是定义中断函数时加了 using x 引起的. 去掉 using就可以了. 因为如果不加 NOREGPARMS 参数是通过寄存器传递的...而你的中断函数也 using 寄存器. 而此时 keil 编译器不会给出警告.   详情 回复 发表于 2007-9-7 15:14
点赞 关注

回复
举报

77

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
不用仿真器一样可以调程序啊!有时仿真器会出些莫名奇妙的问题!当然你的问题就不一定了,不过你可以编译成汇编语言,直接看看汇编语言,确认一下参数的传递。
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
fun2(uchar a2)
{
while(a2--)
{
....
}
fun3(a4);//这个a4从哪来的啊?
}

调试结果是a2=0x00 但是while循环又确实4次//很怪啊,这会出现?
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

4
 
o 对了
我上面说的那个fun3函数  函数原来是这样的
uchar FrameEncap(uchar FrameType,uchar Num_IFrame,uchar idata * p_Data_IFrame)
是不是参数过多了  我好像在那本书看过 在keil c51 参数不能过多的

不知道是不是这个问题  试试先!!
 
 
 

回复

126

帖子

0

TA的资源

一粒金砂(初级)

5
 
书上原话:
模块间接口:
1 通过寄存器传递函数参数
最大只能有3个参数通过寄存器传递

2 通过固定存储区传递

3 函数返回值一律放在寄存器中

由1所说 参数只有3个 但是由2却可以多于3个啊!!

迷漫!!
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

6
 
给个人回个帖啊 一个人不能连续发3个帖的啊
现在我改了一下函数格式 也不行 在fun3中还有很奇怪的问题
fun1:  void Frame_Rec_Serial(void)        interrupt 4 using 1
fun2:  void CheckFrame_Serial(void)
fun3:  uchar FrameEncap_R(uchar FrameType)
还是一样 fun1调用fun2 fun2调用fun3(0x0f)
调试问题  FrameType总是为0x00
在fun3中部分语句
//#define FlagFrame 0x7e

        buffer_Send_Serial[0]=FlagFrame;
        CountFCS=buffer_Send_Serial[0];

        buffer_Send_Serial[1]=0x00;
        CountFCS+=buffer_Send_Serial[1];

        buffer_Send_Serial[2]=FrameType;
        CountFCS+=buffer_Send_Serial[2];

        buffer_Send_Serial[3]=CountFCS;
        buffer_Send_Serial[4]=FlagFrame;
调试结果为:
buffer_Send_Serial={0x7e,0x00,0x00,0x7e,0x7e}
那么分明FrameType得到的值为0x00  并且CountFCS在Watch Window那里一直是0x00
但是buffer_Send_Serial[3]=CountFCS;却得到了0x7e

现在调试了一整天 我狂晕!!

 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

7
 
我晕,
//#define FlagFrame 0x7e

        buffer_Send_Serial[0]=FlagFrame;
        CountFCS=buffer_Send_Serial[0];

        buffer_Send_Serial[1]=0x00;
        CountFCS+=buffer_Send_Serial[1];

        buffer_Send_Serial[2]=FrameType;
        CountFCS+=buffer_Send_Serial[2];

        buffer_Send_Serial[3]=CountFCS;
        buffer_Send_Serial[4]=FlagFrame

难道0x7e+0x00+0x00!=0x7e???????!!!!
你写的程序不就是把buffer_Send_Serial中[0]--[2]中的数累加起来放到[3]中吗?
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

8
 
哦,刚才没把问题看全。现在的问题是参数不能传递哦。

你可以试试把函数改一下,
fun3:  uchar FrameEncap_R(uchar FrameType)
改成
fun3:  uchar FrameEncap_R(uchar FlagFrame),
看到底是怎么回事。

不知道你是用什么调试的?如果用的是仿真机,建议只用软件来调,就是不连单片机,只在电脑上调。

你也可以看看它的汇编代码,作一下参考。
还要考虑一下是不是有些东西是不是被优化掉了?

问题应该不会太大。

 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(中级)

9
 
很好!又可以发帖了
deletor():  
fun3:  uchar FrameEncap_R(uchar FrameType)
改成
fun3:  uchar FrameEncap_R(uchar FlagFrame),

FlagFrame是一个宏来的 它的值为0x7e

虽然我现在换了个方法解决了 但问题是什么原因还是不清楚  希望个位探讨一下
现在我换了用全局变量做参数  不在调用函数传参数进去  这样做就可以了 uchar FrameEncap_R(void)

而之前在调用函数才传参数进去 uchar FrameEncap_R(uchar FrameType) 在main中调用是没有错的 但是在中断调用却有上面的问题!

哦 我知道了 在看汇编的时候是这样的 //因为我改了程序 不能弄回去看是什么程序了 我把记起来的就写上去吧  大家看对不对吧  


比如:
//FrameEncap_R(0x07)
mov r6,#0x07
lcall FrameEnca_R(...)
mov r6,0x27
哎呀 还是想不起来了  不好意思  上面可能有点错了  

但我记得就是 它用r6做传递参数的  但是 它的语句是mov r6,0x.. (0x..就是参数存的单元 好像是寄存器的地址)就是把一个ram单元的内容做参数了 然而在主函数调用可以 而在中断调用却有错误 是因为0x..(0x..就是参数存的单元 好像是寄存器的地址)虽然没有变 但是r6却不是那个组的拉!

不好意思 说的很乱!总的意思就是说寄存器组变了造成的问题!
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

10
 
mark下
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

11
 
如果在中断函数中调用了其他函数,则被调用函数所使用的寄存器组必须与中断函数相同!!!

你的中断函数是用using 1组的,可能你的被调函数用了0组吧。
去掉using 1试试?或设为相同?

我的习惯是中断函数以及其所调用的函数中用全局变量传递参数,尽量不使用到寄存器组(不使用局部变量),否则寄存器组会推、入栈浪费时间,而且可减少如楼主一样出错后要狂调试的隐患。
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

12
 
keil难道没有给你一个警告么?

你在ISR和主循环,或在不同的ISR里调用同一个函数,会收到一个警告的。
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

13
 
楼主的问题可能有两个来源,一是局部变量,一是参数传递。

keil是不会在堆栈上分配局部变量的,如果一个函数有较多的局部变量,部分局部
变量将要在固定的存储区分配,如果它在不同的ISR被调用,几乎是一定要出问题。
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

14
 
现在改了程序  改为全局变量 就可以了 虽然不知道出现问题的原因.

wlxu1209(无限循环)  他的观点我是同意! 但我又有问题 因为全局变量就霸占了ram  因为中断有些变量是不需要如此的   ram的利用率不高 对于51来说是不好的吧 他那么少ram
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

15
 
我也遭遇过类似的问题.被困扰了两天

是定义中断函数时加了 using x 引起的.
去掉 using就可以了.

因为如果不加 NOREGPARMS

参数是通过寄存器传递的...而你的中断函数也 using 寄存器.

而此时 keil 编译器不会给出警告.



 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表