SUPER_CRJ 发表于 2021-11-28 16:26:29

STM32F0-数组定义为局部变量在中断会出错?

本帖最后由 SUPER_CRJ 于 2021-11-28 16:30 编辑

遇到一个特别奇怪的问题。请大神赐教(程序已上传附件)。
如图,在做一个LCD12864测试。
先说重点:定义全局变量没有问题,局部变量就有问题。

有一个数组只需要在这个中断里面使用:
如果在中断定义为局部变量,就会在LCD12864中某段位置中:显示一段乱码。把:优化等级调整最低,把堆栈调大几倍都不能解决。
只要:定义为全局变量,立刻解决。

具体情况是这样:做LCD12864的显示测试,定义1KB的RAM,然后在I2C中断中配合DMA不断传送数据,来达到减少CPU开销,因为STM32F0的I2C,每次只能传送255字节(也可以超过,但是相对麻烦。)。而这1KB的RAM,每次在I2C中断中,会每次传送128字节到一个临时数组(这个临时数组就是:出问题的数组!)。
然后临时数组配置为DMA的MEMORY地址。
在前台程序中:有一个按键程序,当按键按下时候:操作了这个1KB的-RAM,但是和出现乱码的位置没有关系。然后:就会看到LCD出现了一瞬间的乱码。
但是:只要这个临时数组,定义在中断外面为全局变量就没有事!





xml2028 发表于 2021-11-28 16:30:34

这么大的数组最好定义全局变量啊

登云钓月 发表于 2021-11-28 16:36:05

栈空间设置的多少?

wye11083 发表于 2021-11-28 16:44:38

登云钓月 发表于 2021-11-28 16:36
栈空间设置的多少?

估计lz没改过,stm32默认好像是512字节。

t3486784401 发表于 2021-11-28 17:04:14

LZ心太大,考虑这种情况:

当中断函数 I2C1_IRQHandler 结束退出时,作为源的 tmpGddram 完成 DMA 没有?

函数退出了,局部变量该销毁了,如果这时候 DMA 还在走你说会咋样?
在搞 C++ 的时候,最忌讳就是局部对象都销毁了,还在别的地方通过指针调用方法,

然后就是经典的:【找不到对象】

SUPER_CRJ 发表于 2021-11-28 17:23:25

t3486784401 发表于 2021-11-28 17:04
LZ心太大,考虑这种情况:

当中断函数 I2C1_IRQHandler 结束退出时,作为源的 tmpGddram 完成 DMA 没有?


高手。我查了几个小时。
我发完帖子也突然想到了,准备明天回帖的。
局部变量函数完成后会被销毁,然后其本来所占用的地址,可能会被重新利用。
解决方法:全局变量,或者定义:静态变量。
之前局部变量这样使用习惯了。{:lol:}

1a2b3c 发表于 2021-11-28 19:53:58

SUPER_CRJ 发表于 2021-11-28 17:23
高手。我查了几个小时。
我发完帖子也突然想到了,准备明天回帖的。
局部变量函数完成后会被销毁,然后其 ...

不改成不是DMA方式输出一下就对了,
DMA你只需要配置几句话就跑了,哪知道别人在后面传输半天,你走的时候还没有传完
我之前也遇到这个问题,最后将你所谓的临时数组改成静态的了事,实际上和全局一回事,只是程序看起来相对独立点罢了,

armstrong 发表于 2021-11-29 08:57:46

所有的中断共享一个堆栈空间,当I2C中断退出,其它中断进入(比如SysTick,UART,等等)就覆写了某些堆栈内容。
由于DMA传输并不能立即把堆栈中的内容传输完毕,有大把的机会留给其它中断来破坏内容。

初音之恋 发表于 2021-11-29 09:05:51

函数执行完局部变量全部无效了,必须在函数里把这个变量发完才有用,不然直接跑飞

nade 发表于 2021-11-29 09:21:42

t3486784401 发表于 2021-11-28 17:04
LZ心太大,考虑这种情况:

当中断函数 I2C1_IRQHandler 结束退出时,作为源的 tmpGddram 完成 DMA 没有?


+++++++++++++

鲜衣怒马 发表于 2021-11-29 09:52:15

又学到了,以前没怎么用过DMA,没注意过副作用

yuyu87 发表于 2021-11-29 10:00:51

中断里这样写肯定会出问题,中断里做一些标志,然后在外部代码里写
页: [1]
查看完整版本: STM32F0-数组定义为局部变量在中断会出错?