CC2430单片机标称AD转化精度为14位,在单片机中算是比较高的了,CC2430最广泛的用处是作为传感器来运用的,而传感器丈量的物理量的原理多半是将物理量转化成电流、电压等模拟信号,再经过AD转化进入单片机处理。一切用好CC2430的AD是运用好CC2430的一项基本技能。
一、CC2430的ad的几个重要参数
1、量化精度14位
2、转化办法为代儿塔-西格玛办法
3、8路独立通道、4路差分通道
4、参阅电压可选内部、外部参阅电压;(详细参阅datasheet)
5、有DMA功用;(每个通道都能触发),这个功用我以为非常重要,主要是做沟通采样,很便利也很简单处理
6、精度可选;
二、单通道AD转化
单通道ad转化很简单,需求留意的是
1、搞清几个AD寄存器的效果、设置的办法P0IFG、PERCFG、P0SEL、ADCCFG、P0DIR
2、被测电压的负极要连到CC2430的GND上
3、转化后数值的ADCL、ADCH内数值的处理,要将ADCH放在低字节、ADCL放在高字节。将一个Uint16右移两位(最终两位没有用);即可得到所要的ADC值;
4、电压核算公式=ADC/精度*参阅电压;
ADC:第3条所得
精度:依据所选位数,例如位数选14位,精度=2的14次方=16384
参阅电压:可选内部或许外部,例如选内部的1.25伏。
5、输入电压不要超越参阅电压。
二、差分通道转化
1、选对输入引脚、设对寄存器
2、电压核算公式=ADC/精度*参阅电压;这儿的精度相对于单通道的精度要再除以2
例如:转化的值=4567; 位数=14位 ;参阅电压=1.25v 则被测电压=4567/16384*2*1.25=0.6969 伏
再例如:转化的值为=12345; 位数=14位 ;参阅电压=1.25v 则被测电压=(12345-16384)/16384*2*1.25=-0.6163 伏
三、运用差分通道转化时怎样进行补偿
一切的AD器材都有或许有必定的0点误差,即电压输入为0时,转化成果不为0,有或许大于0,也有或许小于0.所以,要得到正确的成果就要进行补偿。应遵从以下几个过程:
1、测channel=0x0c,时的AD值
通道号选0xc时,单片机以为被测电压为0,测得AD值为ADoffset1(有或许为+、也有或许为-);
2、测被测通道的AD值
假定测P0.4、P0.5两个引脚间的电压,测得AD值为ADC(有或许为+、也有或许为-);
3、被测电压=(ADC-ADoffset)/精度*2*参阅电压;
四、运用DMA通道进行AD采样;
CC2430的DMA通道功用很强壮,有多个触发源。详见datasheet;
沟通采样时运用DMA AD转化有许多优点
a、采样距离简单核算
采样距离可经过公式Tconv = (decimation rate + 16) x 0.25 μs.来核算14位是decimation=512
b、AD选用的一起、单片机能够做其他作业,相互不搅扰
c、存储在一个数组之中,便于今后核算。
1、首先要了解CC2430的DMA怎样运用
2、可参阅我的另一篇文章《CC2430 运用dma存储adc接连转化数据的存储,及转化时刻的核算》
3、举例说明:程序比较长能够只看前半部分,后半部分功用为核算对正弦波正弦波正半周平均值,DMA转化的精华在上半部分。
float getseadc (uint8 channel, uint8 refvolt)
{
volatile uint16 reading = 0;
uint8 resbits;
volatile uint16 adctemp,i;
volatile uint8 tmp;
uint8 adcChannel = 1;
volatile float sum,sum1;
int tmp1,max,m,n,X,lst;//m为大数,n为小数
ADCCFG |= adcChannel;
if (channel==0x0A)
{
ADCCFG=0x30;
};
resbits=0x30;
tmp = ADCL;
tmp = ADCH;
osal_int_disable( INTS_ALL );
//装备dma
adcdma.srcAddrH=0xDF; //adch的逻辑地址
adcdma.srcAddrL=0xBA; //adcl的逻辑地址
adcdma.dstAddrH=(uint8)((uint16)&adctab>>8); //方针内存块中的地址高位
adcdma.dstAddrL=(uint8)&adctab; //方针内存块中的地址位置
adcdma.xferLenV=0x03; //
adcdma.xferLenL=0x20; //传送0x320个字符
adcdma.ctrlA=0xd7; // word传送 not bytes ;重复单次传送;1号差分通道完毕后触发
adcdma.ctrlB=0x10; //意图地址主动加1,中止不翻开。
DMA0CFGL=(uint8)&adcdma; //将0号dma通道设置为上述结构
DMA0CFGH=(uint8)((uint16)&adcdma>>8);
DMAARM=0x01; //投入0号dma通道asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
adctemp = channel | resbits | (refvolt<<6);
ADCCON2 = adctemp;
ADC_SAMPLE_CONTINUOUS();
tmp=0;
while (!(DMAIRQ & 0x01));
DMAARM|=(1<<7);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);
DMAIRQ=0;
ADC_STOP(); //转化完毕 ,至此一切800次AD转化的值现已存在adctab中了。
tmp=ADCL;
tmp=ADCH;
ADCCFG &= ~adcChannel;
sum=0;
sum1=0;
max=0;
tmp1=0;
X=-1;
lst=-1;
for(i=0;i<800;i++)
{
//int AdtoInt(uint16 adctmp,int offset)
//转化成int
tmp1=AdtoInt(adctab[i],(int)ADoffset2);
//存储到本来的空间里
adctab[i]=(uint16)tmp1;
//判断过零点
if((i>0) && ( *((int*)(adctab+i))<0) && (*((int*)(adctab+i-1))>=0))
{
if(X==-1)
{
n=(int)i;
lst=(int)i;
X=0;
}
else
{
if((i-lst)>120)
{
X++;
lst=i;
}
}
if(X==4)
{
m=(int)i;
}
}
//取绝对值
if(tmp1<0)
{
tmp1=0-tmp1;
}
//累加
if(X>=0 && X<4)
{
sum+=(float)tmp1;
}
//取最大值
if(tmp1>max)
{
max=tmp1;
}
sum1+=(float)tmp1;
}
osal_int_enable(INTS_ALL);
// 最大值假如小于 0x2000的5%则有或许杂波搅扰比较大,真实的过零点难找,而又由于只要5%,所以累加后求平均值对最终的核算成果影响很小
if(max<410)
{
return (sum1/800);
}
else
{
return (sum/(m-n));
}
};
//将无符号整数转化为int 大于0x1fff的为负数 偏移量要从float转成int
int AdtoInt(volatile uint16 adctmp,int offset)
{
int tmp1;
adctmp=(adctmp<<8)|(adctmp>>8);
adctmp>>=2;
if(adctmp>8191)
{
tmp1=(int)adctmp-0x4000-offset;
}
else
{
tmp1=(int)adctmp-offset;
}
return tmp1;
}
五、至此我运用cc2430AD转化的心得现已讲完了,期望对我们的开发作业有点协助。