F28335 ADC数据类型转换的问题

在用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 能够有效的防止因为数据类型的转换和除法导致的错误。

猜你喜欢

转载自blog.csdn.net/sy243772901/article/details/83894377