ADC求和注意事项

前言:

局部变量在参与求和等运算前必须先初始化,否则得到的值是不确定的,会产生意想不到的结果。

典型错误示范:

/**
  * 函    数:将获取AD转换的值进行均值滤波
  * 参    数:无
  * 返 回 值:AD转换的值,范围:0~4095
  */
uint16_t ADC_AverageFilter(void)
{
	volatile uint32_t adc_sum; //未初始化就开始计算,会产生意料之外的结果
	for(int i=0;i<AD_NUM_MAX;i++)
	adc_sum += AD_GetValue();
	return adc_sum / AD_NUM_MAX;					//读数据寄存器,得到AD转换的结果
}

一开始没发现异常,但是随着进一步测试,发现ADC采样超出了最大阈值4095,甚至是随机的大数字。

技术分析:
局部变量处于栈区,其数值是随机的,即当时内存中的值,必须在使用前初始化。

C语言的内存模型分为5个区:栈区、堆区、静态区、常量区、代码区。每个区存储的内容如下:
1、栈区:存放函数的参数值、局部变量等,由编译器自动分配和释放,通常在函数执行完后就释放了,其操作方式类似于数据结构中的栈。栈内存分配运算内置于CPU的指令集,效率很高,但是分配的内存量有限,比如iOS中栈区的大小是2M。
2、堆区:就是通过new、malloc、realloc分配的内存块,编译器不会负责它们的释放工作,需要用程序区释放。分配方式类似于数据结构中的链表。“内存泄漏”通常说的就是堆区。
3、静态区:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后,由系统释放。
4、常量区:常量存储在这里,不允许修改。
5、代码区:顾名思义,存放代码。
引用自:原文链接

修改之后输出参数在正常范围内波动:
在这里插入图片描述

总结:

程序设计中的隐藏疏漏可能会导致最终计算结果错误,需要严谨对待每一处的细节。

### ADC指令的功能与使用方法 #### 一、ADC指令功能概述 `ADC` 是汇编语言中的加法带进位指令,其主要作用是对两个操作数相加的同时考虑上一次运算产生的进位标志(Carry Flag, CF)。具体而言,该指令会将目标寄存器的内容加上源操作数以及当前的进位标志值,并将结果存储到目标寄存器中[^2]。 #### 二、语法结构 以下是 `ADC` 指令的一般形式: ```assembly ADC destination, source ``` 其中: - **destination** 表示目标操作数,可以是一个寄存器或者内存地址。 - **source** 表示源操作数,同样可以是寄存器或立即数。 #### 三、工作原理 当执行 `ADC` 指令时,计算过程如下所示: \[ \text{Result} = (\text{Destination}) + (\text{Source}) + \text{CF} \] 例如,在给定的例子中: ```assembly mov ax, 1 ; 将 AX 寄存器初始化为 1 add ax, ax ; 执行无符号整数加法,AX 的值变为 2 并可能设置 CF=0 adc ax, 3 ; 计算 (AX) + 3 + CF,最终 AX 的值为 5 如果 CF=0 或者 6 如果 CF=1 ``` 如果前一条指令设置了进位标志,则此条 `ADC` 指令的结果将会受到额外的影响。上述例子展示了如何通过组合多条指令来处理多位数值加法的情况。 #### 四、应用场景 在嵌入式开发领域,尤其是涉及大数字运算时,`ADC` 指令非常有用。它允许程序员逐字节地完成超过单个寄存器容量的大数据加减操作。比如对于 STM32 微控制器来说,虽然内部集成了模数转换模块用于模拟信号数字化处理[^1],但在某些情况下仍需借助此类低级控制手段实现更复杂的算法逻辑。 #### 五、注意事项 需要注意的是,每次调用之前都应确保清楚当前状态下的 Carry Flag 是否已被正确置位;否则可能会导致错误累积影响后续程序运行效果。 ```assembly ; 示例代码展示了一个简单的双精度加法 mov cx, 0xFFFF ; 高位部分设为最大短整型负数 (-1) mov dx, 0x8000 ; 低位同理 mov bx, 0x7FFF ; 另一组高位置零接近正边界的最大正值 mov ax, 0x7FFE ; add dx,bx ; 对较低有效半部求和并更新 CF 若有必要的话 adc cx,dx ; 考虑到来自前面 ADD 运算所产生的任何溢出情况后再做高位累加 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值