longd99 发表于 2010-12-25 20:22:11

请教一个基础问题,单片机中如何避免这种因中断产生的错误?马老师可以指教一下吗?

windows多线程编程中有数据保护手段(如线程锁),单片机中如何实现?(中断必须要开的)
左边是C程序,右边是反汇编代码:
主程序:将count变量的值移到寄存器中。(count=5,寄存器R16=5),
* 此时发生中断,然后切换到中断子程序,保护现场,中断的(count=5,寄存器未知)。
中断子程序:将count变量的值移到寄存器中(count=5,寄存器R16=5)。
中断子程序: 增加寄存器中的值(count=5,寄存器R16=6)。
中断子程序: 将寄存器中的值写回count变量(count=6,寄存器R16=6),
* 此时中断返回:恢复现场,返回主程序,主程序的(count=6,寄存器R16=5)。
主程序: 增加寄存器的值。(count=6,寄存器R16=6)。
主程序: 将寄存器中的值写回count变量(count = 6, 寄存器R16 = 6)。
temp 的值是6而不是7。
如何避免上面的情况发生?也就是最后使count的结果为7,谢谢!
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_607127YX74CT.PNG
(原文件名:abc.PNG)

X-Hawk 发表于 2010-12-25 21:48:59

禁中断

longd99 发表于 2010-12-25 22:35:21

禁中断?玩笑吧?中断是要求开的!
我有一个小的电机控制项目,大概一天中就可能出现运行错误,怀疑是这个引起。
此处只是一段实验代码,所以请帮忙!

NJ8888 发表于 2010-12-25 22:42:32

你如果用8位机处理超8位数据,中断和外部同时写确实有隐患,这时要在处理外部写前关了中断,写完再开

cat_li 发表于 2010-12-25 22:45:34

不是可以切换寄存器组吗

longd99 发表于 2010-12-26 08:02:15

回复【4楼】cat_li
-----------------------------------------------------------------------
和“切换寄存器组”应该没有关系吧!切换寄存器组是51单片机保护现场的一种手段,
这个问题应该属于“原子操作”范畴吧!

-----------------------------------------------------------------------
回复【3楼】
你的方法因该可以但是有没有更好的,不关中断的方法呢?
8位单片机操作8位数据一样会出这种问题,主要原因是++count执行需要3条指令完成,
单片机中,有没有类似windows多线程程序开发中“线程锁”保护全局变量数据,类似的方法?或机制?

longd99 发表于 2010-12-28 13:27:52

回复【3楼】888888888888
你如果用8位机处理超8位数据,中断和外部同时写确实有隐患,这时要在处理外部写前关了中断,写完再开
-----------------------------------------------------------------------
你说的没错,好像只能用这种方法。
我看了IAR AVR的内部函数实现的反汇编代码也是用的这种方法。

1、存储中断状态。
2、关全局中断。
...
此处要保护的全局变量
...
3、恢复中断状态。

machao 发表于 2010-12-30 20:12:01

回复【5楼】longd99
回复【4楼】cat_li
-----------------------------------------------------------------------
和“切换寄存器组”应该没有关系吧!切换寄存器组是51单片机保护现场的一种手段,
这个问题应该属于“原子操作”范畴吧!
-----------------------------------------------------------------------
回复【3楼】
你的方法因该可以但是有没有更好的,不关中断的方法呢?
8位单片机操作8位数据一样会出这种问题,主要原因是++count执行需要3条指令完成,
单片机中,有没有类似windows多线程程序开发中“线程锁”保护全局变量数据,类似的方法?或机制?

-----------------------------------------------------------------------

单片机是硬件,windows是软件。单片机不知道什么需要“锁”,什么不需要“锁”,基本上没有什么“锁”什么的机制。关中断就是“锁”了,这是程序员的编写软件完成的,如同windows,“线程锁”是软件上完成,不是CPU自己硬件系统实现的。

所谓的“线程锁”,其实就是“原子操作”,加上锁的线程,在这个线程过程中是不能被其它线程打断的。意思是一样的,只是说法不同。原子操作通常指几句指令必须完整执行完,而线程可能更大些,但也是必须完整执行,不允许被打断。

machao 发表于 2010-12-30 20:17:07

说句得罪人的话,纯学软件的人,写不出好的面向低层的嵌入式系统代码。他们只能站在别人的肩膀上(OS)上写代码。

longd99 发表于 2010-12-30 20:58:09

谢谢马老师百忙中给以解答!是我基本上了解了,谢谢!
页: [1]
查看完整版本: 请教一个基础问题,单片机中如何避免这种因中断产生的错误?马老师可以指教一下吗?