您尚未登录。

楼主 #1 2020-04-11 23:02:06

ifree64
会员
注册时间: 2019-06-27
已发帖子: 74
积分: 143.5

【愚人千虑】C51 编程中的常见陷阱

以前没有怎么用C51写过较大的程序,这次因为一个项目的原因,用C51写程序,踩了很多坑,这里总结分享一下,愚人千虑必有一得。

## 常见的中断陷阱之一: volatile变量

如果,中断中修改了一个变量的值,这个变量会被另外的函数访问,这个变量应该声明为 volatile

## 常见的中断陷阱: 临界区

用于中断的引入,程序中产生了真正的并发。
假设有一个变量a,在中断服务isr和funA中都访问了同一个变量a,而对a的操作是非原子的(即对a的操作需要多于1条指令),那么可能发生的情况是funA对a的操作还没有完成,中断发生了,等中断返回,回到funA后,变量a的值已经被破坏了,但funA并不知道,因此将得到了一个错误结果。

对中断和普通函数共享变量的访问,应该是原子操作。如果不是原子操作,那么对变量访问期间,应该关闭中断。

显然,16或32bit 变量操作,在8位CPU中,是非原子的,对他们的操作应该关闭中断。
还有一些8位变量的操作也是非原子操作。操作flags |= 0x80在51单片机中,是非原子的。

## 常见的中断陷阱: 堆栈溢出
中断的返回地址和寄存器是保存在堆栈之中的,所以中断执行时,应该有足够的堆栈空间。

堆栈溢出通常发生在非常深的子程序调用中。

## 常见的中断陷阱: 使用不可重入的函数
特别值得说明的是,整数乘法、浮点数操作可能使用外部的支持函数来实现的。

尽可能避免在中断中调用不可重入的函数,因为这很可能产生难以发现的bug
函数funA是不可重入的,在其内部使用了固定地址的存储空间;若funA在执行过程中,被某一个中断打断,而该中断服务函数又调用了funA,那么中断将破坏原本funA的执行现场,导致错误。这种错误不一定会发生,但如果发生,将非常难于发现。

### 不可重入的函数什么时候会导致错误
C51在固定的位置分配变量的存储空间。一个函数,如果在执行中途,被中断打断,而且中断中又再次调用该函数,那么中断就可能破坏掉原来的执行现场(分配在固定空间的值)导致执行出错。

离线

楼主 #5 2020-04-13 12:40:19

ifree64
会员
注册时间: 2019-06-27
已发帖子: 74
积分: 143.5

Re: 【愚人千虑】C51 编程中的常见陷阱

51确实太多不方便的地方,但是架不住便宜啊,有的小项目,51单片机只要1元左右。

离线

楼主 #7 2020-04-16 19:23:07

ifree64
会员
注册时间: 2019-06-27
已发帖子: 74
积分: 143.5

Re: 【愚人千虑】C51 编程中的常见陷阱

n76e就是51啊,以前stm8s003确实很便宜,但有一段时间涨到了3元左右,一大票的003兼容国产51出来。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn