打印

while语句问题

[复制链接]
2002|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wen86sv|  楼主 | 2012-10-26 14:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
沙发
阿南| | 2012-10-26 14:30 | 只看该作者
T0_Cnt定义的什么数据类型?
单步调试看看While那的汇编代码,及值的状态可发现为何会跳出。也可以查到500被定义成什么样子了

使用特权

评论回复
板凳
wen86sv|  楼主 | 2012-10-26 14:32 | 只看该作者
C8051F310单片机,keil,T0_Cnt为unsigned int

使用特权

评论回复
地板
阿南| | 2012-10-26 14:32 | 只看该作者
如果是8位单片机,500会被分成两个寄存器,而此时当第一个寄存器比较完后,此时产生了中断而更改了T0_Cnt的数,中断返回后接着比较第二个寄存器,那么此时肯定就出错跳出while了。

使用特权

评论回复
5
ayb_ice| | 2012-10-26 14:50 | 只看该作者
本帖最后由 ayb_ice 于 2012-10-26 14:53 编辑

非原子操作的原因

类似于飞读的概念

while(T0_Cnt<=Time);

U16 x;

for(;;){
    EA = 0;
    x = T0_Cnt;
    EA = 1;

    if(x <= Time){

    }else{
        break;
    }
}

使用特权

评论回复
6
wen86sv|  楼主 | 2012-10-26 14:57 | 只看该作者
#define  Time  500
......

back: while(T0_Cnt<=Time);
if(T0_Cnt<=Time) goto back;

按照阿南所说;加上上述程序,总体上解决了问题;但看着很累赘,有没有更好的解决办法

使用特权

评论回复
7
ayb_ice| | 2012-10-26 14:57 | 只看该作者
volatile U16 x;

        for(;;){
                for(;;){
                        x = T0_Cnt;
                        if(x == T0_Cnt){
                                break;
                        }
                }

                if(T0_Cnt <= Time){

                }else{
                        break;
                }
        }

使用特权

评论回复
8
wen86sv|  楼主 | 2012-10-26 15:12 | 只看该作者
谢谢

使用特权

评论回复
9
joyme| | 2012-10-26 15:13 | 只看该作者
好像有个版主写过这个问题
8位机比较,先比较低位,在比较高位
当T0_Cnt = 0xFF时,低位比较完,结果是低位 > 500 (0x1F4),这时刚好来中断,中断返回后T0_Cnt = 0x100,即高位相等,就会跳出循环了
简单的做法是比两次 while((T0_Cnt <= 500) & (T0_Cnt <= 500));

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
handlike + 1
10
joyme| | 2012-10-26 15:13 | 只看该作者
打错了,& 应该是 &&

使用特权

评论回复
11
handlike| | 2012-10-26 22:27 | 只看该作者
以前还真没有注意过,以后8位机做整型计算及比较时要注意了。

使用特权

评论回复
12
wen86sv|  楼主 | 2014-12-31 11:13 | 只看该作者

上图是中断之前;

上图是中断之后;Cnt_tmp+1;
可以看出实际在执行过程中,比较函数并未执行完就跳到中断;

谁帮我解释下汇编?什么情况下导致while跳出的问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:Success To Victory

4

主题

53

帖子

0

粉丝