查看: 3462|回复: 2

[S12] MC9S12P128MQK的AD模块读取数据问题

[复制链接]
  • TA的每日心情
    奋斗
    2020-12-31 08:09
  • 签到天数: 438 天

    连续签到: 1 天

    [LV.9]以坛为家II

    9

    主题

    510

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1673
    最后登录
    2020-12-31
    发表于 2018-11-28 17:45:04 | 显示全部楼层 |阅读模式
    DEMOAX9S12P128开发板,CodeWarrior5.1,用之前用自己编写的AD工程结果当通道1输入信号,如5V,在通道0寄存器ATDDR0读到了值,不知道是哪里设置问题。然后用full version的Processor Expert生成AD程序,发现ATDDR0~ATDDR7寄存器的值均为0,我的输入是0,0.625,1.25,1.875,2.5,3.125,3.75,4.375V,但是读到的值均为0。请问各位大神是怎么解决的?
    工程代码见附件。
    AD1.c源代码如下:
    /** ###################################################################
    **     THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT.
    **     Filename  : AD1.c
    **     Project   : pe_adc
    **     Processor : MC9S12P128MQK
    **     Component : ADC
    **     Version   : Component 01.593, Driver 01.17, CPU db: 3.00.027
    **     Compiler  : CodeWarrior HC12 C Compiler
    **     Date/Time : 2018/11/28, 16:58
    **     Abstract  :
    **         This device "ADC" implements an A/D converter,
    **         its control methods and interrupt/event handling procedure.
    **         This device is designed for fast A/D conversions.
    **     Settings  :
    **         AD control register         : ATDCTL4     [$0074]
    **         Interrupt name              : Vatd
    **         Interrupt enable reg.       : ATDCTL23    [$0072]
    **         Priority                    :
    **         User handling procedure     : AD1_OnEnd
    **         Number of conversions       : 1
    **         AD resolution               : 12-bit
    **
    **         Input pins
    **
    **              Port name              : ADL
    **              Bit number (in port)   : 0
    **              Bit mask of the port   : $0001
    **              Port data register     : PT1AD       [$0271]
    **              Port control register  : DDR1AD      [$0273]
    **
    **              Port name              : ADL
    **              Bit number (in port)   : 1
    **              Bit mask of the port   : $0002
    **              Port data register     : PT1AD       [$0271]
    **              Port control register  : DDR1AD      [$0273]
    **
    **              Port name              : ADL
    **              Bit number (in port)   : 2
    **              Bit mask of the port   : $0004
    **              Port data register     : PT1AD       [$0271]
    **              Port control register  : DDR1AD      [$0273]
    **
    **              Port name              : ADL
    **              Bit number (in port)   : 3
    **              Bit mask of the port   : $0008
    **              Port data register     : PT1AD       [$0271]
    **              Port control register  : DDR1AD      [$0273]
    **
    **              Port name              : ADL
    **              Bit number (in port)   : 4
    **              Bit mask of the port   : $0010
    **              Port data register     : PT1AD       [$0271]
    **              Port control register  : DDR1AD      [$0273]
    **
    **              Port name              : ADL
    **              Bit number (in port)   : 5
    **              Bit mask of the port   : $0020
    **              Port data register     : PT1AD       [$0271]
    **              Port control register  : DDR1AD      [$0273]
    **
    **              Port name              : ADL
    **              Bit number (in port)   : 6
    **              Bit mask of the port   : $0040
    **              Port data register     : PT1AD       [$0271]
    **              Port control register  : DDR1AD      [$0273]
    **
    **              Port name              : ADL
    **              Bit number (in port)   : 7
    **              Bit mask of the port   : $0080
    **              Port data register     : PT1AD       [$0271]
    **              Port control register  : DDR1AD      [$0273]
    **
    **         Initialization:
    **              Conversion             : Enabled
    **              Event                  : Enabled
    **         High speed mode
    **             Prescaler               : divide-by-20
    **     Contents  :
    **         Measure    - byte AD1_Measure(bool WaitForResult);
    **         GetValue16 - byte AD1_GetValue16(word *Values);
    **
    **     Copyright : 1997 - 2010 Freescale Semiconductor, Inc. All Rights Reserved.
    **     
    **     http      : www.freescale.com
    **     mail      : support@freescale.com
    ** ###################################################################*/

    /* MODULE AD1. */
    #pragma MESSAGE DISABLE C5703          /* Disable warning C5703 "arameter is not referenced" */
    #pragma MESSAGE DISABLE C4002          /* Disable warning C4002 "Result not used is ignored" */
    #pragma MESSAGE DISABLE C12056         /* Disable warning C12056 "SP debug info incorrect because of optimization or inline assembler" */
    #include "Events.h"
    #include "AD1.h"
    #pragma DATA_SEG AD1_DATA              /* Select data segment "AD1_DATA" */
    #pragma CODE_SEG AD1_CODE
    #pragma CONST_SEG AD1_CONST            /* Constant section for this module */
    #define STOP            0U             /* STOP state           */
    #define MEASURE         1U             /* MESURE state         */
    #define CONTINUOUS      2U             /* CONTINUOUS state      */

    static bool OutFlg;                    /* Measurement finish flag */
    volatile static byte ModeFlg;          /* Current state of device */
    /*
    ** ===================================================================
    **     Method      :  AD1_Interrupt (component ADC)
    **
    **     Description :
    **         The method services the interrupt of the selected peripheral(s)
    **         and eventually invokes event(s) of the component.
    **         This method is internal. It is used by Processor Expert only.
    ** ===================================================================
    */
    #pragma CODE_SEG __NEAR_SEG NON_BANKED
    ISR(AD1_Interrupt)
    {
      ATDDR0;                              /* Dummy read of data register to clear flags */
      OutFlg = TRUE;                       /* Measured values are available */
      ModeFlg = STOP;                      /* Set the device to the stop mode */
      AD1_OnEnd();                         /* Invoke user event */
    }
    #pragma CODE_SEG AD1_CODE
    /*
    ** ===================================================================
    **     Method      :  AD1_Measure (component ADC)
    **
    **     Description :
    **         This method performs one measurement on all channels that
    **         are set in the component inspector. (Note: If the <number of
    **         conversions> is more than one the conversion of A/D
    **         channels is performed specified number of times.)
    **     Parameters  :
    **         NAME            - DESCRIPTION
    **         WaitForResult   - Wait for a result
    **                           of a conversion. If the <interrupt
    **                           service> is disabled and a <number of
    **                           conversions> is greater than 1, the
    **                           WaitForResult parameter is ignored and
    **                           the method waits for each result every
    **                           time.
    **     Returns     :
    **         ---             - Error code, possible codes:
    **                           ERR_OK - OK
    **                           ERR_SPEED - This device does not work in
    **                           the active speed mode
    **                           ERR_DISABLED - Device is disabled
    **                           ERR_BUSY - A conversion is already
    **                           running
    ** ===================================================================
    */
    byte AD1_Measure(bool WaitForResult)
    {
      if (ModeFlg != STOP) {               /* Is the device in different mode than "stop"? */
        return ERR_BUSY;                   /* If yes then error */
      }
      ModeFlg = MEASURE;                   /* Set state of device to the measure mode */
      OutFlg = FALSE;                      /* Output values aren't available */
      /* ATDCTL5: ??=0,SC=0,SCAN=0,MULT=1,CD=0,CC=0,CB=0,CA=0 */
      ATDCTL5 = 0x10U;                     /* Start conversions */
      if (WaitForResult) {                 /* Is WaitForResult TRUE? */
        while (ModeFlg == MEASURE) {}      /* If yes then wait for end of measurement */
      }
      return ERR_OK;                       /* OK */
    }
    /*
    ** ===================================================================
    **     Method      :  AD1_GetValue16 (component ADC)
    **
    **     Description :
    **         This method returns the last measured values of all
    **         channels justified to the left. Compared with <GetValue>
    **         method this method returns more accurate result if the
    **         <number of conversions> is greater than 1 and <AD
    **         resolution> is less than 16 bits. In addition, the user
    **         code dependency on <AD resolution> is eliminated.
    **     Parameters  :
    **         NAME            - DESCRIPTION
    **       * Values          - Pointer to the array that
    **                           contains the measured data.
    **     Returns     :
    **         ---             - Error code, possible codes:
    **                           ERR_OK - OK
    **                           ERR_SPEED - This device does not work in
    **                           the active speed mode
    **                           ERR_NOTAVAIL - Requested value not
    **                           available
    **                           ERR_OVERRUN - External trigger overrun
    **                           flag was detected after last value(s)
    **                           was obtained (for example by GetValue).
    **                           This error may not be supported on some
    **                           CPUs (see generated code).
    ** ===================================================================
    */
    byte AD1_GetValue16(word *Values)
    {
      if (!OutFlg) {                       /* Is measured value(s) available? */
        return ERR_NOTAVAIL;               /* If no then error */
      }
      /* Note: Next 8 lines are speed optimized */
      *Values++ = ATDDR0;                  /* Save measured values to the output buffer */
      *Values++ = ATDDR1;                  /* Save measured values to the output buffer */
      *Values++ = ATDDR2;                  /* Save measured values to the output buffer */
      *Values++ = ATDDR3;                  /* Save measured values to the output buffer */
      *Values++ = ATDDR4;                  /* Save measured values to the output buffer */
      *Values++ = ATDDR5;                  /* Save measured values to the output buffer */
      *Values++ = ATDDR6;                  /* Save measured values to the output buffer */
      *Values = ATDDR7;                    /* Save measured values to the output buffer */
      return ERR_OK;                       /* OK */
    }
    /*
    ** ===================================================================
    **     Method      :  AD1_Init (component ADC)
    **
    **     Description :
    **         Initializes the associated peripheral(s) and the component's
    **         internal variables. The method is called automatically as a
    **         part of the application initialization code.
    **         This method is internal. It is used by Processor Expert only.
    ** ===================================================================
    */
    void AD1_Init(void)
    {
      OutFlg = FALSE;                      /* No measured value */
      ModeFlg = STOP;                      /* Device isn't running */
      /* ATDCTL4: SMP2=1,SMP1=1,SMP0=1,PRS4=0,PRS3=1,PRS2=0,PRS1=0,PRS0=1 */
      ATDCTL4 = 0xE9U;                     /* Set sample time and prescaler */
      /* ATDCTL3: DJM=0,S8C=1,S4C=0,S2C=0,S1C=0,FIFO=0,FRZ1=0,FRZ0=0 */
      ATDCTL3 = 0x40U;                     /* Set ATD control register 3 */
      /* ATDCTL0: ??=0,??=0,??=0,??=0,WRAP3=1,WRAP2=1,WRAP1=1,WRAP0=1 */
      ATDCTL0 = 0x0FU;                     /* Set wrap around */
      /* ATDCTL1: ETRIGSEL=0,SRES1=1,SRES0=0,SMP_DIS=1,ETRIGCH3=1,ETRIGCH2=1,ETRIGCH1=1,ETRIGCH0=1 */
      ATDCTL1 = 0x5FU;                     /* Set resolution and discharge */
      /* ATDCTL2: ??=0,AFFC=1,ICLKSTP=1,ETRIGLE=0,ETRIGP=0,ETRIGE=0,ASCIE=1,ACMPIE=0 */
      ATDCTL2 = 0x62U;                     /* Set ATD control register 2 */
    }

    /* END AD1. */
    /*
    ** ###################################################################
    **
    **     This file was created by Processor Expert 3.02 [04.44]
    **     for the Freescale HCS12 series of microcontrollers.
    **
    ** ###################################################################
    */

    我知道答案 目前已有2人回答

    pe adc.zip

    353.89 KB, 下载次数: 1, 下载积分: 威望 1

    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2020-12-31 08:09
  • 签到天数: 438 天

    连续签到: 1 天

    [LV.9]以坛为家II

    9

    主题

    510

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1673
    最后登录
    2020-12-31
     楼主| 发表于 2018-11-28 17:50:14 | 显示全部楼层
    主函数如下:
    /** ###################################################################
    **     Filename  : pe_adc.c
    **     Project   : pe_adc
    **     Processor : MC9S12P128MQK
    **     Version   : Driver 01.14
    **     Compiler  : CodeWarrior HC12 C Compiler
    **     Date/Time : 2018/11/28, 10:12
    **     Abstract  :
    **         Main module.
    **         This module contains user's application code.
    **     Settings  :
    **     Contents  :
    **         No public methods
    **
    ** ###################################################################*/
    /* MODULE pe_adc */

    /* Including needed modules to compile this module/procedure */
    #include "Cpu.h"
    #include "Events.h"
    #include "AD1.h"
    /* Include shared modules, which are used for whole project */
    #include "PE_Types.h"
    #include "PE_Error.h"
    #include "PE_Const.h"
    #include "IO_Map.h"

    /* User includes (#include below this line is not maintained by Processor Expert) */

    void main(void)
    {
      /* Write your local variable definition here */
      int ADvalue[8];
      /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
      PE_low_level_init();
      /*** End of Processor Expert internal initialization.                    ***/

      /* Write your code here */
      while(1) {
              AD1_GetValue16(ADvalue);       
      }
      /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
      for(;;){}
      /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
    } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

    /* END pe_adc */
    /*
    ** ###################################################################
    **
    **     This file was created by Processor Expert 3.02 [04.44]
    **     for the Freescale HCS12 series of microcontrollers.
    **
    ** ###################################################################
    */
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2020-12-31 08:09
  • 签到天数: 438 天

    连续签到: 1 天

    [LV.9]以坛为家II

    9

    主题

    510

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1673
    最后登录
    2020-12-31
     楼主| 发表于 2018-11-28 17:55:39 | 显示全部楼层
    用之前用自己编写的AD工程结果当通道1输入信号,如5V,在通道0寄存器ATDDR0读到了值255,ATDDR1~ATDDR7,不知道哪里出了问题,请大神帮忙分析分析。
    源代码如下:
    #include <hidef.h>      /* common defines and macros */
    #include "derivative.h"      /* derivative-specific definitions */



    void delay(void)
    {
      unsigned int i;
      for(i=0;i<50;i++)
       {
        asm("nop");           //汇编命令,执行一个总线周期的空指令
       }
    }
    /*
    void vfnADC_Init(void)
    {

          ATDCTL1_SRES = 0x00;      //8bit resolution
          ATDCTL1_SMP_DIS = 1;      
          ATDCTL2_ETRIGE = 0;   
          ATDCTL3_DJM = 1;      
          ATDCTL3_S8C = 1;      
          ATDCTL3_S4C = 1;
          ATDCTL3_S2C = 1;
          ATDCTL3_S1C = 1;
        ATDCTL5_SCAN = 1;      
        ATDCTL5_MULT = 1;         
        ATDCTL0 = ATDCTL0 & 0x0F;  
        ATDCTL3_FRZ = 2;  
        ATDCTL4_SMP = 3;
        ATDCTL4_PRS = 4;
        ATDSTAT0_SCF = 1;
        ATDCTL2_ASCIE = 1;
       //ATDCTL5 = ATDCTL5 & 0xF0;
             
    }*/

    void INIT_AD(void)
    {

    ATDSTAT0_SCF = 1;

    ATDCTL2 = 0xc0;  //7位空
                       //6位AFFC=1, 转换标志位快速清零
                       //5位ICLKSTP=0,在停止模式下,ATD模块停止当前的转换
                       //432位ETRIGP、ETRIGLE、ETRIGE=000,禁止外部触发
                       //1位ASCIE=0  禁止AD完成中断?
                       //0位ACMPIE=0 禁止A/D 比较中断
    delay();          //延时函数,给硬件一定的反应时间
    ATDCTL1_SRES=0;  //设置ATD0CTL1_SRES=0选用8位模数转换
                       //   SRES        AD精度
                       //    00           8位
                       //    01          10位
                       //    10          12位
                       //    11           无
    ATDCTL1_SMP_DIS = 1;
    ATDCTL3 = 0x88;  //7位DJM=1 转换结果右对齐
                       //6543位S8C·S4C·S2C·S1C=0001转换序列长度为1
                       //2位FIFO=0 禁止FIFO模式
                       //10位FRZ1-0=00,冻结模式下继续转换

    ATDCTL4 = 0x01;   //765位SMP2,SMP,SMP1=000 设置采样时间为4倍AD时钟周期
                       //43210位 PPS[4:0]=00001    设置AD时钟周期
                       //公式:ATDClock = BusClock/(PRS[4 : 0] + 1) × 0.5
                       //      ATDClock = 8M      /(1 + 1) × 0.5 =2M

    //PT1AD = 0x02;
    //DDR1AD = 0x03;

    }



    /*************************************************************/
    /*                        起动AD转换                         */
    /*************************************************************/
    unsigned char AD_capture(unsigned char s)
    {
    unsigned char AD_data;
    switch(s)
    {
      case 0:
        ATDCTL5 = 0x00;    //6位3210位SC·CD·CC·CB·CA=00001  设置模拟量输入通道为AN0
                            //5位SCAN=0  AD转换序列只转换一次
                            //4位MULT=0  AD转换为单通道序列

        while(!ATDSTAT0_SCF);  //SCF:转换序列完成标志位。当一次转换序列完成后,该标志位置1
                                //等待AD转换完成
        AD_data = ATDDR0L;     //从结果转换寄存器读取AD转换结果到变量AD_data??????
        break;

      case 1:
        ATDCTL5 = 0x01;    //6位3210位SC·CD·CC·CB·CA=00000  设置模拟量输入通道为AN1
                            //5位SCAN=0  AD转换序列只转换一次
                            //4位MULT=0  AD转换为单通道序列
        while(!ATDSTAT0_SCF);  //SCF:转换序列完成标志位。当一次转换序列完成后,该标志位置1
                                //等待AD转换完成
        AD_data = ATDDR1L;     //从结果转换寄存器读取AD转换结果到变量AD_data
        break;
       
      case 2:
        ATDCTL5 = 0x02;    //6位3210位SC·CD·CC·CB·CA=00000  设置模拟量输入通道为AN1
                            //5位SCAN=0  AD转换序列只转换一次
                            //4位MULT=0  AD转换为单通道序列
        while(!ATDSTAT0_SCF);  //SCF:转换序列完成标志位。当一次转换序列完成后,该标志位置1
                                //等待AD转换完成
        AD_data = ATDDR2L;     //从结果转换寄存器读取AD转换结果到变量AD_data
        break;
       
      case 3:
        ATDCTL5 = 0x03;    //6位3210位SC·CD·CC·CB·CA=00000  设置模拟量输入通道为AN1
                            //5位SCAN=0  AD转换序列只转换一次
                            //4位MULT=0  AD转换为单通道序列
        while(!ATDSTAT0_SCF);  //SCF:转换序列完成标志位。当一次转换序列完成后,该标志位置1
                                //等待AD转换完成
        AD_data = ATDDR3L;     //从结果转换寄存器读取AD转换结果到变量AD_data
        break;
       
      case 4:
        ATDCTL5 = 0x04;    //6位3210位SC·CD·CC·CB·CA=00000  设置模拟量输入通道为AN1
                            //5位SCAN=0  AD转换序列只转换一次
                            //4位MULT=0  AD转换为单通道序列
        while(!ATDSTAT0_SCF);  //SCF:转换序列完成标志位。当一次转换序列完成后,该标志位置1
                                //等待AD转换完成
        AD_data = ATDDR4L;     //从结果转换寄存器读取AD转换结果到变量AD_data
        break;
       
      case 5:
        ATDCTL5 = 0x05;    //6位3210位SC·CD·CC·CB·CA=00000  设置模拟量输入通道为AN1
                            //5位SCAN=0  AD转换序列只转换一次
                            //4位MULT=0  AD转换为单通道序列
        while(!ATDSTAT0_SCF);  //SCF:转换序列完成标志位。当一次转换序列完成后,该标志位置1
                                //等待AD转换完成
        AD_data = ATDDR5L;     //从结果转换寄存器读取AD转换结果到变量AD_data
        break;
       
      case 6:
        ATDCTL5 = 0x06;    //6位3210位SC·CD·CC·CB·CA=00000  设置模拟量输入通道为AN1
                            //5位SCAN=0  AD转换序列只转换一次
                            //4位MULT=0  AD转换为单通道序列
        while(!ATDSTAT0_SCF);  //SCF:转换序列完成标志位。当一次转换序列完成后,该标志位置1
                                //等待AD转换完成
        AD_data = ATDDR6L;     //从结果转换寄存器读取AD转换结果到变量AD_data
        break;
       
      case 7:
        ATDCTL5 = 0x07;    //6位3210位SC·CD·CC·CB·CA=00000  设置模拟量输入通道为AN1
                            //5位SCAN=0  AD转换序列只转换一次
                            //4位MULT=0  AD转换为单通道序列
        while(!ATDSTAT0_SCF);  //SCF:转换序列完成标志位。当一次转换序列完成后,该标志位置1
                                //等待AD转换完成
        AD_data = ATDDR7L;     //从结果转换寄存器读取AD转换结果到变量AD_data
        break;
    }
    return(AD_data);           //返回变量AD_data
    }


    /*-- Main Code ----------------------------------------------------------------*/
    void main(void)
    {

         int out_value_original;
         int outvalueflag = 0x1000;
         int i,j;
         DDRB = 0xff;
         
         //DISABLE_INTERRUPTS();
         //vfnADC_Init();
         INIT_AD();
         //ENABLE_INTERRUPTS();
         
         while(1){
          
        out_value_original = AD_capture(1) ;
        outvalueflag = 0xAAAA;
        for(i=0;i<=15;i++)
        {
          for(j=0;j<50;j++);
          if((outvalueflag & 0x0001)==0x0001)
          {        
            PORTB_PB5=1;
          }
          else
          {
            PORTB_PB5=0;
          }
          outvalueflag = outvalueflag >> 1;
          PORTB_PB6 = ~PORTB_PB6;      
        }
       
        for(i=0;i<=15;i++)
        {
          for(j=0;j<50;j++);
          if((out_value_original & 0x0001)==0x0001)
          {        
            PORTB_PB5=1;
          }
          else
          {
            PORTB_PB5=0;
          }  
          out_value_original = out_value_original >> 1;
          PORTB_PB6 = ~PORTB_PB6;   
        }
        }
    }

    /*******************************************************************************/
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-21 06:33 , Processed in 0.091959 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表