飞思卡尔XS128八位数模转换模块的实验与心得体会

飞思卡尔XS128八位数模转换模块的实验与心得体会

数模转换的编程流程:

① 锁相环时钟设置,这一步不细讲,后面会有文章来专门解释锁相环的设置,将总线时钟频率升到32MHz
② ATDCTL2(控制寄存器2)设置,这个寄存器主要针对标志快速清除,触发方式与中断使能,这里设置为快速清零,中断禁能
③ ATDCTL1_SRES选用8位
④ ATDCTL3选择对齐方式与序列转换长度
⑤ ATDCTL4选择采样时间与采样时钟分频系数
⑥ ATDCTL5选择通道转换,注意,看好电路图,你是从哪个通道采来的信号,不单单要从软件寄存器上去选择,还要符合硬件原理图。两个电位计在开发板上的连接原理图是接着AD00和AD01。
⑦ ATDSTAT0_SCF状态结束标志位判断
⑧ 按照结果寄存器的保存位置输出到变量里观察

代码标注

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */

#define  BUS_CLOCK		   32000000	   //总线频率,改变总线频率直接在此处修改
#define  OSC_CLOCK		   16000000	   //晶振频率         
#define LEDCPU PORTK_PK4
#define LEDCPU_dir DDRK_DDRK4
unsigned char AD_in1,AD_in0,Lilun_AD1,Lilun_AD0;


/*************************************************************/
/*                      初始化锁相环                         */
/*************************************************************/
void INIT_PLL(void) 
{
    CLKSEL &= 0x7f;       //设置OSCCLK作为系统时钟
    PLLCTL &= 0x8F;       //禁止锁相环
 
    //PLLCLK=2×OSCCLK×(SYNDIV+1)/(REFDIV+1), fbus=PLLCLK/2
    #if(BUS_CLOCK == 120000000) 
        SYNR = 0xcd;
    #elif(BUS_CLOCK == 104000000) 
      SYNR = 0xcc;
    #elif(BUS_CLOCK == 96000000) 
      SYNR = 0xcb;
    #elif(BUS_CLOCK == 88000000) 
      SYNR = 0xca;
    #elif(BUS_CLOCK == 80000000) 
      SYNR = 0xc9;
    #elif(BUS_CLOCK == 72000000) 
      SYNR = 0xc8;
    #elif(BUS_CLOCK == 64000000) 
      SYNR = 0xc7;
    #elif(BUS_CLOCK == 56000000) 
      SYNR = 0xc6;
    #elif(BUS_CLOCK == 48000000) 
      SYNR = 0xc5;
    #elif(BUS_CLOCK == 40000000) 
      SYNR = 0x44;
    #elif(BUS_CLOCK == 32000000)
      SYNR = 0x43;     
    #elif(BUS_CLOCK == 24000000)
      SYNR = 0x42;
    #elif(BUS_CLOCK == 16000000)
      SYNR = 0x01;
   #endif 

    REFDV = 0x81;
    PLLCTL |=0x70;  //使能锁相环 PLLCLOCK CONTROL
    asm NOP;
    asm NOP;
    while(!(CRGFLG&0x08)); //PLLCLK锁定
    CLKSEL |= 0x80;        //设置PLLCLK为系统时钟
}

/*************************************************************/
/*                      初始化AD模块                         */
/*************************************************************/
void INIT_AD(void) 
{
 ATD0CTL2 = 0x40;  //Bit7:只读不用管
                   //Bit6:标志快速清除,不用读状态寄存器直接读了结果寄存器就清除
                   //    如果不是快速清除的话需要读完所有才能清除
                   //Bit5:停止模式时,转换被终止
                   //Bit4:有效边沿触发模式
                   //Bit3:低电平或者下降沿触发
                   //Bit2:禁止外部触发模式
                   //Bit1:ASCIE ATD序列结束中断禁能
                   //Bit0:禁能比较中断
                   //启动A/D模块,快速清零,禁止中断      0100 0000
                   
 ATD0CTL1_SRES=0;  //选用8位模数转换   ERES[1:0]是精度选择
 
 ATD0CTL3 = 0x88;   //每次只转换一个通道                1000 1000
                    //Bit7:DJM 1为右对齐也就是说结果寄存器的数据是怎么向映射到IP数据总线上
                    //对于八位分辨率右对齐,结果寄存器映射到数据总线的0-7位,7是高位
                    //Bit6 5 4 3 S8C/S4C/S2C/S1C 0001 每个序列转换长度(转换了多少次)为1,分配到ATDDR0
                    //Bit2:FIFO位 转换序列的转换结果映射到转换结果寄存器中
                    //Bit1 0:背景调试冻结使能,00忽略背景信号
 
 
 ATD0CTL4 = 0x07;   //Bit15 14 13:SMP[2:0]表示采样时间,000为采样时间的ATD时钟周期数为4个
                    //这里需要注意的是,采样周期有三个阶段,第一第二个阶段是不能控制的,第三个转换时长可以控制
                    //也就是说,一共会消耗第一阶段2+第二阶段4+第三阶段自己选择的时长来完成采样
                    //Bit[13:8]:PRS[4:0]时钟预分频器,构成时钟的预分频系数PRS
                    //计算式为f=fBUS/(2*(PRS+1)),注意范围500kHz-2MHz
                    //总线时钟32MHz f=32/(2*(7+1))=2MHz 
                    
                    
                    
                    //AD模块时钟频率为2MHz            0000 0111
}

/*************************************************************/
/*                        起动AD转换                         */
/*************************************************************/
unsigned char AD_capture(unsigned char chanel) 
{
 unsigned char AD_data;
 switch(chanel)
 { 
  case 0:
    ATD0CTL5 = 0x00;    //转换AD00          Bit6:SC 禁止特殊通道转换
                                          //Bit5:SCAN 单次执行转换序列模式,不连续
                                          //Bit4:MULT 多通道采集 0是单通道指定采集
                                          //Bit[3:0]:CD CC CB CA选择模拟输入通道 AD0
                                          /***********************************************************/
                                          /*例子:MULT+CC/CB/CA+S8C/S4C/S2C/S1C                      */
                                          /*0+0/1/0+0/0/1/1单通道模式AD2通道采集转化3次放到ATDDR[0:2]*/
                                          /*1+0/1/0+0/0/1/1多通道模式AD2/AD3/AD4转化放到紸TDDR[0:2]  */
                                          /***********************************************************/
                                          //这里就是单通道模式AD0转化一次放到ATDDR0中
                                                                               
                                          
    while(!ATD0STAT0_SCF);                //SCF为状态寄存器结束标志
    AD_data = ATD0DR0L;                   //八位右对齐找ATDDR0L
    break;

  case 1:
    ATD0CTL5 = 0x01;    //转换AD01
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;
  
  case 2:
    ATD0CTL5 = 0x02;    //转换AD02
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;
 
  case 3:
    ATD0CTL5 = 0x03;    //转换AD03
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 4:
    ATD0CTL5 = 0x04;    //转换AD04
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 5:
    ATD0CTL5 = 0x05;    //转换AD05
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 6:
    ATD0CTL5 = 0x06;    //转换AD06
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 7:
    ATD0CTL5 = 0x07;    //转换AD07
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 8:
    ATD0CTL5 = 0x08;    //转换AD08
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 9:
    ATD0CTL5 = 0x09;    //转换AD09
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 10:
    ATD0CTL5 = 0x0a;    //转换AD10
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 11:
    ATD0CTL5 = 0x0b;    //转换AD11
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 12:
    ATD0CTL5 = 0x0c;    //转换AD12
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 13:
    ATD0CTL5 = 0x0d;    //转换AD13
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 14:
    ATD0CTL5 = 0x0e;    //转换AD14
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;

  case 15:
    ATD0CTL5 = 0x0f;    //转换AD15
    while(!ATD0STAT0_SCF);
    AD_data = ATD0DR0L;
    break;
  
 }
 return(AD_data);
}

/*************************************************************/
/*                           主函数                          */
/*************************************************************/
void main(void) {
	DisableInterrupts;
  INIT_PLL();
  INIT_AD();
  LEDCPU_dir=1;
	EnableInterrupts;


  
  
  for(;;) 
  {
      AD_in1= AD_capture(1);
      AD_in0=AD_capture(0);
  //    Lilun_AD1=AD_in1*5/255;
  //    Lilun_AD0=AD_in0*5/255;      (数据丢失,这样没有任何意义)
      if(AD_in1 > AD_in0)
        LEDCPU = 0;
      else
        LEDCPU = 1;
  
  } 
}

注:代码来源飞翔单片机开发板演示程序,本人小白,欢迎指出错误

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值