📄 adc12.c
字号:
#include <msp430x14x.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "ADC12.H"
#include "TimerA.H"
#include "Globe.H"
#include "FlashMemOP.H"
#include "TimerB.H"
#include "includes.h"
#include "GaoJin.h"
//unsigned int Factor[ADINPUTNUM]; //AD转换得到的数值和实际电压电流值之间的比例因子,这个比例因子需要校准
Buff adBuff;
value val[ADINPUTNUM]; //最终的计算结果
//初始化MyAdcFlag
void InitMyAdcFlag(void)
{
MyAdcFlag.SampCounter = 0; //初始时置已经采样的点数为零
MyAdcFlag.Channel = 0; //初始采样通道设为电压通道
MyAdcFlag.SampleOK =false;
MyAdcFlag.adMoniCount=0; //在AD中断里面计数
}
//初始化AD转换模块
//每周波采集128个点的数据,实际上采集
//使用内部2.5V参考
void InitADC12(void)
{
int i;
P6DIR &=~0xff;
P6SEL |=0xff;
STOP_ADC(); //Set ENC=0;
//ADC12CTL0 |= SHT0_12; //采样时间定为1024个ADC12CLK,125ns×512=128us+13个转换周期13*0.125=1.625us 共129.625us
ADC12CTL0 |= SHT0_11; //所以AD输入端的RC电路的时间常数不能大于128us,现在的r=100K C=0.001uf
//时间常数为100us
//每周波等间隔采集128个点,一个点的采样加转换时间最多不能超过20ms/128=0.15625ms
ADC12CTL0 |= SHT1_10;
//ADC12CTL0 |= MSC; //Multiple Sample
ADC12CTL0 |= REF2_5V; //Internal Reference 2.5V
ADC12CTL0 |= REFON; //Internal Reference on
ADC12CTL0 |= ADC12ON; //turn on ADC12
ADC12CTL1 |= CSTARTADD_0; //Conversion start at mem0
ADC12CTL1 |= SHS_3; //Sample and hold source is TB OUT1
ADC12CTL1 |= SHP; //Pulse-mode SAMPCON signal is sourced from the Sampling Timer
ADC12CTL1 &= ~ISSH; //The sample-input signal is not inverted
ADC12CTL1 |= ADC12SSEL_2; //select MClk for ADC12 clock source 8M
ADC12CTL1 |= ADC12DIV_0; //ADC12CLK's divider=1 8M
//ADC12CTL1 |= CONSEQ_1; //Sequence-of-channels,一次一序列通道采样.
ADC12CTL1 |= CONSEQ_0; //Single conversion,单通道单次采样
i=ADC12MEM0; //清除中断标志ADCIFG.0
i=ADC12MEM1;
i=ADC12MEM2;
i=ADC12MEM3;
i=ADC12MEM4;
i=ADC12MEM5;
i=ADC12MEM6;
i=ADC12MEM7;
i=ADC12MEM8;
i=ADC12MEM9;
i=ADC12MEM1 ;
i=ADC12MEM11;
i=ADC12MEM12;
i=ADC12MEM13;
i=ADC12MEM14;
i=ADC12MEM15;
i=i;
//所有通道的参考都是内部参考2.5V和AGND
ADC12MCTL0 = INCH_0+REF_VREF_AVSS; //UA
ADC12MCTL1 = INCH_1+REF_VREF_AVSS; //UB
ADC12MCTL2 = INCH_3+REF_VREF_AVSS; //IA
ADC12MCTL3 = INCH_4+REF_VREF_AVSS; //IB
ADC12MCTL4 = INCH_2+REF_VREF_AVSS; //UC
ADC12MCTL5 = INCH_5+REF_VREF_AVSS; //IC
ADC12MCTL6 = INCH_6+REF_VREF_AVSS; //电源
// ADC12MCTL7 = INCH_7+REF_VREF_AVSS; //备用通道
ADC12MCTL7 = INCH_10+REF_VREF_AVSS; //备用通道,
ADC12MCTL8 = INCH_10+REF_VREF_AVSS+EOS; //内部温度传感器
//ADC12MCTL9 = INCH_9+REF_VREF_AVSS;
//ADC12MCTL10 = INCH_10+REF_VREF_AVSS+EOS;
//ADC12MCTL11 = INCH_11+REF_VREF_AVSS+EOS;
ADC12IE = 0xff; //允许中断
START_ADC();
}
#define CHANNELNUM 8
char adSamecount=0;
#pragma vector=ADC_VECTOR
__interrupt void isrADC12(void)
{
unsigned int i;
//i=ADC12MEM8;
//ADC12IFG=0; //清除中断标志
switch(MyAdcFlag.Channel) //根据当前采样通道号读取相应的采样值
{
case UA:
adBuff.buff[MyAdcFlag.SampCounter]=ADC12MEM0;
break;
case UB:
adBuff.buff[MyAdcFlag.SampCounter]=ADC12MEM1;
break;
case IA:
adBuff.buff[MyAdcFlag.SampCounter]=ADC12MEM2;
break;
case IB:
adBuff.buff[MyAdcFlag.SampCounter]=ADC12MEM3;
break;
case UC:
adBuff.buff[MyAdcFlag.SampCounter]=ADC12MEM4;
break;
case IC:
adBuff.buff[MyAdcFlag.SampCounter]=ADC12MEM5;
break;
case PWR:
adBuff.buff[MyAdcFlag.SampCounter]=ADC12MEM6;
break;
case TMP:
adBuff.buff[MyAdcFlag.SampCounter]=ADC12MEM7;
break;
}
i=ADC12MEM0; //清除中断标志ADCIFG.0
i=ADC12MEM1;
i=ADC12MEM2;
i=ADC12MEM3;
i=ADC12MEM4;
i=ADC12MEM5;
i=ADC12MEM6;
i=ADC12MEM7;
i=ADC12MEM8;
i=ADC12MEM9;
i=ADC12MEM1 ;
i=ADC12MEM11;
i=ADC12MEM12;
i=ADC12MEM13;
i=ADC12MEM14;
i=ADC12MEM15;
i=i;
AGAIN_ADC();
if(MyAdcFlag.Channel<6)
{
if(adBuff.buff[MyAdcFlag.SampCounter]>2300 ||adBuff.buff[MyAdcFlag.SampCounter]<800)
{
if(abs(adBuff.buff[MyAdcFlag.SampCounter-1]-adBuff.buff[MyAdcFlag.SampCounter])<3)
{
if(adSamecount++>20) //严重削顶了
{
GJSta.urgency=1;
}
}
}
}
MyAdcFlag.SampCounter++; //增加一个转换点记录
MyAdcFlag.adMoniCount=0; //
if(MyAdcFlag.SampCounter>=SAMPLENUM) //如果已经完成SAMPLENUM个采样点的采样
{ //则转换采样通道
StopTimerB(); //停止TB
MyAdcFlag.SampleOK=true; //置通道采样完成标志
MyAdcFlag.SampCounter = 0; //计数值清零
adSamecount=0;
}
}
void AdcTask(void *pdata)
{
double result;
pdata=pdata;
InitFreqTrack();
InitTimerA();
InitMyAdcFlag();
InitADC12();
OSTimeDly(50);//等待频率跟踪完成
while(1)
{
ModifySampTime(); //根据频率跟踪的结果修正采样时间
for(MyAdcFlag.Channel =0;MyAdcFlag.Channel <CHANNELNUM;MyAdcFlag.Channel++)
{
STOP_ADC();
ADC12CTL1 &=0xfff;
ADC12CTL1 |=(MyAdcFlag.Channel*0x1000); //更改采样通道
START_ADC();
AGAIN_ADC();
OSTimeDly(6);
if(MyAdcFlag.Channel<4)
{
StartTimerB(MyAdcFlag.Ch1TBCCR1); //启动TimerB,timerB启动后将触发AD进行采样,直到SAMPLENUM个采样点完成后停止TB
}
else
{
StartTimerB(MyAdcFlag.Ch2TBCCR1); //启动TimerB,timerB启动后将触发AD进行采样,直到SAMPLENUM个采样点完成后停止TB
}
while(!MyAdcFlag.SampleOK)
OSTimeDly(1); //等待采样完成
STOP_ADC();
MyAdcFlag.SampleOK=false;
//采样完成,以下进行处理
result=CalcuValue(MyAdcFlag.Channel); //计算有效值
val[MyAdcFlag.Channel].Value=(unsigned int)(result*1000);
GJCheckExtra(MyAdcFlag.Channel);
}
OSTimeDly(1);
}
}
#define ADJFACTOR (100.0/4.3) //放大100倍
#define REFVOLT (2.5) //放大10倍
double CalcuValue(char channel) //计算有效值
{
unsigned long adAverage;//用于计算ad采样的平均值
int i,temp;
double aa;
union
{ //这个因子存储在Flash中,每个通道的因子都需要在出厂前校准
unsigned long value; //计算后的结果,存放电流或电压值
unsigned int ValueInt[2];
}tempValue;
if(channel<6)
{
adAverage=0;
for(i=0;i<SAMPLENUM;i++)
{
adAverage+= (adBuff.buff[i]);
}
i=0;
temp=SAMPLENUM;
do
{
temp/=2;
i++;
}
while(temp);
adAverage=adAverage>>(i-1); //求得平均值
//adAverage=
for(i=0;i<SAMPLENUM;i++)
{
temp=adBuff.buff[i]-adAverage;
MAC=abs(temp);
OP2 =abs(temp);
}
tempValue.ValueInt[1]=RESHI;
tempValue.ValueInt[0]=RESLO; //得到乘积累加和
aa=(double)(tempValue.value/SAMPLENUM);
aa=sqrt(aa); //求均方根
aa*=REFVOLT;
aa/=4095.0;
aa*=ADJFACTOR;
}
else if(channel==6) //电源通道
{
adAverage=0;
for(i=0;i<SAMPLENUM;i++)
{
adAverage+= (adBuff.buff[i]);
}
i=0;
temp=SAMPLENUM;
do
{
temp/=2;
i++;
}
while(temp);
aa=adAverage>>(i-1); //求得平均值
aa*=REFVOLT;
aa/=4095.0;
aa*=ADJFACTOR;
}
else //温度传感器通道
{
adAverage=0;
for(i=0;i<SAMPLENUM;i++)
{
adAverage+= (adBuff.buff[i]);
}
i=0;
temp=SAMPLENUM;
do
{
temp/=2;
i++;
}
while(temp);
aa=adAverage>>(i-1); //求得平均值
aa*=REFVOLT;
aa/=4095.0; //得到温度传感器输出的电压值
aa-=0.986;
aa=aa*20000/71;//得到温度值
//aa-=11;
}
return aa;
}
unsigned long sqrt32(unsigned long x)
{
unsigned long small, big, mid, t;
small = 0;
big = 0xffff; //?a·??á1?2?3?1y65535
mid = (small + big) >>1; //?t·?
while (small < (big-1)) //?±μ??t??2??μ?a1
{
t = mid * mid;
if (t == x)
break;
if ( t > x)
{
big = mid;
}
else
{
small = mid;
}
mid = (small + big) >>1;
}
return mid;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -