STM32单片机 while(m_Flag == 0);不能退出死循环的解决方法

在调试电机正反转程序时,遇到一个死循环问题。电机通过光耦感应改变控制变量m_flag,但while(m_flag==0)循环无法跳出。问题源于编译器优化导致的变量状态更新不及时。解决方案包括降低编译器优化等级、加入延迟函数或使用volatile关键字避免优化。通过这些方法,成功解决了程序死锁的问题。
摘要由CSDN通过智能技术生成

一、问题描述:

在调试一个电机运转方向切换的工程时,在main()函数中,while(1){}之前,设置一个控制电机转动的子程序,子程序中涉及到了一个电机运转到某位置后,触发光耦(设置的的是外中断,触发后置位一个标志),然后反向运转。

程序设计原理是,先让电机正向运转,同轴旋转的一个挡片,遮挡光耦触发外中断,在外中断服务函数中,置位一个标志(m_flag = 1)。当子程序中检测到这个标志后,控制电机反向运转。这里用到了while(m_flag == 0);的等待函数。

程序编译下载后,无论挡片怎么遮挡光耦,子程序都无法跳出while循环,while进入死循环了,永远无法跳出来(已经反复检查过程序,确保程序语法、运行逻辑、触发条件等都没有任何问题)。

二、问题原因

通过网上查找资料,说是程序死在了汇编代码:CMP  r0,#0x00 这里了。

原因是编译器在编译时认为该状态变量只会在main函数中使用,所以只取了一次状态值到r0,然后状态值发生了变化,主函数却未能感知到,所以才出现这个问题。

三、解决方法

解决的方法有三个:

        (1)、修改编译器的优化等级,将Options for target’***’->c/c++->optimization从默认的Level3 改为Level0。

        (2)、在while的函数体内加一个不影响程序执行结果的delay。那么当调用之后再判断时,就会再取一次状态值进行CMP。

               while(m_flag == 0)

                    {

                      HAL_Delay(1);

                    }

        (3)、在m_flag变量定义的时候,加上volatile修饰,或者加前缀__IO,指出与volatile变量有关的运算,不要进行编译优化,确保变量不会因编译器的优化而省略。

例如:__IO uint8_t m_flag = 0;

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值