您的位置 首页 技术

ARM Cortex-M3 MCU的I2C和DMA操作被中止打断的解决方法

ARM Cortex-M3 MCU的I2C和DMA操作被中断打断的解决方法-在项目开发的过程中,发现程序总是死在判断DMA一次传输是否完成这个标志位上。进一步回退分析,发现是在I2C读的过程中,有使用到DMA去取外部I2C设备的data。

在项目开发的进程中,发现程序总是死在判别DMA一次传输是否完结这个标志位上。进一步回退剖析,发现是在I2C读的进程中,有运用到DMA去取外部I2C设备的data。

可是data并没有读完,Data为32bits,DMA在读到18bits时,就呈现读不到data bit了。导致I2C硬件模块不能进一步动作,SCK一向被拉低,没有clock输出,SDA也是如此。

下面是通过示波器抓到的波形:

在上面的波形图中,绿色的是SCK,蓝色的是SDA。

在榜首幅波形图中,有2段波形,榜首段接连的I2C波形,通过承认I2C硬件和DMA合作是正常的。第二段则是有一段I2C波形,然后就SCK和SDA就都被拉低了。

将榜首幅图的第2段波形扩大,便是第二副图看到的状况。能够很显着的看到SCK输出有被其他要素打断。I2C吐出几个clock,被其他要素打断了,clock线即SCK被拉低一段时间,然后clock线再持续吐出几个clock。

直到I2C被频频中止,clock吐不出来停止,SCK和SDA都被拉低,此刻显着的I2C和DMA的合作进程被其他要素频频的搅扰打死了。

通过示波器抓到的波形验证了这一点,然后再来剖析代码和串口输出,发现是外部GPIO一向有中止输入,Cortex-M3 MCU频频的呼应中止,导致I2C&DMA操作被打挂了。

有什么办法来处理这个问题?

办法便是在I2C和DMA操作的进程开端处封闭一切中止,而在操作完毕的时分从头翻开中止,避免I2C&DMA操作被其他中止打断。

ARM MDK编译环境自带的编译器ARMCC,含有内置的c函数,可供操作中止用:

__enable_irq();

__disable_irq();

不过debug发现这两个函数只会在privileged mode运用。也便是说需求Cortex-M3 MCU先进入privileged mode,才干调用这两个函数。

用什么办法让MCU从user mode切换到privileged mode呢,excepTIon handler!

能够用SVC啦,软件能够使用SVC制作一个excepTIon,然后在excepTIon handler中使用MCU的privileged mode来完结自己的使命。有点类似于linux里边的体系调用。

SVC excepTIon能够调用SVC函数,而SVC函数能够传入参数,也能够回来参数。转为体系调用而规划。

举个比如,用户程序调用read()这个体系调用,read()会引发SVC exception,从而调用SVC函数,read()函数的参数传递给SVC函数,SVC在内核态履行硬件动作,并将SVC函数的回来成果,作为read()函数的回来,回来给用户程序。当然linux里边并不一定是SVC,这儿仅仅做个类比。

也便是说SVC能够完结从用户态到内核态的改变,不让用户直接操作硬件。用户只需求记住体系调用API的姓名和函数即可,而不必管硬件的详细完成。

所以这儿咱们就把I2C读的操作放在一个SVC函数里边去完成,并且在SVC函数的开端处调用__disable_irq();在函数的完毕处,调用__enable_irq()。

通过验证,I2C&DMA操作再也不会被中止打断了。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/jishu/346814.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部