查看: 40|回复: 0

【Eval-ADuCM360MKZ评估板】ADI公司24bits的ADC(二):ADC功能测试

[复制链接]

主题

好友

568

积分

举人

  • TA的每日心情
    无聊
    2016-10-8 20:34
  • 签到天数: 10 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2016-8-29 08:42:28 |显示全部楼层
    上一贴https://jingyan.eeboard.com/article/75376;
    来一张评估板的原理图:

    这个板子除了电源、ADuCM360最小系统之外,就只有两个设备:LED + PT100;
    那么就先把板子上的设备先用起来吧,当然用之前先单独测一下,做一些准备工作;
    LED在上一次测试工程模板的时候,已经测过了;
    那么就剩下PT100铂电阻了,这个铂电阻是用来测温的,需要用ADC采集电阻两端的电压,那么就要使用ADuCM360上的ADC,那么就先把ADC测一下,学会使用这个芯片上的ADC,为使用PT100铂电阻测温做好准备工作。
    ①看板子电路图,看芯片手册等文档,了解ADC特性及其使用方法;
    ②编写ADC测试程序,并调试;
    ③分析,总结,并发帖。
    详细过程如下:
    ①看板子电路图,看芯片手册等文档,了解ADC特性及其使用方法;
    先看一下ADuCM360这个芯片的框图:

    可以看出模拟部分和数字部分引脚是分开的,这样就不用复用引脚了;
    芯片上有两个ADC,ADC前面有一个选择器 MUX,还有一串功能组件AMP、BUF、GAIN等,ADC后面就是到M3的接口了:

    M3通过接口把这些功能组件配置成正确的模式,ADC就可以工作了,M3就可以读取ADC的状态和转换数据了。
    ②编写ADC测试程序,并调试;
    在ADI库里面找到ADC的例程,阅读例程,仿照例程写一个测试程序;

    写一个adc.c
    /**  ******************************************************************************  * @file    adc.c  * @author  YangJie  * @version V0.0  * @date    2016-8-25  * @brief   adc function  ******************************************************************************  * @attention  ******************************************************************************  *//* Includes ------------------------------------------------------------------*/#include        "adc.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/uint32_t adc1_data = 0;/* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*/  /**  * @brief  ADC1_Init  * @param  iStart:ADC状态  *        - 0 or ADCMDE_ADCMD_OFF for power down.  *        - 1 or ADCMDE_ADCMD_CONT for continuous conversion.  *        - 2 or ADCMDE_ADCMD_SINGLE for Single conversion.  *   - 3 or ADCMDE_ADCMD_IDLE for idle mode.  *        - 4 or ADCMDE_ADCMD_INTOCAL for offset calibration.  *        - 5 or ADCMDE_ADCMD_INTGCAL for gain calibration.  *        - 6 or ADCMDE_ADCMD_SYSOCAL for system offset calibration.  *        - 7 or ADCMDE_ADCMD_SYSGCAL for system gain calibration.  * @retval None  * @brief  配置ADC1参数,并使能ADC1中断  */        void ADC1_Init(int iStart){   // Masks in dividual ADC interupt flags 中断控制器   AdcMski(pADI_ADC1,ADCMSKI_RDY,1);              // Enable ADC ready interrupt source                   // Sets filter details 配置滤波器参数   AdcFlt(pADI_ADC1,124,14,FLT_NORMAL|ADCFLT_NOTCH2|ADCFLT_CHOP); // ADC filter set for 3.75Hz update rate with chop on enabled   // Sets ADC measurement range 设置ADC测量范围   // 使用内部参考电压,增益=4,有符号整型输出   AdcRng(pADI_ADC1,ADCCON_ADCREF_INTREF,ADCMDE_PGA_G4,ADCCON_ADCCODE_INT); // Internal reference selected, Gain of 4, Signed integer output   // Configures ADC buffers 配置ADC的BUFFER   // Turn off input buffers to ADC and external reference   // 关闭外部参考缓冲,打开正负缓冲电源,绕过正负缓冲旁路   AdcBuf(pADI_ADC1,ADCCFG_EXTBUF_OFF,ADCCON_BUFBYPN|ADCCON_BUFBYPP|ADCCON_BUFPOWP|ADCCON_BUFPOWN);    // 配置ADC引脚   AdcPin(pADI_ADC1,ADCCON_ADCCN_AIN10,ADCCON_ADCCP_AIN11); // Select AIN10 as postive input and AIN11 as negative input   // ADC初始状态   AdcGo(pADI_ADC1,iStart);   // 中断使能   NVIC_EnableIRQ(ADC1_IRQn);}/**  * @brief  ADC1_Int_Handler  * @param  None  * @retval None  * @brief  ADC中断服务函数  */        void ADC1_Int_Handler(){   volatile unsigned int adc_status= 0;      adc_status = AdcSta(pADI_ADC1);               // read ADC status register   adc1_data = AdcRd(pADI_ADC1);            // read ADC result register//   bSendResultToUART = 1;                  // Set flag to indicate ready to send result to UART}再为其写一个adc.h/**  ******************************************************************************  * @file    adc.c  * @author  YangJie  * @version V0.0  * @date    2016-8-25  * @brief   adc function  ******************************************************************************  * @attention  ******************************************************************************  *//* Define to prevent recursive inclusion -------------------------------------*/#ifndef __ADC_H#define __ADC_H /* Includes ------------------------------------------------------------------*/#include <ADuCM360.h>#include        "AdcLib.h"/* Exported variables ---------------------------------------------------------*/extern  uint32_t adc1_data;/* Exported functions ------------------------------------------------------- */void ADC1_Init(int iStart);#endif然后写一个用来测试的mian.c/**  ******************************************************************************  * @file    main.c  * @author  YangJie  * @version V0.0  * @date    2016-8-21  * @brief   Main program body  ******************************************************************************  * @attention  ******************************************************************************  *//* Includes ------------------------------------------------------------------*/#include <stdio.h>#include <string.h>#include <ADuCM360.h>#include        "clock.h"#include "Serial.h"#include        "delay.h"#include        "LED.h"#include        "adc.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/float voltage_f = 0.0;/* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//**  * @brief  Main program.  * @param  None  * @retval None  */int main(void){   Clk_Init();    SER_Init();   delay_init();   LED_Init();   ADC1_Init(ADCMDE_ADCMD_CONT);      printf ("\n\r\n\r初始化成功!\n\r\n\r");      /* Infinite loop */   while (1)   {      static uint8_t i = 0;            LED_on();      voltage_f = (1.2 / 268435456)*adc1_data;      printf ("\n\radc1_data --%3d-- %8f\n\r",i++,voltage_f);      delay_ms(500);      LED_off();      delay_ms(500);   }}然后编译再下载到板子上试一下,现象是能正常打印被测电压值,但是只能测0.3V,0.4V就不行了……


    ③分析,总结,并发帖。
    看到只能测到0.3V的电压,再升高也是显示0.3几伏,是已经饱和的样子,我不禁以为这个芯片坏了,伤心了一把,然后仔细去看一下程序和手册,看哪里有没有遗漏。
    首先是电压转换的计算式子:
    voltage_f = (1.2 / 268435456)*adc1_data;在数据手册上找到了依据:
    再打印ADC数据寄存器的值出来看一下:
    printf ("\n\radc1_data --%3d-- %8f--%8x\n\r",i++,voltage_f,adc1_data);观察到电压为0.3V的时候,ADC数据寄存器就饱和了,再增大到0.4、0.5都是饱和的;然后继续翻手册,直到看到增益配置时,才明白为什么:

    原来是增益影响了ADC的输入范围,一开始照着例程配置的增益配为4,最大输入只能±250mA,修改增益为1后继续测试,满量程可以测到1.2V了:

    至此,ADC已经可以使用,下一步可以试一下铂电阻测温了。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

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

    手机版|电路城

    GMT+8, 2019-7-19 21:19 , Processed in 0.147848 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz!

    返回顶部