TA的每日心情 | 无聊 2016-10-8 20:34 |
---|
签到天数: 10 天 连续签到: 1 天 [LV.3]偶尔看看II
|
接上一贴: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就不行了&hellip;&hellip;
③分析,总结,并发帖。
看到只能测到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已经可以使用,下一步可以试一下铂电阻测温了。 |
|