初始化程序
#if (CPU_FRQ_150MHZ) // Default – 150 MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
#endif
#if (CPU_FRQ_100MHZ)
#define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz
#endif
void Init_ADC(void)
{
uint16_t tmp = 0;
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;
AdcRegs.ADCTRL3.all = 0x00E0; // Power up bandgap/reference/ADC circuits
tmp = 5000;
while(tmp–); // 等待ADC稳定
//以下开始设置ADC的控制寄存器、转换通道选择寄存器等
AdcRegs.ADCST.all = 0x30; //首先清除中断标志位
AdcRegs.ADCOFFTRIM.all = 0;
AdcRegs.ADCTRL3.all = 0x0E2;
//bit7~6:ADCBGRFDN[1:0]:adc 缝隙上电,3上电
//bit5:ADCPWDN:adc 模块上电,set1 上电
//bit1~4:ADCCLKPS=1
// bit0:SMODE_SEL =0 :set 0 顺序采样; set1 :同步采样
// 0 = [ADCCLK = HSPCLK/(CPS+1)], 1 = [ADCCLK = HSPCLK/2*(1)(CPS+1)]; HSPCLK 默认情况下 = CPUSYSCLK/2;
//ADC module clock = HSPCLK/2*ADC_CKPS = 25.0MHz/(1*2) = 12.5MHz
//设置为顺序采样模式 0 = 连续采样方式 1 = 并发采样方式
AdcRegs.ADCTRL1.all = 0x0F50;
/*bit13~12:SUSMOD=0;
bit11~8:ACQ_PS =F :16 ADC clocks;
bit7: CPS =0时钟预分频1
bit6: CONT_RUN=1;//设置为启停模式 0 = 启停模式,1 = 连续转换模式
bit5:SEQ_OVRD = 0
bit4:SEQ_CASC =1//级联模式 0 = 双序列发生器方式, 1 = 级联模式
*/
//AdcRegs.ADCTRL1.bit.CONT_RUN = 1;
AdcRegs.ADCTRL2.all = 0x0000;
AdcRegs.ADCMAXCONV.all = 0x0F; //最大转换16通道
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; // ADCINA0 & ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1; // ADCINA1 & ADCINB1
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2; // ADCINA2 & ADCINB2
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 3; // ADCINA3 & ADCINB3
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 4; // ADCINA4 & ADCINB4
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 5; // ADCINA5 & ADCINB5
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 6; // ADCINA6 & ADCINB6
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 7; // ADCINA7 & ADCINB7
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 8; // ADCINA8 & ADCINB8
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 9; // ADCINA9 & ADCINB9
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 10; // ADCINA10 & ADCINB10
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 11; // ADCINA11 & ADCINB11
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 12; // ADCINA12 & ADCINB12
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 13; // ADCINA13 & ADCINB13
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 14; // ADCINA14 & ADCINB14
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 15; // ADCINA15 & ADCINB15
}
系统时钟用的是150M
读取结果的函数
void Test_Ai_Handle(Ubyte *paramData)
{
uint16_t i = 0;
uint16_t value[16];
uint16_t chan = 0;
float tmp = 0;
uint16_t delay_tmp = 0;
chan = paramData[0];
memset((void *)value, 0, sizeof(value));
/* handle */
for(i=0; i<10; i++)//3 change 10
{
/* start sw conversion */
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // sofware start ADC
/* wait conversion done */
delay_tmp = 1000;
while(delay_tmp–);
while(AdcRegs.ADCST.bit.INT_SEQ1 == 0);
/* value save */
value[0] += ((AdcRegs.ADCRESULT0) >> 4);
value[1] += ((AdcRegs.ADCRESULT1) >> 4);
value[2] += ((AdcRegs.ADCRESULT2) >> 4);
value[3] += ((AdcRegs.ADCRESULT3) >> 4);
value[4] += ((AdcRegs.ADCRESULT4) >> 4);
value[5] += ((AdcRegs.ADCRESULT5) >> 4);
value[6] += ((AdcRegs.ADCRESULT6) >> 4);
value[7] += ((AdcRegs.ADCRESULT7) >> 4);
value[8] += ((AdcRegs.ADCRESULT8) >> 4);
value[9] += ((AdcRegs.ADCRESULT9) >> 4);
value[10] += ((AdcRegs.ADCRESULT10) >> 4);
value[11] += ((AdcRegs.ADCRESULT11) >> 4);
value[12] += ((AdcRegs.ADCRESULT12) >> 4);
value[13] += ((AdcRegs.ADCRESULT13) >> 4);
value[14] += ((AdcRegs.ADCRESULT14) >> 4);
value[15] += ((AdcRegs.ADCRESULT15) >> 4);
}
tmp = (float)(value[chan-1]) / 10;
tmp = (3000 * tmp / 4095) ;
if(tmp >= 1499)
tmp += 1;
else;
paramData[3] = Type_Extrh_U8_Of_U16_TE(tmp);
paramData[4] = Type_Extrl_U8_Of_U16_TE(tmp);
}
把ADC模块的误差缩小到30MV 以内
Annie Liu:
为更加有效地解决您的问题,我们建议您将问题发布在E2E英文技术论坛上https://e2e.ti.com/support/microcontrollers/c2000/f/171,将由资深的工程师为您提供帮助。我们的E2E英文社区有TI专家进行回复,并得到全球各地工程师的支持,分享他们的知识和经验。
初始化程序
#if (CPU_FRQ_150MHZ) // Default – 150 MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
#endif
#if (CPU_FRQ_100MHZ)
#define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz
#endif
void Init_ADC(void)
{
uint16_t tmp = 0;
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;
AdcRegs.ADCTRL3.all = 0x00E0; // Power up bandgap/reference/ADC circuits
tmp = 5000;
while(tmp–); // 等待ADC稳定
//以下开始设置ADC的控制寄存器、转换通道选择寄存器等
AdcRegs.ADCST.all = 0x30; //首先清除中断标志位
AdcRegs.ADCOFFTRIM.all = 0;
AdcRegs.ADCTRL3.all = 0x0E2;
//bit7~6:ADCBGRFDN[1:0]:adc 缝隙上电,3上电
//bit5:ADCPWDN:adc 模块上电,set1 上电
//bit1~4:ADCCLKPS=1
// bit0:SMODE_SEL =0 :set 0 顺序采样; set1 :同步采样
// 0 = [ADCCLK = HSPCLK/(CPS+1)], 1 = [ADCCLK = HSPCLK/2*(1)(CPS+1)]; HSPCLK 默认情况下 = CPUSYSCLK/2;
//ADC module clock = HSPCLK/2*ADC_CKPS = 25.0MHz/(1*2) = 12.5MHz
//设置为顺序采样模式 0 = 连续采样方式 1 = 并发采样方式
AdcRegs.ADCTRL1.all = 0x0F50;
/*bit13~12:SUSMOD=0;
bit11~8:ACQ_PS =F :16 ADC clocks;
bit7: CPS =0时钟预分频1
bit6: CONT_RUN=1;//设置为启停模式 0 = 启停模式,1 = 连续转换模式
bit5:SEQ_OVRD = 0
bit4:SEQ_CASC =1//级联模式 0 = 双序列发生器方式, 1 = 级联模式
*/
//AdcRegs.ADCTRL1.bit.CONT_RUN = 1;
AdcRegs.ADCTRL2.all = 0x0000;
AdcRegs.ADCMAXCONV.all = 0x0F; //最大转换16通道
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; // ADCINA0 & ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1; // ADCINA1 & ADCINB1
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2; // ADCINA2 & ADCINB2
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 3; // ADCINA3 & ADCINB3
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 4; // ADCINA4 & ADCINB4
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 5; // ADCINA5 & ADCINB5
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 6; // ADCINA6 & ADCINB6
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 7; // ADCINA7 & ADCINB7
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 8; // ADCINA8 & ADCINB8
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 9; // ADCINA9 & ADCINB9
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 10; // ADCINA10 & ADCINB10
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 11; // ADCINA11 & ADCINB11
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 12; // ADCINA12 & ADCINB12
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 13; // ADCINA13 & ADCINB13
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 14; // ADCINA14 & ADCINB14
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 15; // ADCINA15 & ADCINB15
}
系统时钟用的是150M
读取结果的函数
void Test_Ai_Handle(Ubyte *paramData)
{
uint16_t i = 0;
uint16_t value[16];
uint16_t chan = 0;
float tmp = 0;
uint16_t delay_tmp = 0;
chan = paramData[0];
memset((void *)value, 0, sizeof(value));
/* handle */
for(i=0; i<10; i++)//3 change 10
{
/* start sw conversion */
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // sofware start ADC
/* wait conversion done */
delay_tmp = 1000;
while(delay_tmp–);
while(AdcRegs.ADCST.bit.INT_SEQ1 == 0);
/* value save */
value[0] += ((AdcRegs.ADCRESULT0) >> 4);
value[1] += ((AdcRegs.ADCRESULT1) >> 4);
value[2] += ((AdcRegs.ADCRESULT2) >> 4);
value[3] += ((AdcRegs.ADCRESULT3) >> 4);
value[4] += ((AdcRegs.ADCRESULT4) >> 4);
value[5] += ((AdcRegs.ADCRESULT5) >> 4);
value[6] += ((AdcRegs.ADCRESULT6) >> 4);
value[7] += ((AdcRegs.ADCRESULT7) >> 4);
value[8] += ((AdcRegs.ADCRESULT8) >> 4);
value[9] += ((AdcRegs.ADCRESULT9) >> 4);
value[10] += ((AdcRegs.ADCRESULT10) >> 4);
value[11] += ((AdcRegs.ADCRESULT11) >> 4);
value[12] += ((AdcRegs.ADCRESULT12) >> 4);
value[13] += ((AdcRegs.ADCRESULT13) >> 4);
value[14] += ((AdcRegs.ADCRESULT14) >> 4);
value[15] += ((AdcRegs.ADCRESULT15) >> 4);
}
tmp = (float)(value[chan-1]) / 10;
tmp = (3000 * tmp / 4095) ;
if(tmp >= 1499)
tmp += 1;
else;
paramData[3] = Type_Extrh_U8_Of_U16_TE(tmp);
paramData[4] = Type_Extrl_U8_Of_U16_TE(tmp);
}
把ADC模块的误差缩小到30MV 以内
mangui zhang:我觉得你将测试的结果对比一下如果固定偏差一个值就讲采集的值减去一个固定的值
这种做法工程中常用
初始化程序
#if (CPU_FRQ_150MHZ) // Default – 150 MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
#endif
#if (CPU_FRQ_100MHZ)
#define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz
#endif
void Init_ADC(void)
{
uint16_t tmp = 0;
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;
AdcRegs.ADCTRL3.all = 0x00E0; // Power up bandgap/reference/ADC circuits
tmp = 5000;
while(tmp–); // 等待ADC稳定
//以下开始设置ADC的控制寄存器、转换通道选择寄存器等
AdcRegs.ADCST.all = 0x30; //首先清除中断标志位
AdcRegs.ADCOFFTRIM.all = 0;
AdcRegs.ADCTRL3.all = 0x0E2;
//bit7~6:ADCBGRFDN[1:0]:adc 缝隙上电,3上电
//bit5:ADCPWDN:adc 模块上电,set1 上电
//bit1~4:ADCCLKPS=1
// bit0:SMODE_SEL =0 :set 0 顺序采样; set1 :同步采样
// 0 = [ADCCLK = HSPCLK/(CPS+1)], 1 = [ADCCLK = HSPCLK/2*(1)(CPS+1)]; HSPCLK 默认情况下 = CPUSYSCLK/2;
//ADC module clock = HSPCLK/2*ADC_CKPS = 25.0MHz/(1*2) = 12.5MHz
//设置为顺序采样模式 0 = 连续采样方式 1 = 并发采样方式
AdcRegs.ADCTRL1.all = 0x0F50;
/*bit13~12:SUSMOD=0;
bit11~8:ACQ_PS =F :16 ADC clocks;
bit7: CPS =0时钟预分频1
bit6: CONT_RUN=1;//设置为启停模式 0 = 启停模式,1 = 连续转换模式
bit5:SEQ_OVRD = 0
bit4:SEQ_CASC =1//级联模式 0 = 双序列发生器方式, 1 = 级联模式
*/
//AdcRegs.ADCTRL1.bit.CONT_RUN = 1;
AdcRegs.ADCTRL2.all = 0x0000;
AdcRegs.ADCMAXCONV.all = 0x0F; //最大转换16通道
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; // ADCINA0 & ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1; // ADCINA1 & ADCINB1
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2; // ADCINA2 & ADCINB2
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 3; // ADCINA3 & ADCINB3
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 4; // ADCINA4 & ADCINB4
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 5; // ADCINA5 & ADCINB5
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 6; // ADCINA6 & ADCINB6
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 7; // ADCINA7 & ADCINB7
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 8; // ADCINA8 & ADCINB8
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 9; // ADCINA9 & ADCINB9
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 10; // ADCINA10 & ADCINB10
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 11; // ADCINA11 & ADCINB11
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 12; // ADCINA12 & ADCINB12
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 13; // ADCINA13 & ADCINB13
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 14; // ADCINA14 & ADCINB14
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 15; // ADCINA15 & ADCINB15
}
系统时钟用的是150M
读取结果的函数
void Test_Ai_Handle(Ubyte *paramData)
{
uint16_t i = 0;
uint16_t value[16];
uint16_t chan = 0;
float tmp = 0;
uint16_t delay_tmp = 0;
chan = paramData[0];
memset((void *)value, 0, sizeof(value));
/* handle */
for(i=0; i<10; i++)//3 change 10
{
/* start sw conversion */
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // sofware start ADC
/* wait conversion done */
delay_tmp = 1000;
while(delay_tmp–);
while(AdcRegs.ADCST.bit.INT_SEQ1 == 0);
/* value save */
value[0] += ((AdcRegs.ADCRESULT0) >> 4);
value[1] += ((AdcRegs.ADCRESULT1) >> 4);
value[2] += ((AdcRegs.ADCRESULT2) >> 4);
value[3] += ((AdcRegs.ADCRESULT3) >> 4);
value[4] += ((AdcRegs.ADCRESULT4) >> 4);
value[5] += ((AdcRegs.ADCRESULT5) >> 4);
value[6] += ((AdcRegs.ADCRESULT6) >> 4);
value[7] += ((AdcRegs.ADCRESULT7) >> 4);
value[8] += ((AdcRegs.ADCRESULT8) >> 4);
value[9] += ((AdcRegs.ADCRESULT9) >> 4);
value[10] += ((AdcRegs.ADCRESULT10) >> 4);
value[11] += ((AdcRegs.ADCRESULT11) >> 4);
value[12] += ((AdcRegs.ADCRESULT12) >> 4);
value[13] += ((AdcRegs.ADCRESULT13) >> 4);
value[14] += ((AdcRegs.ADCRESULT14) >> 4);
value[15] += ((AdcRegs.ADCRESULT15) >> 4);
}
tmp = (float)(value[chan-1]) / 10;
tmp = (3000 * tmp / 4095) ;
if(tmp >= 1499)
tmp += 1;
else;
paramData[3] = Type_Extrh_U8_Of_U16_TE(tmp);
paramData[4] = Type_Extrl_U8_Of_U16_TE(tmp);
}
把ADC模块的误差缩小到30MV 以内
user4329368:
回复 mangui zhang:
但是有些AI通道会左右摆动。这个问题解决不了。ADC模块12bit的分辨率,误差不应该有这个大。