新闻  |   论坛  |   博客  |   在线研讨会
ColdFire 32位微控制器学习系列四--ADC模数转换模块
moran | 2008-08-01 17:33:34    阅读:1474   发布文章

1、MCF52235 ADC模块的主要特性:
·12位的精度
·频率最高为5MHz
·采样率高达1.66MPS
·单通道采样转换时间1.7微秒
·额外转换时间1.2微秒
·可以队列转换
·可以工作在低功耗模式
·采样中断功能
·结果有符号或者无符号
·差分功能

2、主要寄存器
 控制寄存器1:CTRL1为16位寄存器,主要位STOP0可以设置是否停止,START0(重要位)使模块开始工作,SYNC0定义如何开始工作,EOSIE0、ZCIE、LLMTIE、HLMTIE定义各种中断使能,CHNCFG定义是否使用差分,SMODE转换模式。
 控制寄存器2:CTRL2为16位寄存器,DIV设置时钟的分频。若工作在并行转换模式,则CTRL2和CTRL1含义基本相同,但是控制的是ADC B模块。
 ADZCC寄存器:和ADOFSn配合使用,过零标志,其实就是和一个偏移量比较而已,然后返回不同的结果。
 ADLST1和ADLST2:可以设置队列转换的先后顺序,我的程序中按默认值。
 采样禁止寄存器ADSDIS:对应位为1允许采样。
 状态寄存器ADSTAT:CIP0和CIP1指A和B模块是正在转换还是处于空闲,EOSI1和EOSI0表示转换完成中断来临,ZCI过零中断,LLMTI最低限制中断,HLMTI最高限制中断,RDYn指示采样是否就绪。
 限制状态寄存器ADLSTAT:指示是否超越高低限制。
 过零状态寄存器ADZCSTAT:过零状态。
 结果寄存器ADRSLTn:16位寄存器RSLT存放12位结果,还提供一个SEXT符号位。低三位未用。
 高低限制寄存器ADHLMTn和ADLLMTn:设置高低限制,离开这个限制将产生中断(如果允许)。
 偏移量寄存器ADOFSn:当然是跟过零状态有关的值。
 参考电压寄存器CAL:选择参考电压源。

3、AD模块的功能描述倒没有很新鲜的东西,这里就不多讲了,有兴趣的可以去参考英文文档。
4、最重要的举例,让你少走弯路:
###初始化###
void ADInit()
{
 //enable GPIO A/D function
    MCF_GPIO_PANPAR = MCF_GPIO_PANPAR_PANPAR0
       | MCF_GPIO_PANPAR_PANPAR1
       | MCF_GPIO_PANPAR_PANPAR2
        | MCF_GPIO_PANPAR_PANPAR3
       | MCF_GPIO_PANPAR_PANPAR4
        | MCF_GPIO_PANPAR_PANPAR5
        | MCF_GPIO_PANPAR_PANPAR6
        | MCF_GPIO_PANPAR_PANPAR7;
    //Setup the low , high limit and offset
    MCF_ADC_ADLLMT0 = 0;
    MCF_ADC_ADHLMT0 = MCF_ADC_ADHLMT_HLMT(0xffff);
    MCF_ADC_ADOFS0 = 0;
    MCF_ADC_ADLLMT1 = 0;
    MCF_ADC_ADHLMT1 = MCF_ADC_ADHLMT_HLMT(0xffff);
    MCF_ADC_ADOFS1 = 0;
    MCF_ADC_ADLLMT2 = 0;
    MCF_ADC_ADHLMT2 = MCF_ADC_ADHLMT_HLMT(0xffff);
    MCF_ADC_ADOFS2 = 0;
    MCF_ADC_ADLLMT3 = 0;
    MCF_ADC_ADHLMT3 = MCF_ADC_ADHLMT_HLMT(0xffff);
    MCF_ADC_ADOFS3 = 0;
    MCF_ADC_ADLLMT4 = 0;
    MCF_ADC_ADHLMT4 = MCF_ADC_ADHLMT_HLMT(0xffff);
    MCF_ADC_ADOFS4 = 0;
 // Disables zero crossing flag
    MCF_ADC_ADZCC = 0x0000;
    // Set all samples to be taken from AN0
 MCF_ADC_ADLST1 = 0x3210;
 MCF_ADC_ADLST2 = 0x7654;
 //Enable all samples
 MCF_ADC_ADSDIS=0;
    MCF_ADC_CTRL1 = MCF_ADC_CTRL1_STOP0
        |MCF_ADC_CTRL1_SYNC0
                //|MCF_ADC_CTRL1_EOSIE0
                    |MCF_ADC_CTRL1_SMODE(0x0);
                   
 MCF_ADC_CTRL2 = MCF_ADC_CTRL2_DIV(0xa);
    // Setting Power Register appropriately
    /////MCF_ADC_POWER |= MCF_ADC_POWER_PUDELAY(0xd);
    //////MCF_ADC_POWER &= ~(MCF_ADC_POWER_PD2|MCF_ADC_POWER_PD1|MCF_ADC_POWER_PD0);
    MCF_ADC_POWER = MCF_ADC_POWER_PUDELAY(0xd) |
                    MCF_ADC_POWER_PD2;
    //ADC_CTRL1 = (ALL_SINGLE_ENDED | MCF_ADC_CTRL1_SMODE(0) | MCF_ADC_CTRL1_START0);
    while (MCF_ADC_POWER & MCF_ADC_POWER_PSTS0)
    {}
    while (MCF_ADC_POWER & MCF_ADC_POWER_PSTS1)
    {}
    //MCF_ADC_CTRL1 |= MCF_ADC_CTRL1_SYNC0;
    MCF_ADC_CTRL1 = 0x3000;//MCF_ADC_CTRL1_START0;
    //printf("MCF_ADC_CTRL1 = %04x \n",MCF_ADC_CTRL1);
    //while(MCF_ADC_ADSTAT && MCF_ADC_ADSTAT_CIP);
    printf("A/D init complete.\n");
    //printf("MCF_ADC_ADSTAT = %04x \n",MCF_ADC_ADSTAT);
}

###AD工作函数###
void ADStartToWork(int mode)
{
 int dummy;
 while (MCF_ADC_POWER & MCF_ADC_POWER_PSTS0)
 ;
 while (MCF_ADC_POWER & MCF_ADC_POWER_PSTS1)
 ;
 MCF_ADC_CTRL1=mode;
 //while(MCF_ADC_ADSTAT && MCF_ADC_ADSTAT_CIP);
 if(PRINT_AD_TO_COMPUTER)
 {
  dummy=MCF_ADC_ADRSLT0>>3;
  printf("MCF_ADC_ADRSLT0 = %04d\n\r",(dummy));
  dummy=MCF_ADC_ADRSLT1>>3;
  printf("MCF_ADC_ADRSLT1 = %04d\n\r",(dummy));
  dummy=MCF_ADC_ADRSLT2>>3;
  printf("MCF_ADC_ADRSLT2 = %04d\n\r",(dummy));
  dummy=MCF_ADC_ADRSLT3>>3;
  printf("MCF_ADC_ADRSLT3 = %04d\n\r",(dummy));
  dummy=MCF_ADC_ADRSLT4>>3;
  printf("MCF_ADC_ADRSLT4 = %04d\n\r",(dummy));
  dummy=MCF_ADC_ADRSLT5>>3;
  printf("MCF_ADC_ADRSLT5 = %04d\n\r",(dummy));
  dummy=MCF_ADC_ADRSLT6>>3;
  printf("MCF_ADC_ADRSLT6 = %04d\n\r",(dummy));
  dummy=MCF_ADC_ADRSLT7>>3;
  printf("MCF_ADC_ADRSLT7 = %04d\n\r",(dummy));
 }
 //printf("MCF_ADC_ADSTAT = %04x \n",MCF_ADC_ADSTAT);
 //printf("MCF_ADC_CTRL2 = %04x\n\r",MCF_ADC_CTRL2);
 
 //**********SPECIAL ATTENTION***********/
 //**********The pins on PCB board have wrong NET LABELS ******/
 
}

调用方法示例:ADStartToWork(0x3000);

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客