ADC概述
ADC API 提供一系列处理ADC的函数。函数提供了配置采样序列,读捕获数据,注册一个采样序列中断处理器,和处理中断标志和中断清零。
取决于该处理器的特性,ADC提供高达24路输入通道,以及一个内部温度传感器。四个采样序列发生器,每个采样序列发生器都可以配置触发事件,捕获。第一个序列发生器可以捕获八路采样,第二,三可以捕获四路,而四个只能采样一路。每个采样序列繁盛期可以是相同的通道,不同的通道,或者任何组合的秩序。
采样序列发生器又可以配置的优先级,优先级可以决定捕获的顺序当多个触发同时出现时。最高优先级的采样序列发生器在总是第一个触发采样。必须注意经常出现的触发。如果他们的优先级太高,有可能饿死低优先级的采样序列发生器。
ADC数据的硬件过采样可以增加准确性,过采样参数可以设置为2x.4x.8x,16x,32x,64x.但降低了ADC的吞吐量对应的因素。硬件过采样统一应用所有样本测序。
ADC数据的软件过采样可以被用来消除采样序列发生器深度的减少。通过增加ADC触发速率和取四个触发器的值的平均。4x过采样可以不会损失任何采样序列发生器的能力。这种情况下,后果是增加数量的ADC触发器(大概ADC中断)。因为这种方式需要ADC驱动本身以外的调整。他不由驱动直接支持。软件过采样APIs不应该在这种情况下使用。
(采样序列发生器包含:输入源,触发事件,中断产生,序列发生器的优先级等)
ADC API分类
模拟到数字转换器API函数分为三组:那些处理采样序列发生器 ,那些处理处理器触发器, 和那些处理中断处理。
采样序列发生器配置,使用 ADCSequenceConfigure() and ADCSequenceStepConfigure().
使能或者禁用:ADCSequenceEnable() and ADCSequenceDisable()
获取捕获的数据:ADCSequenceDataGet().
采样序列发生器FIFO溢出和下溢的管理: ADCSequenceOverflow(), ADCSequenceOverflowClear(), ADCSequenceUnderflow()
控制硬件的过采样ADC:ADCHardwareOversampleConfigure()
控制软件的过采样ADC:ADCSoftwareOversampleConfigure(), ADCSoftwareOversampleStepConfigure(), and ADCSoftwareOversampleDataGet().
处理器触发使用它们生成:ADCProcessorTrigger().
ADC样品测序器中断的中断处理程序管理:ADCIntRegister() and ADCIntUnregister().
采样序列发生器中断来源管理:ADCIntDisable(), ADCIntEnable(), ADCIntStatus(), and ADCIntClear().
管脚对应:
/*
* main.c
* 程序任务:从一个引脚介入高电平,然后配置采样。
* 观察ADC采样值是否正确
*
* 步骤:
* 1,首先配置ADC模块
* 初始化ADC序列步骤如下:
* 1,使用RCGCADC寄存器使能ADC时钟
* 2,通过RCGCGPIO寄存器使能相应的的GPIO模块
* 3,对于ADC输入引脚设置GPIO AFSEL bits,以确定那个引脚被配置
* 4,通过清零在GPIOEN寄存器的相应的DEN引脚来配置AINx作为模拟输入
* 5,禁用对于ADC输入模拟隔离电路,这些模拟隔离电路通过写一个1到CPIOAMSEL寄存器在相关的GPIO块来使用
* 6,如果需要,可以重新配置序列优先级。默认配置为采样序列0有最高的优先级,而采样序列3优先级最低
* ----
* 可以简化为:
* 1,配置ADC时钟
* 2,配置相应的端口设置为ADC功能。
* 3,配置采样方式:比如配置采样序列,采样是否触发中断
* 4,开启采样
* 2,采样序列配置
* 配置过程如下:
* 1,通过将清零ADCACTSS寄存器的相应ASENn bit引脚,来确保采样序列被禁用。
* 采样序列编程可以被允许而不需要他们的使能,如果一个触发时间在配置过程中发生,
* 在编程防止错误性执行器件禁用。
* 2,在ADCMUX寄存器中配置采样序列的触发时间
* 3,当使用PWM生成器作为触发源时,使用ADCCTSSEL寄存器来指定,在这个寄存器中,
* PWM模块发生器是固定的。对于所有的生成器,默认寄存器复位选择PWM0模块
* 4,对于每个采样序列,在ADCSSMUX寄存器中配置相应的输入源
* 5,对于每个采样序列,在ADCSSCTLn寄存器中相应的半字节来配置采样序列的控制bit位
* 当编程到最后一个半字节时,确认END bit被设置。未能设置成功END bit,将会导致一个
* 不可预测的行为
* 6,如果中断被使用,在ADCIM寄存器中设置相应的MASK bit位
* 7,通过设置在ADCACTSS寄存器中相应的ASENn bit位。来使能采样序列逻辑
* -------------------------------------------------------------
* 系统提供了以下配置函数
* ADCIntRegister()
* ADCSequenceConfigure()
* ADCSequenceStepConfigure()
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/sysctl.h"
#include "driverlib/adc.h"
/*
* 外围设备驱动程序库运行时参数检查相当粗略因为过度的检查会对循环计数有负面影响
* 在调试过程,你可能以一种错误的方式调用API或者其他的原因,导致一个错误发生。
* 如果驱动库遇到这样的问题,那么下边的代码将会调用。他将会保存文件名和错误发生的位置。
*
*/
#ifdef DEBUG
void__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
int main(void)
{
uint32_t ui32ADC0Value[4];
/*
* 因为volatile是不稳定的,所以它的值可能发生变化。每次使用它的时候必须从内存中取出i的值,
* 因而编译器生成的汇编代码会重新从m 的地址处读取数据放在n中。
* 理解为直接存取原始内存地址”比较合适,保证敏感数据的一致性
*/
volatile uint32_t ui32TempAvg;
/*
* 系统时钟设置
* SYSCTL_SYSDIV_5->系统时钟或者是锁相环/5
* SYSCTL_USE_PLL ->System clock is the PLL clock
* SYSCTL_OSC_MAIN->Osc source is main osc
* SYSCTL_XTAL_16MHZ ->External crystal is 16 MHz
* 系统时钟为40Mhz
*/
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
//ADC0使能
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
//ADC序列设置
//extern void ADCSequenceConfigure
//(uint32_t ui32Base, uint32_t ui32SequenceNum,uint32_t ui32Trigger, uint32_t ui32Priority);
//序列1,最大采样值4.FIFO深度为4.优先级为1,最高
ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
/*
* extern void ADCSequenceStepConfigure(uint32_t ui32Base,
uint32_t ui32SequenceNum,
uint32_t ui32Step, uint32_t ui32Config);
*/
//ADC_CTL_TS -> Temperature sensor select
//ADC_CTL_IE -> Interrupt enable
//ADC_CTL_END-> Sequence end select
//在TM4C123G芯片中,每个ADC四个可编程序列
//最后一个参数ADC_CTL_CHx 是用来选择中断源
//在完成第四个采样动作之后,结束采样序列。
ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE,1,3,ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);
//使能
ADCSequenceEnable(ADC0_BASE, 1);
while(1)
{
//ADC中断清零清零
ADCIntClear(ADC0_BASE, 1);
//ADC处理触发器
ADCProcessorTrigger(ADC0_BASE, 1);
//等ADC转换结束
while(!ADCIntStatus(ADC0_BASE, 1, false))
{
}
//获取ADC序列数据
ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
/*
* 加2的原因:加2是为了舍入,因为2/4=0.5.1.5进位为2.如果0.5增益到1.5,这个将会被舍入到1,因为整数的规则。
*/
ui32TempAvg = (ui32ADC0Value[0] + ui32ADC0Value[1] + ui32ADC0Value[2] + ui32ADC0Value[3] + 2)/4;
}
}