早上好、
在我目前正在开发的程序中、ADC10并不总是提供可靠的结果。 我正在尝试监控对硬件运行至关重要的五个模拟电压。 从 A0到 A4返回的值似乎是准确的、A2除外。 如果该通道的计数值始终在10到20个计数范围内、则该通道返回的值应约为350、具体取决于 A0和 A1的值。 这些值通常在650到800的范围内、A2的值应约为其他两个值的一半。 我已经验证了 A2引脚的模拟输入是正确的、因此我对这个结果感到困惑、尤其是因为我已经测试了10到12个具有相同结果的不同相同卡。 我在其他设计中使用了与以下附件类似的代码、结果很好、因此我不确定我的代码有什么问题。
此致、Harvey
初始化代码:
//================================================ 设置 ADC10 ================================================
//
//这些位从最高通道开始选择单次转换序列的通道。
//
//模数转换器(ADC)初始化。
ADC10CTL1 = 0;//关闭 ADC10
ADC10CTL0 = 0;
ADC10AE0 |= 0x1F;//通过 P2.0引脚将 P3.0和 P2.4设置为 ADC 的输入。
ADC10CTL1 = INCH_4 + ADC10DIV_7 + CONSEQ_1;//选择序列中的最大通道数(A5)
ADC10CTL0 = ADC10SHT_3 + ADC10ON;//选择 Vcc 作为正基准电压。
ADC10CTL0 |= ADC10IE;
ADC10CTL0 |=(ENC + ADC10SC);//启动 ADC 块转换状态机。
数据采集代码:
if (ADC_CC ==(ADC_CC & ADC_Flags)){ ADC_Flags &=~(ADC_CC);//清除转换完成标志
switch (ADC_DATA_STstate)//***** ADC 数据状态机开始*****
{
/*
案例 Acquite_A5://模拟输入 A5 -备用模拟、当前分配的数字输出 UCLK。
CH_A5[8]= Ch_A5[ADC_POINTER];//从所有样本之和减去最早的样本。
CH_A5[ADC_POINTER]= Analog _DATA;//保存最新样本。
CH_A5[8]+= Ch_A5[ADC_POINTER];//添加最新样本。
Analog5 = Ch_A5[8]>> 3;//备用输入 A5的平均值=总和/8。
ADC10CTL0 |= ADC10SC;//开始下一次转换。
ADC_DATA_STstate = Acquire _A4;
中断;
*
案例 Acquire _A4://模拟输入 A4 - VREF_2.5
CH_A4[8]= Ch_A4[ADC_POINTER];//从所有样本之和减去最早的样本。
CH_A4[ADC_POINTER]= Analog _DATA;//保存最新样本。
CH_A4[8]+= Ch_A4[ADC_POINTER];//添加最新样本。
VREF = Ch_A4[8]>> 3;//通道 A4 - 777、基准的平均电压。
ADC10CTL0 |= ADC10SC;//开始下一次转换。
ADC_DATA_STstate = Acquire _A3;
中断;
案例 Acquore_A3://模拟输入 A3 - I_Sns_Volt -流入或流出电池串的电流。
CH_A3[8]= Ch_A3[ADC_POINTER];//从所有样本之和减去最早的样本。
CH_A3[ADC_POINTER]= Analog _DATA - IMPw_Offset;//保存最新样本更少传感器偏移。
CH_A3[8]+= Ch_A3[ADC_POINTER];//添加最新样本。
if (((Ch_A3[ADC_Pointer]< I_maximum_Neg)||(Ch_A3[ADC_Pointer]> I_maximum_Pos)){
P1OUT &=~StR_en;//断开电池串。
LED_Reload = 50;
LED_Reload = 50;
OVER 电流计时器= 34;//在允许重新启动之前为电池提供冷却的机会。
I_Monitor_state = I_MON_Max;//已超出绝对最大值、请等待电流变为零。
}
I_SENSE = Ch_A3[8]>> 3;//通道 A3 -电池串输入或输出的平均电流。
ADC10CTL0 |= ADC10SC;//开始下一次转换。
ADC_DATA_STstate = Acquire _A2;
中断;
案例 Acquire _A2://模拟输入 A2 - MID_STRING*
CH_A2[8]= Ch_A2[ADC_POINTER];//从所有样本之和减去最早的样本。
CH_A2[ADC_POINTER]= Analog _DATA;//保存最新样本。
CH_A2[8]+= Ch_A2[ADC_POINTER];//添加最新样本。
MID_STRING = Ch_A2[8]>> 3;// Ch A2 -电芯串中心抽头的平均电压。
ADC10CTL0 |= ADC10SC;//开始下一次转换。
ADC_DATA_STstate = Acquire _A1;
中断;
案例 Acquire _A1://模拟输入 A1 - Cell_POS*
CH_A1[8]= Ch_A1[ADC_POINTER];//从所有样本之和减去最早的样本。
CH_A1[ADC_POINTER]= Analog _DATA;//保存最新样本。
CH_A1[8]+= Ch_A1[ADC_POINTER];//添加最新样本。
CELL_POS = Ch_A1[8]>> 3;// Ch A1 -顶部电池的平均电压。
ADC10CTL0 |= ADC10SC;//开始下一次转换。
ADC_DATA_STstate = Acquire _A0;
中断;
案例 Acquire _A0://模拟输入 A0 - BAT_BUS*
CH_A0[8]= Ch_A0[ADC_POINTER];//从所有样本之和减去最早的样本。
CH_A0[ADC_POINTER]= Analog _DATA;//保存最新样本。
CH_A0[8]+= Ch_A0[ADC_POINTER];//添加最新样本。
BATTERY_BUS = Ch_A0[8]>> 3;//通道 A0 -电池总线上的平均电压。
//内部管理
//
ADC10CTL0 &=~(ENC + ADC10SC);//禁用 ADC
if (+ADC_Pointer > 7){ ADC_Pointer = 0;}//指向数组中的下一个元素。
if (adc_Real!=(adc_Real 和 adc_Flags)){
if (to_ON_DELAY!=(to_ON_DELAY 和 System_Flags)){
if (REAL_Data_Count!= 0){REAL_Data_Count--;}
否则{ADC_Flags |= ADC_REAL;}//告知主循环数据现在是可靠的。
}
}
ADC_Flags |= ADC_BCC;//设置数据块完成标志。
ADC10CTL0 |=(ENC + ADC10SC);//开始新的块转换
if (WAIT_Timer >0){ WAIT_Timer--;}//如果尚未为0,则递减计时器。
ADC_DATA_STstate = Acquire _A4;// Go 获取下一个转换块
中断;
默认值:
Gen_Msg_FLAG1 |= Gen_Msg_0;
ADC_DATA_STstate = Acquire _A4;
中断;
}//结束开关***** ADC 数据状态机底部*****
}//如果 ADC_CC 和 PACKE_DEFAULT 则结束
中断服务例程:
/*----------------------------------
*名称:evadc_isr
*
*描述:
*对 ADC 进行了转换
*设置最多样化的进程标志
*
*
******************------------------------------------------------------- *
#pragma vector = ADC10_vector
_interrupt void evADC_ISR (void)
{
ANALOG_DATA = ADC10MEM;//将来自 ADC 的数据保存在临时缓冲区中
ADC10CTL0 &=~ADC10SC;//保持下一次转换。
// ADC10CTL0 &=~(ADC10IFG);//清除 ADC 转换完成中断标志
ADC_Flags |= ADC_CC;//设置转换完成标志
}