打印
[RISC-V MCU 应用开发]

MRS遇到一个莫名奇妙的问题,帮忙看看,困扰一天了

[复制链接]
2161|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gaobq|  楼主 | 2022-5-7 14:26 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
se, AI, MRS, RS, TI
使用CH32V307VC开发板,使用定时器TIM3定时中断,设置一个变量Send_Flag为1,在main循环中,啥都不干,判断Send_Flag是否为1,如果是发送一个字符,并清零。多么简单是吧。问题是,Send_Flag明明等于1,就是不进入if语句执行。第一次运行可以进if语句,后面再运行就进不去了,好奇怪

ADC_DMA_16CH.zip

611.72 KB

使用特权

评论回复

相关帖子

沙发
gaobq|  楼主 | 2022-5-7 15:48 | 只看该作者
上面的工程是在wch提供的例子上修改的,为避免环境,路径的影响,重新使用MRS生成一个工程,添加TIME模块,但效果依旧如此

CH32V307VCT6_16AD.zip

780.17 KB

使用特权

评论回复
板凳
gaobq|  楼主 | 2022-5-7 16:00 | 只看该作者
找到解决方法了,添加一条延时语句就正常了,不知道为什么需要延时?

使用特权

评论回复
地板
qq172179| | 2022-5-9 14:09 | 只看该作者
全局变量在中断做标志位时,声明和定义加上volatile,不然某些情况下会被优化成定值

使用特权

评论回复
5
WCHTech2| | 2022-5-10 10:53 | 只看该作者
gaobq 发表于 2022-5-7 16:00
找到解决方法了,添加一条延时语句就正常了,不知道为什么需要延时?

您好,因为定义变量被编译器优化了,建议在定义的变量前面加volatile关键字防止优化或者将编译器优化等级设为0,均可解决问题,如下图

使用特权

评论回复
6
gaobq|  楼主 | 2022-5-10 12:02 | 只看该作者
谢谢两位,果然如此,不同的编译器差异很大。

使用特权

评论回复
7
sadicy| | 2022-5-27 20:34 | 只看该作者
真不错~~~

使用特权

评论回复
8
海滨消消| | 2022-6-22 16:34 | 只看该作者
原来是编译器的问题啊,学习了

使用特权

评论回复
9
binbin0317| | 2022-6-23 10:29 | 只看该作者
这个是典型的开了优化的问题吧,把优化等级改为O0(一般debug模式就是这个,不过好像MRS统一采用Os来减少体积)。不加volatile的话,编译器认为这是函数内应该不会被改变的数据,在进去的时候就直接赋值给寄存器,直到函数结束前每次调用这个数值实际上直接读取寄存器而不是再读取原来的值。来提高速度和减少体积。就算是keil那些编译器,记得也会有这个优化逻辑。

使用特权

评论回复
10
gaobq|  楼主 | 2022-6-23 16:44 | 只看该作者
binbin0317 发表于 2022-6-23 10:29
这个是典型的开了优化的问题吧,把优化等级改为O0(一般debug模式就是这个,不过好像MRS统一采用Os来减少体 ...

谢谢,记住了

使用特权

评论回复
11
吾要单片机| | 2022-6-23 17:29 | 只看该作者
gaobq 发表于 2022-5-10 12:02
谢谢两位,果然如此,不同的编译器差异很大。

请问,下载使用MRS需要交费吗?

使用特权

评论回复
12
gaobq|  楼主 | 2022-6-24 17:57 | 只看该作者
吾要单片机 发表于 2022-6-23 17:29
请问,下载使用MRS需要交费吗?

国产免费IDE

使用特权

评论回复
13
tototm| | 2022-6-26 22:06 | 只看该作者
遇到同样问题,也是加延时解决问题,很好奇为什么加延时没有被优化掉

使用特权

评论回复
14
tototm| | 2022-6-27 07:01 | 只看该作者
不加延时也可以,把加延时换成加一条printf语句也可以达到目的,太神奇葩

使用特权

评论回复
15
binbin0317| | 2022-7-5 15:09 | 只看该作者
tototm 发表于 2022-6-27 07:01
不加延时也可以,把加延时换成加一条printf语句也可以达到目的,太神奇葩

编译器优化逻辑就是非volatile变量认为在这段代码中没有修改过变量,就只读一次变量到寄存器,之后直接读寄存器来提高运行速度。
调用了其他函数,实现了跳转。编译器无法预测调用的函数是否有修改这个变量,所以干脆就重新读取变量。
如果调用一个很短的函数,或者inline函数,编译器可预测到函数里面肯定没修过过这个变量的话,编译器就不会重新读取了。

使用特权

评论回复
16
haohao96| | 2022-7-11 08:58 | 只看该作者
我也遇到过这样的问题,我一般想到的是编译器代码优化的问题。一般先将编译器的优化级别设置为最低或者不优化,待所需功能调试正常后,再将代码优化等级恢复为实际所需要的等级,然后再编译,这个时候若再出现问题,就可以很明确的确定是编译器优化所带来的问题。

使用特权

评论回复
17
tototm| | 2022-8-1 10:08 | 只看该作者
binbin0317 发表于 2022-7-5 15:09
编译器优化逻辑就是非volatile变量认为在这段代码中没有修改过变量,就只读一次变量到寄存器,之后直接读 ...

难怪,或许自己知识有限,但是也没有必要一上来就将优化开到S级,强调自己的IDE厉害,编译出来的代码少,
给刚入手的人带来困惑

使用特权

评论回复
18
kjkujkj22| | 2022-8-4 15:29 | 只看该作者
volatile关键字,编译器设置的问题的,造成的优化。

使用特权

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

本版积分规则

166

主题

804

帖子

5

粉丝