tu312 发表于 2010-10-25 10:59:15

xmega的ADC结果不太准确

大家好
我正在使用Xmega16D4。我已升级至4.18SP3和AVR tools chain 3.0,已可以成功编译。修改1300库的例程example_interrupt,adc.aps,加入了头文件缺少的PB口上的四路定义,测试了下ADC,发现结果不太准确。我现在PIN1是1.28V,其他PIN0和PIN2~11都是0V,使用SINGLEENDED和SIGNED,使用了CalibrationValues和offset,但结果除PIN0是正确外,其他都不正确,相差10%以上,请问这是什么原因,谢谢。



点击此处下载 ourdev_592615WW1NWA.rar(文件大小:88K) (原文件名:test adc.rar)
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_592616V0XM6Z.jpg
(原文件名:未命名-1.jpg)

xsh2005105326 发表于 2010-10-25 11:28:00

看不懂,ADC测的是什么?基准源是什么?电源纹波大不?我对xmage不了解

dxtc234 发表于 2010-10-25 13:56:52

降低采样速度试一下

tu312 发表于 2010-10-25 14:16:13

基准源是内部1.6V的        ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc),速率手册上写的可达200k,分频我已设了最大512了,ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV512_gc),速度现在32M/512=62.5k

windy__xp 发表于 2010-10-25 14:31:25

非常好奇,LZ的 Xmega16D4 哪里来的?没听过国内有推 Xmega16D4 啊,我接触的XMEGA最低版本是32A4。

windy__xp 发表于 2010-10-25 14:39:23

下面是我在32A4上的测试程序,ADC还是比较准的,使用内部 1.00V 参考源。Xmega 的一大改进之一,就是内部参考源终于有点像个参考源了。

;==========================================================================
; 函数名称:Sub_Read_Vcc_Vol
; 函数功能:读取电池电压
; 入口参数:无
; 出口参数:无
; 用寄存器: ……
; 程序版本:1.0
; 编写日期:2009-11-13
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
Sub_Read_Vcc_Vol:                           ;//
    NOP                                     ;//
            SET_PWADCS_OUTPUT_SLEW_EN       ;// 01. 开启 ADC 电压
            SET_POWER_ADC_ENABLE            ;//
    LDI   R16, 200                        ;// 02. 延迟2ms,等待ADC电压稳定
    CALL    Sub_System_Delay_Nms            ;//
    CLR   R31                           ;// 03. 读取校准字节,校准ADCA
    LDI   R30, 0x20                     ;//
    LDI   R20, 0x02                     ;//    0x02 为读取校准字命令
    CALL    Sub_Read_Signature_Rows         ;//    R0 为出口参数
    PUSH    R0                              ;//
    CLR   R31                           ;//    高字节读取
    LDI   R30, 0x21                     ;//
    LDI   R20, 0x02                     ;//    0x02 为读取校准字命令
    CALL    Sub_Read_Signature_Rows         ;//    R0 为出口参数
    POP   R1                              ;//
    STS   ADCA_CAL, R1                  ;//    校准字低字节
    STS   (ADCA_CAL+1), R0                ;//    校准字高字节
    LDI   R16, 0x10                     ;// 04. 设置ADC 为有符号模式,单次转换,结果右对齐12bit
    STS   ADCA_CTRLB, R16               ;//
    CLR   R16                           ;// 05. 基准源设置为内部 1.00V
    STS   ADCA_REFCTRL, R16               ;//
    LDI   R16, 0x02                     ;// 06. ADC时钟,系统时钟 16 分频
    STS   ADCA_PRESCALER, R16             ;//
    LDI   R16, 0x01                     ;// 07. 设置SDC输入模式,使用 CH0 单端输入
    STS   ADCA_CH0_CTRL, R16            ;//
    LDI   R16, 0x20                     ;// 08. ADC4 引脚输入
    STS   ADCA_CH0_MUXCTRL, R16         ;//
    CLR   R16                           ;// 09. 转换接触设置中断标志,禁止中断
    STS   ADCA_CH0_INTCTRL, R16         ;//
    LDI   R16, 0x01                     ;// 10. 清零中断标志
    STS   ADCA_CH0_INTFLAGS, R16          ;//
    LDI   R16, 0x05                     ;// 11. 开启ADC转换
    STS   ADCA_CTRLA, R16               ;//
Wait_ADC_End:                               ;// 12. 等待ADC转换完毕
    LDS   R16, ADCA_CH0_INTFLAGS          ;//
    TST   R16                           ;//
    BREQ    Wait_ADC_End                  ;//
    LDS   R16, ADCA_CH0_RES               ;// 13.读取转换结果
    LDS   R17, ADCA_TEMP                  ;//
    LDI   R18, 0x00                     ;// 14. 关闭ADC转换
    STS   ADCA_CTRLA, R18               ;//
            SET_POWER_ADC_DISABLE         ;// 15. 关闭ADC电压
    RET                                     ;//



;==========================================================================
; 函数名称:Sub_Read_Signature_Rows
; 函数功能:读取产品签名、用户签名信息
; 入口参数:Z(R31 R30):签名信息地址; R20:读取命令
; 出口参数:R0
; 用寄存器: ……
; 程序版本:1.0
; 编写日期:2009-11-14
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
Sub_Read_Signature_Rows:                  ;// 读取签名信息
    NOP                                     ;//
Wait_NVM_Operate_End:                     ;// 1. 等待 NVM 操作完毕
    LDS   R16, NVM_STATUS               ;//
    TST   R16                           ;//
    BRNE    Wait_NVM_Operate_End            ;//
    STS   NVM_CMD, R20                  ;// 2. 设置命令
    LPM                                     ;// 3. 读取,(Z)---> R0
    LDI   R16, 0x00                     ;//
    STS   NVM_CMD, R16                  ;// 4. 设置命令寄存器为空
    RET                                     ;//

tu312 发表于 2010-10-25 14:45:09

哪里来的是领导的问题,我是打工的,呵呵。
别提有多痛苦了。国内基本没资料,D4又是A的阉割版本,很多不一样,编译器也有问题,16D4又是D系列今年新推的,问题多多,我以前莫名其妙的问题都随着编译器和IDE的升级解决,头文件iox16d4.h自己改,加了头文件缺少的PB口上的四路定义

对了,楼上windy__xp 龙笑,请问有没有C语言的版本,汇编极差


谢谢windy__xp 龙笑,我再试试

windy__xp 发表于 2010-10-25 14:56:57

ADC 当时只用汇编做了个测试,没有实际应用,你参考一下流程和寄存器设置即可,另外你说的参考电压估计是 VCC/1.6 而不是 1.6V,看一下问题是不是出在这里。数据手册中说明如下:

http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_592663J4F7SR.JPG
(原文件名:xmega 参考源.JPG)


    一直还惦记着 Xmega,期待 128A1 能正常供货。

tu312 发表于 2010-10-25 15:11:26

谢谢windy__xp 龙笑,如果按照您的理解方式,PIN1倒是差不多1.28V,但2~11路还是不对啊,示波器测得是0的,但如测得图多的有500多,少的也有200多。
我是在中断中修改测第几路
ISR(ADCA_CH0_vect)
{

        /*Read samples and clear interrupt flags. */
        adcSamples = ADC_ResultCh_GetWord_Signed(&ADCA.CH0, offset);


interrupt_count++;
mux=s(interrupt_count%12);
ADC_Ch_InputMux_Config(&ADCA.CH0, mux, 0);

按我的理解,应该是不断的从0测到11循环

lisn3188 发表于 2010-10-25 23:02:33

粗看了一下楼主的程序发现:
1.ADC端口没有进行初始化
2.程序中interrupt_count 这个变量在使用过程中没有进行复位

tu312 发表于 2010-11-1 20:27:28

谢谢大家,感谢windy__xp 龙笑,感谢lisn3188 龙南。
已搞定,低级错误,管脚悬空和windy__xp 龙笑所说的参考电压估计是 VCC/1.6 而不是 1.6V
此外,我以前无法测试AD是由于编译器问题,写信问了atmel总部,升级至4.18SP3和AVR tools chain 3.0,编译就能正常运行
16D4头文件仍有错误,自己添加PB口定义
enum {
ADC_CH_MUXPOS_PIN8_gc = (0x08<<3),/* Input pin 8 */
ADC_CH_MUXPOS_PIN9_gc = (0x09<<3),/* Input pin 9 */
ADC_CH_MUXPOS_PIN10_gc = (0x0a<<3),/* Input pin 10 */
ADC_CH_MUXPOS_PIN11_gc = (0x0b<<3),/* Input pin 11 */
};
添加AD转换前端的放大为DIV2等等
右侧IO/VIEW没有内部温度传感器的选项等等~~

lsy5110 发表于 2011-3-1 22:34:35

mark

gerbins 发表于 2013-4-17 13:54:58

楼主我遇到和你一样的问题了 但是的引脚没有悬空输入电压为0.744V,参考电压1V,12位有符号单端转换模式,测得的值为1567还是比真实值1523大50左右.。。
页: [1]
查看完整版本: xmega的ADC结果不太准确