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

作者: 杨肉师傅
上传时间为: 2016-08-29 08:42 AM
2016-08-29
阅读:

上一贴http://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已经可以使用,下一步可以试一下铂电阻测温了。

全部评论 ()
条评论
写评论

创建讨论帖子

登录 后参与评论
系统提示