绿茶山人 发表于 2013-4-15 11:11:37

C8051F120 ADC使用心得,及ADC2多通道源码共享!

本帖最后由 绿茶山人 于 2013-4-15 11:37 编辑

最近在用C8051F120, 在ADC2上卡了几天,今天终于鼓捣成功了,完整源码在帖子最后附件中。

最开始的代码,烧入运行后发现当ADC所接模拟电压超过0.5V后,ADC2的转换结果就是255,在0~0.5V之间对应的ADC转换结果是0~255,检测半天也没看出代码问题,最后逛阿莫,看到有人出现了和我同样的结果,只是他用的F120的ADC0,这是该帖子的链接http://www.amobbs.com/forum.php?mod=viewthread&tid=5477075&pid=6600723&page=1&extra=page%3D1#pid6600723在17楼他反应电压超过0.5V转换结果就是最大值,他的代码我没看出问题。
电压超过0.5V后,ADC2的转换结果就是255,在ADC2_Init()中有问题,但是不知道这和结果有什么联系
void main(void)
{
       ............
        Timer3_Init();                  
        PORT_Init();                     
        OSCILLATOR_Init();               // Initialize oscillator
        ADC2_Init();                     // Init ADC2
        EA = 1;                           // Enable global interrupts
        ............

}

static void ADC2_Init(void)
{
        SFRPAGE = ADC2_PAGE;
        ADC2CN = 0x02;            
                                                                                          
        //这个地方有问题,应加上SFRPAGE = ADC2_PAGE;
        //但是没加这句程序可以运行,只是输入超过0.5V后结果一直是255, 不知道具体原因。
        REF0CN = 0x0A;                      // Enable on-chip AV+

        AMX2SL = 0x00;                      //从第0通道开始,一共8通道
        ADC2CF = (SYSCLK / SAR_CLK - 1) << 3;    // ADC conversion clock
        ADC2CF |= 0x01;                              // PGA gain = 1
        EIE2   |= 0x10;                     // enable ADC2 interrupts
        ADC2CN |= 0x80;                      // ADC2 enabled
}
现在对ADC2_Init();进行修改,其他代码不变,运行后发现ADC2根本不转换,趴窝了!还是没找到原因,这是现在的ADC2_Iint():static void ADC2_Init(void)
{
        SFRPAGE   = ADC0_PAGE;
        REF0CN = 0x0A;                      // Enable on-chip AV+
        SFRPAGE = ADC2_PAGE;
        AMX2SL = 0x0;                      //从第0通道开始,一共8通道
        ADC2CF = (SYSCLK / SAR_CLK - 1) << 3;    // ADC conversion clock
        ADC2CF |= 0x01;                              // PGA gain = 1
        ADC2CN = 0x82;                                                               
        EIE2   |= 0x10;                     // enable ADC2 interrupts
}
用Configuration Wizard重新生成代码后发现和以前的很多初始化函数和一些寄存器的调用前后顺序很多都变化了,现在ADC2能正常运行,在输入电压是AV+时转换结果才是255。第一次的结果不知道是什么原因,第二次和第三次的差别就是改变个别初始化函数和寄存器的顺序,第二次趴窝,第三次正常,真是神奇的一款单片机!下面是修改的代码:
static void Voltage_Reference_Init(void);

void main(void)
{
       ................
       //初始化顺序变了
        PORT_Init();                     // Initialize crossbar and GPIO
        Timer3_Init();                     // Initialize Timer2 to overflow at 1 mS
        ADC2_Init();                     // Init ADC
        Voltage_Reference_Init();                         //ADC2基准电压初始化
        OSCILLATOR_Init();               // Initialize oscillator
       
        EA = 1;                           // Enable global interrupts
        EIE2 |= 0x10;   //开ADC2中断
      ...............
}
static void ADC2_Init(void)
{
        SFRPAGE = ADC2_PAGE;       
        AMX2SL= 0x0;                      //从第0通道开始,一共8通道
        ADC2CF= (SYSCLK / SAR_CLK - 1) << 3;    // ADC conversion clock
        ADC2CF |= 0x01;                                          // PGA gain = 1       
        ADC2CN = 0x82;                                                                     
}
//=========================================================================================================
//新添加的ADC2基准电压初始化
//=========================================================================================================
static void Voltage_Reference_Init(void)
{
    SFRPAGE   = ADC0_PAGE;
    REF0CN = 0x0A;                      // Enable on-chip AV+
}

绿茶山人 发表于 2013-4-15 15:13:43

怎么没人回帖呢?!

techbaby 发表于 2013-4-15 15:19:55

C8051F120的ADC0,ADC2都用过,而且在一个项目中全部使用。
没发现LZ说描述的问题。

ADC使用关键是要配置好采样管脚(模拟输入),配置好ADC的采样时钟,采样选择管脚,增益等,基本没什么问题了。

话说我基本不用Configuration Wizard去生产程序,除了时钟和管脚的初始配置。

techbaby 发表于 2013-4-15 15:23:44




LZ可以参考一下。很久以前的程序。比较乱,不整理了。

绿茶山人 发表于 2013-4-15 15:47:12

techbaby 发表于 2013-4-15 15:19 static/image/common/back.gif
C8051F120的ADC0,ADC2都用过,而且在一个项目中全部使用。
没发现LZ说描述的问题。



我开始也没用Configuration Wizard生成代码,第三次的代码是用Configuration Wizard生成的,与第二次相比就是一些寄存器配置顺序和初始化函数调用顺序不同而已,第二次就不能工作,不会有这么严格的编码顺序要求吧?!ADC只是这个项目中的一部分,现在只是单独把ADC拿出来分析了,可能第二次ADC源码本身是好用的,只是其他地方影响了它,按照Configuration Wizard生成代码的顺序配置初始化应该会好一些。

techbaby 发表于 2013-4-15 15:59:05

Configuration Wizard生成代码的调用顺序是有要求的。
比如你使用外部晶振,但把晶振初始化的函数放在了GPIO初始化之前,那你的晶振就起振不了,程序就僵死在了晶振初始化函数中。这个我以前遇到过。

建议只在系统初始化时初始GPIO管脚,时钟晶振,内部电压及ADC参考电压即可。其他外设的使用在用到此种外设时再初始化。

有些相关联外设初始化时也要注意调用顺序,比如timer0和timer1就有相关联的设置寄存器。所以使用时要特别注意!

绿茶山人 发表于 2013-4-15 16:04:02

techbaby 发表于 2013-4-15 15:59 static/image/common/back.gif
Configuration Wizard生成代码的调用顺序是有要求的。
比如你使用外部晶振,但把晶振初始化的函数放在了GPI ...

学习了!谢谢指点!
页: [1]
查看完整版本: C8051F120 ADC使用心得,及ADC2多通道源码共享!