本帖最后由 oxygenzz 于 2019-3-25 18:42 编辑
ADC是MCU的基本外设,用于采集模拟信号进行模数转换。ADCC是一种高级的ADC外设。下面以PIC16F18446为例,使用MCC来学习这款外设。
我们先把ADCC的MCC配置界面和数据手册中的模块框图做一对比。ADC时钟配置,电压参考,通道是需要配置的主要参数。
1. ADC时钟设设置,TAD需要满足数据手册的规定。转换时间基本上为11.5倍的TAD,而且时间太长太短都不建议采用。见图。
2. 参考电压文档里也有详细介绍,需要注意的是,如果使用FVR 1.024/2.048/4.096V 作为正参考电压,需要使能FVR外设。
3. ADC转换通道分为内部通道和由管脚引入的外部通道。内部通道涉及到其他外设的,相关外设需要使能。
外部通道需要通过MCC 的管脚管理器配置。选择的管脚(如RB6, RC2)会设置为模拟通道。
由框图可知,通道由PCH<5:0>来选择。
4. 转换结果保存在ADRESH和ADRESL中。可选择左对齐或右对齐方式。
以上设置都是基于ADC工作在基本模式下的。从MCC下拉框可知,共有5种操作模式。下面简单看下其他的工作模式。
数据手册里找到对应解释。
基本模式就是普通的ADC转换器。其他模式是在ADC转换结果的基础上,加入了各种计算操作。以前需要软件做的平均和滤波操作现在都集成到ADCC硬件里了。模块的名字也从ADC升级到了ADCC,原来多出来的字母C是计算的意思。
MCC生成代码后。 初始化函数ADCC_Initialize(),通过寄存器操作,已经将操作模式,ADC时钟,参考电压,结果对齐方式等设置好。 void ADCC_Initialize(void) { …
// ADDSEN disabled; ADGPOL digital_low; ADIPEN disabled; ADPPOL Vss; ADCON1 = 0x00; // ADCRS 0; ADMD Basic_mode; ADACLR disabled; ADPSIS RES; ADCON2 = 0x00; // ADCALC First derivative of Single measurement; ADTMD disabled; ADSOIADGO not cleared; ADCON3 = 0x00; // ADMATH registers not updated; ADSTAT = 0x00; // ADNREF VSS; ADPREF VDD; ADREF = 0x00; // ADACT disabled; ADACT = 0x00; // ADCS FOSC/6; ADCLK = 0x02; // ADGO stop; ADFM right; ADON enabled; ADCS FOSC/ADCLK; ADCONTdisabled; ADCON0 = 0x84; }
因为在MCC界面上没有选择使用中断,生产的代码是以Polling 方式工作的。 开始转换 -> 查询是否转换完成 -> 如完成, 读取结果
开始转换,需要给定通道号。ADPCH寄存器设定通道。ADCON0中ADON开启ADC功能,ADGO设为1启动转换。需要注意的是,在选择通道之后,开启转换之前,有时候需要人为插入一下延迟,以避免外部通道输入电阻电容过大带来的影响。 void ADCC_StartConversion(adcc_channel_tchannel) { // select the A/D channel ADPCH = channel;
// Turn on the ADC module ADCON0bits.ADON = 1;
// Start the conversion ADCON0bits.ADGO = 1; }
检查转换是否完成。ADGO变低意味着转换完成。 bool ADCC_IsConversionDone() { // Start the conversion return ((unsigned char)(!ADCON0bits.ADGO)); }
读取结果,16位全部读出。然后用户程序需要根据结果对齐选择,来处理转换输出。 adc_result_t ADCC_GetConversionResult(void) { // Return the result return ((adc_result_t)((ADRESH << 8) + ADRESL)); }
除了以上分步处理外,还提供了一下单一函数完成一次转换。 adc_result_tADCC_GetSingleConversion(adcc_channel_t channel) { // select the A/D channel ADPCH = channel;
// Turn on the ADC module ADCON0bits.ADON = 1;
//Disable the continuous mode. ADCON0bits.ADCONT = 0;
// Start the conversion ADCON0bits.ADGO = 1;
// Wait for the conversion to finish while (ADCON0bits.ADGO) { }
// Conversion finished, return the result return ((adc_result_t)((ADRESH << 8) + ADRESL)); }
|
谢谢分享
那个小锁头打开和关闭到底是什么意思啊。