你好!
我在用28335做AD转换时,当AD口输入0V时,AdcRegs.ADCRESULT的值>>4位后为0。当AD口输入3V时,AdcRegs.ADCRESULT的值>>4位后为3800。当AD口输入3.2V时,AdcRegs.ADCRESULT的值>>4位后为4095。我看资料上都写输入3V时就到4095,请教是什么原因?基准电压用REF3020为2.048V,AdcRegs.ADCREFSEL.all = 0x4000。我以前用2808没发现这个问题!
谢谢!
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
你好!
我在用28335做AD转换时,当AD口输入0V时,AdcRegs.ADCRESULT的值>>4位后为0。当AD口输入3V时,AdcRegs.ADCRESULT的值>>4位后为3800。当AD口输入3.2V时,AdcRegs.ADCRESULT的值>>4位后为4095。我看资料上都写输入3V时就到4095,请教是什么原因?基准电压用REF3020为2.048V,AdcRegs.ADCREFSEL.all = 0x4000。我以前用2808没发现这个问题!
谢谢!
你量一下ADCLO引脚是电压是多少呢?这个测量请用以下两种方法,同时确保量测时转换值确实有偏移:
1. 以芯片地为基准,分别测试你的实际信号对地的电压,以及ADCLO对地的电压;
2. 正端接实际信号,负端接ADCLO,看看电压差是多少?
有没有参考datasheet中Figure 4-10. ADC Pin Connections With External Reference对相应的引脚进行对比确定是否符合要求,特别是ADCRESEXT,ADCREFP和ADCREFM这几个。
另外,有没检查一下ADCOFFTRIM寄存器的值是多少?
当输入电压达到3.2V时,寄存器的值才到4095。万用表和示波器是绝对没问题的,测量精度很高的,示波器5万多刚买来。
补充下:ADCREFIN引脚接外部基准电压2.048V (选用REF3020芯片),AdcRegs.ADCREFSEL.all = 0x4000;
那么如果施加电压是1.5V呢?1V或2V呢,误差又有多大?
如果将输入电压从0开始,以每0.73mV(1LSB)增加,ADC结果寄存器的变化状况如何?
你好,测量43脚(接模拟地)与40脚(测试AD口)电压与 寄存器AdcRegs.ADCRESULT8>>4值对比如下:
电压 AdcRegs.ADCRESULT8>>4
0.05V 65
0.1V 129
0.2V 256
0.3V 383
0.4V 512
0.5V 640
0.6V 768
0.7V 895
0.8V 1025
0.9V 1150
1.0V 1275
1.1V 1400
1.2V 1530
1.3V 1660
1.4V 1780
1.5V 1913
1.6V 2040
1.7V 2160
1.8V 2295
1.9V 2420
2.0V 2540
2.1V 2668
2.2V 2803
2.3V 2925
2.4V 3053
2.5V 3181
2.6V 3300
2.7V 3430
2.8V 3555
2.9V 3692
3.0V 3820
3.1V 3940
3.2V 4072
3.22V 4095
你可能需要量得小一点,特别关注从0开始,每增加1LSB时(对应0.7mV)对应的ADC结果寄存器。
另外,这是在单片芯片上出现的,还是几颗都这样?有没有试试有例程看结果如何?
我分析了一下你的数据(见附表),可以看到其实是线性度有偏移,参考ADC手册提到的对gain进行线性补偿应该就准确了,但初始值偏那么大有点说不通。
那很可能还是硬件上的问题,建议重新量测一下ADC参考以及供电电源。
例程可以在下面下载,不过建议还是下载controlsuite,里面包含了所有C2000的资料:
你好:
我从TI网站下载了例程adc_seqmode_test,运行后发现AD转换正常。
例程AdcRegs.ADCREFSEL.all用的是默认值,读出为1DA4。我把AdcRegs.ADCREFSEL.all设成0x0000,AD转换的值马上发生误差。由此我把使用外部2.048参考电压的AdcRegs.ADCREFSEL.all=0x5DA4,这样用外部2.048V做参考电压,AD转换值就正常了。请问AdcRegs.ADCREFSEL.all这个寄存器第15和14位是参考电压选择位,其他的位代表什么意思?文档里我找不到说明。谢谢!另外以前用2808时AdcRegs.ADCREFSEL.all=0x4000,AD一直正常
寄存器定义里提到如下说明,代表的意思应该就是内部校准相关的。
如果你写入0x5DA4可以的话,那就这样处理吧,或者你可以试试AdcRegs.ADCREFSEL.bit.REF_SEL = 1;看看。后者可行的话建议使用后者。
These bits are reserved for reference calibration data loaded from the Boot ROM. All writes to the ADCREFSEL register should leave the contents of this bit field as is after population by the Boot ROM.
你好 请问你的ad精度达到千分之一是怎么弄出来的
加了低通滤波吗? 我这飘得狠 用的内部参考
难道是参考源的问题吗? 等候解答啊
楼上可否把你初始化AD的函数赛出来,我也想采用28335的AD外部基准,设置了AdcRegs.ADCREFSEL.bit.REF_SEL=1,还是不对
extern void DSP28x_usDelay(Uint32 Count);
AdcRegs.ADCTRL3.all = 0x00c0; // Power up bandgap/reference/ADC circuits
DELAY_US(ADC_usDELAY); // Delay before converting ADC channels
AdcRegs.ADCTRL3.bit.ADCPWDN = 0x1;
DELAY_US(ADC_20usDELAY);
EALLOW;
#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
EDIS;
// *IMPORTANT*
// The ADC_cal function, which copies the ADC calibration values from TI reserved
// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
// Boot ROM. If the boot ROM code is bypassed during the debug process, the
// following function MUST be called for the ADC to function according
// to specification. The clocks to the ADC MUST be enabled before calling this
// function.
// See the device data manual and/or the ADC Reference
// Manual for more information.
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; //使能ADC外设内部高速时钟(HSPCLK)
ADC_cal();
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0;
EDIS;
PieVectTable.SEQ1INT = &adc_isr;
EDIS;
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
IER |= M_INT1;
AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x1;
//ADCTRL2 Inition
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
AdcRegs.ADCTRL2.bit.SOC_SEQ1 =1;
//ADCTRL1 Inition
AdcRegs.ADCTRL1.bit.ACQ_PS =0x01 ;
AdcRegs.ADCTRL1.bit.CPS = 1;
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;
AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
AdcRegs.ADCREFSEL.bit.REF_SEL = 0;
AdcRegs.ADCOFFTRIM.bit.OFFSET_TRIM = 0;
// Configure ADC
AdcRegs.ADCMAXCONV.all = 0x000f; // Setup 16 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4;
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5;
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6;
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7;
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x8;
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x9;
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xa;
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0xb;
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xc;
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xd;
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xe;
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0xf;
// Assumes ePWM1 clock is already enabled in InitSysCtrl();
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm1Regs.ETSEL.bit.SOCASEL = 2; // Select SOC from from period
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm1Regs.ETPS.bit.SOCACNT = 1;
// EPwm1Regs.ETFLG.bit.SOCA = 1;
// EPwm1Regs.ETCLR.bit.SOCA = 1;
// EPwm1Regs.ETFRC.bit.SOCA = 1;
// EPwm1Regs.CMPA.half.CMPA = 0x0080; // Set compare A value
EPwm1Regs.TBPRD = 0x271; // Set period for ePWM1
EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start
EPwm1Regs.TBCTL.bit.CLKDIV = 0; //default clk=1
// EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;
// EPwm1Regs.CMPCTL.bit.LOADAMODE= 0;
// EPwm1Regs.CMPCTL.bit.SHDWAMODE= 1;