ADC模块总结 AC7801 ADC特性: 12位分辨率 输入电压范围:AVSS-AVDD 最大转换速率:1Msps 支持12路外部通道、1路内部温度传感器通道、1路内部带隙基准电压通道 工作模式:1、规则组单通道单次转换 2、规则组单通道连续转换 3-1、规则组扫描+注入组扫描模式多通道单次转换 3-2、规则组扫描+注入组间隔模式多通道单次转换 4、规则组扫描+自动触发注入组扫描模式多通道单次转换 5-1、规则组扫描+注入组扫描模式多通道连续转换 5-2、规则组扫描+注入组间隔模式多通道连续转换 6、规则组扫描+自动触发注入组扫描模式多通道连续转换 7、规则组子组扫描模式转换 8、注入组子组扫描模式转换 AC7801 ADC时钟及转换速率计算:AC7801时钟由总线时钟(BUS Clock)分频得到的,分频单元为Clock Divisor的PSC[3:0]寄存器设置。 ADC模块通过使用若干个ADC-CLOCK周期对输入电压进行采样,采用周期通过ADC_SPT寄存器中的SPT[2:0]位进行更改。每个通道可以分别使用不同的采样时间。 转换公式为:(SPT+12)*ADC_CLOCK_CYCLE+5*APB_CLOCK_CYCLE 功能实现:使用TIMER1触发ADC规则组多通道(通道7,8)采样
代码是在官网示例代码1的基础上修改的。代码除基础的初始化代码外,采用TIMER1触发ADC采样,ADC采样可采用软件触发和硬件触发,这里采用CTU功能链接TIMER1触发,初始化代码如下:
void CTU_Config(void)
{
CTU_ConfigType ctuConfig;
memset(&ctuConfig, 0x00, sizeof(ctuConfig));
ctuConfig.uart0RxFilterEn = DISABLE;
ctuConfig.rtcCaptureEn = DISABLE;
ctuConfig.acmpCaptureEn = DISABLE;
ctuConfig.uart0RxCaptureEn = DISABLE;
ctuConfig.uartTxModulateEn = DISABLE;
ctuConfig.clkPsc = CTU_CLK_PRESCALER_1;
ctuConfig.adcRegularTriggerSource = CTU_TRIGGER_ADC_TIMER_CH1_OVERFLOW;
ctuConfig.delay0Time = 0;
CTU_Init(&ctuConfig);
}
初始化CTU后,接下来就是初始化ADC,ADC初始化代码如下:
void ADC_init()
{
ADC_ConfigType tempAdcConfig;
ADC_ConfigType* adcConfig;
adcConfig = &tempAdcConfig;
//配置复用功能引脚
GPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN2);///<ADC_IN8 Analog function enable
GPIO_SetFunc(GPIOA, GPIO_PIN3, GPIO_FUN2);///<ADC_IN7 Analog function enable
初始化ADC硬件时需要注意的是,采用多通道采样时每个通道的引脚都需要复用为ADC功能,同时需要注意规则组的采样顺序,这里我在修改代码的时候出现了一点失误,没有注意到ADC_SetRegularGroupChannel(ADC0, ADC_CH_8, ADC_SPT_CLK_7, 1)这个函数第三个参数实际代表的意义,默认把1copy成了0,导致只有一个通道在采样,另一个通道**,所以一定要记得设置规则组的组序。另外,这里我们使能了DMA功能,需要对DMA初始化,并设置DMA的链接地址,DMA初始化代码如下:
void ADC_DMAInit(void)
{
uint32_t tmpMemStartAddr = (uint32_t)&g_ADCValueBuffer[0];
uint32_t tmpMemEndAddr = (uint32_t)&g_ADCValueBuffer[DMA_TRANSFER_NUM + 1]; ///<Setting memory DMA address
DMA_ConfigType tmpDMAConfig;
memset(&tmpDMAConfig, 0x00, sizeof(DMA_ConfigType));
tmpDMAConfig.memStartAddr = tmpMemStartAddr; //初始地址
tmpDMAConfig.memEndAddr = tmpMemEndAddr;//终止地址
tmpDMAConfig.periphStartAddr = (uint32_t)(&(ADC0->RDR)); ///<Move ADC DR to memory
tmpDMAConfig.channelEn = ENABLE;
tmpDMAConfig.finishInterruptEn = ENABLE;
tmpDMAConfig.halfFinishInterruptEn = DISABLE;
tmpDMAConfig.errorInterruptEn = ENABLE;
tmpDMAConfig.channelPriority = DMA_PRIORITY_VERY_HIGH;
tmpDMAConfig.circular = ENABLE;
tmpDMAConfig.direction = DMA_READ_FROM_PERIPH;
tmpDMAConfig.MEM2MEM = DISABLE;
tmpDMAConfig.memByteMode = DMA_MEM_BYTE_MODE_1TIME;
DMA正常配置就可以了,只要注意到初始地址和终止地址链接正常,方便后续读取以及数据处理就可以实现DMA功能。最后需要初始化的是TIMER1,因为我们是采用TIMER1触发ADC采样,因此需要在TIMER中设置触发时间,保证触发时间不小于采样转换时间,这里我们设置的是500微秒timerConfig.periodValue = 100*Delay5us;最后将采集的数据读取出来,通过串口打印就可以实现我们的需求功能了。
|