在用28335采样的时候,难免会碰到因为数据类型的问题导致无法顺利从结果寄存器ADCRESULT中提取到我们想要的值,
寻其原因是因为在
结果寄存器中的数据类型,和我们需要精确读出的数据类型不同,
尤其是ADC是存在比例关系的,在进行除法运算的时候经常会出现错误,
所以在此分享一下我提取的方法,
主要运用volatile限定符来改变数据类型。
1 volatile限定符
当一个对象的值可能会在编译器的控制或检测之外被改变时,例如一个被
系统时钟更新的变量,那么对象应该声明成volatile。
一般说来,volatile用在如下的几个地方:
1、
中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、
存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。
简单点:
就是该变量会以编译器无法预知的方式发生变化,请编译器不要做优化(所有的编译器的优化均假设编译器知道变量的变化规律)
2 ADC结果寄存器介绍
首先我们看结果寄存器,F28335内部A/D只有12位,用16位的结果寄存器来存储,所以必然有四位是空着的,如下表所示是从15-4位的有效位。
然后再看
结果寄存器内的数据类型
从下图头文件的定义我们可以看出,在结果寄存器内
Uint16 型,而
Uint16 代表
unsigned int 即无符号整型。而我们需要读取的一般是小数,
即浮点型。F28335的浮点型是有7位小数的,
所以我们就需要用
volatile限定符来定义我们的读取值
volatile Uint16 SampleTable[1];
volatile float adc0=0;
读取部分
SampleTable[0]= ( (AdcRegs.ADCRESULT0)>>4);
adc0=(float)SampleTable[0] * 3.0 /4096.0;
首先定义其为volatile变量
,然后从
寄存器AdcRegs.ADCRESULT0内读取出其10进制的值,并通过
(float)操作强制转换数据类型为浮点型,使其计算值能够赋给同为volatile float 型的 adc0,并且在后面的乘法和除法运算中也要使用3.0和4096.0
这是因为
1.计算算术表达式结果时,相同数据类型的数据/变量进行运算,结果保持原有数据类型。
2.当不同数据类型的数据/变量进行运算时,结果为精度高的数据类型。
小结:
整体而言,从寄存器
AdcRegs.ADCRESULT0 到 我们需要的
1.34423这种数,需要从
16进制(Uint16)———> 十进制(Uint16)——> float
通过使得中间这个十进制数变成 volatile 能够有效的防止因为数据类型的转换和除法导致的错误。