stm8中断使用

工程应用分析
最近的一个项目中用到了stm8s,一个比较重要的知识点就是中断的使用。暂且称stm8s这边做从机,要进行双机通信。stm8s作“从机”接收数据,也可以发送数据给主机。
自定了一个通信协议,一个CLK线,一个DAT线,CLK线总是由主机边控制。类似于I2C通信,CLK为高时,DAT由高到底表示开始。CLK位高时,DAT由低到高表示结束。CLK为高电平时,DAT线数据为保持,为低电平时允许数据跳变。实际的时序图如下:
这里写图片描述
我这边接收数据其实有很多种方法,比如:
1.可以在程序主循环while(1)中每一次周期监视检测电平的变化,来达到判断信号的目的
2.采用延时,很多常用的通信会采用,比如我们接收数据,在高电平读数据,传送16位数据,得到第一个CLK高电平之后,可以直接延时固定间隔时间读,就可以得到下一个高电平时DAT数据,以此类推
3.采用中断,不依赖于时间,完全依赖于硬件检测电平变化
4.采用中断加延时的方法

评价:
1的方法,对时间要求比较高,因为有传输速度的要求,电平变化本来比较快,应尽可能缩短主循环一次执行时间,后续添加其他功能会有影响
2的方法,对时间要求比较高,双机通信,一对一尚可,如果一对很多,不稳定,待验证
3的方法,完全依赖于自身的硬件,比较稳定
4的方法,依然存在2的缺点,情况类似

最终实现方法DAT触发条件为上升沿和下降沿,CLK触发条件为上升沿
DAT触发,检测DAT电平,只有开始和结束符合条件,所以可以用这个来判断开始位和结束位。CLK上升沿触发中断,读DAT,可以保证肯定是在高电平时读的数据。俩个中断同时开启,最终的操作还是简单的,参考代码如下:
这里写图片描述
这里写图片描述

————————————————————————-分割线———————————————————————————

stm8的中断具体使用方法
和常规的中断使用类似,首先要关闭全局中断,然后初始化中断用到的GPIO口,设置输入输出,是否可以中断,然后设置触发条件,用到多于一个中断,就要设置优先级。
需要指明的是stm8s的中断屏蔽是采用优先级的方式,有一个系统CPU寄存器保存当前执行程序的优先级。

这里写图片描述
过程问题:
在中断中,不能使用串口打印,会影响程序执行,就如前面图形所示波形,黄色线上升沿和下降沿触发中断,正确的会检测到10个中断,并且为2个高电平7个低电平。最终通过中断处理函数里的打印,得到一个本该低电平的值,检测到一个高电平值,推想应该是发生了偏移。在中断处理函数里面,检测高电平的判断条件里加了一个变量用作计数,在while(1)主循环去打印该值,得到了2,表示检测情况正确。
产生疑问:中断执行应当每一次都是独立的,怎么会出现其中一次出错的情况呢?

还有一种中断接收数据的方法,理论上行的通,结果还是有点问题,没有找出来。
DAT下降沿判断开始,然后关闭掉该中断,上升沿CLK去读数据,读完数据,设置DAT上升沿触发,如果触发,判断结束,将触发条件设为下降沿,迎接下一次数据传输的开始。试验验证,传输数据12位每次都可以正常,一旦到了多余12位,就出现首次中断不能判断结束位,只有下次才可以判断到,数据也只能是一次正确,后面出错。和上面的情形有点类似,中断函数好像出现了一个时间累加出错效果。

现在自定了一个通信协议,波形类似于i2c,就是一次传送16字节。

bug解决:
1.采用了俩个独立的中断触发,满足了要求,但是数据只有第一次是正确的,后面就出现了固定的每一次又移一位的问题。一开始怀疑串口,可能是串口有缓冲,数据没有完全从打印的队列中打印完毕,但是不管是直接打印一个值,还是分开打印每一位都是错误的,而且俩种方式下,错误结构都是一样的。后来想到了,可以用调试,IAR虽然粗略,但是调试中观察一个变量的值还是不成问题,发现数据依然是错的,串口是没问题的。每次移一位,可能是把停止位当开始位了,所以会出现又移的假象。原来是第17个上升沿判断结束,更改判断触发条件的标志位,改了17以后果然可以了。庆祝一下!!!

解决过程:
有了最终实现的结果,想方法去实现。延时的方法最好做,最终没有采用,完全用中断去做。过程中,遇到了很多阻力,也学到了一些东西,遇到问题,就开始思考可能原因,查资料确认结果。
一开始想需要屏蔽中断,在stm8s中是采用优先级的方式,优先级设到最高,就没有其他中断可以打断。中断屏蔽的使用,还得再查看相关资料确定。最终采用的方法,中断上使用挺简单,重要的是过程和思路的形成,排除了很多方法,才想到这一个,然后去验证。

单片机有必要学一下,了解最基本的寄存器。

猜你喜欢

转载自blog.csdn.net/xingzhibo/article/details/51438123
今日推荐