1.概述
小华HC32F448搭载3个ADC单元,单元1支持16个通道,单元2支持8个通道,单元3支持12个通道,可以转换来自外部引脚、以及芯片内部的模拟信号。ADC转换支持A、B两组扫描序列,每个序列都支持单次扫描模式、连续扫描模式、数据缓冲模式、以及双序列扫描模式,另外HC32F488的ADC还支持模拟看门狗功能、转换数据平均计算功能、过采样功能、以及多ADC协同工作模式。
2.序列
HC32F448支持A、B两组扫描序列,讲真,这是我第一次接触到这个概念;之前都是接触的MCU有几个ADC单元、哪个ADC单元有几个ADC通道这些说法;结合使用过的其它国产MCU,再想想……其中有一款国产芯片中有提到过一个说法,叫普通通道转换和任意通道转换,其中任意通道模式的概念感觉和小华这个序列的概念很像,再细细研读小华的UM手册,感觉很强大哈!它相当于带了2组任意通道转换的功能哎……每个序列都可以由用户根据实际应用来指定,对序列的扫描模式、序列间的优先级描述、图示都很到位,一直子就看明白了。
3.转换数据平均计算功能
这个功能很强大哈!!!使用平均计算功能可以去除一定的噪声干扰,使转换结果更准确、更稳定啊。UM手册对这个功能的描述比较少,但通过图示,可以很清楚的理解这一功能的用法和强大之处!
4.过采样
过采样的功能是通过配置选择任意一个或多个需要过采样的通道,使AD进入过采样模式,在该模式下,通过连续多次采样转换和结果移位,得到16bit精度的转换结果。额……UM手册上就是这么描述的,也没图示……感觉的平均计算功能差不多呢?感觉平均功能就是序列中需要平均的通道配置一下,过采样呢就是序列中所有的通道都是使用平均计算的功能,具体的效果还是通过例程实验感受一下吧。
5.转换数据平均计算和过采样示例
5.1.配置程序
#define ADC_UNIT (CM_ADC1)
#define ADC_PERIPH_CLK (FCG3_PERIPH_ADC1)
#define ADC_CH_POTENTIOMETER (ADC_CH10)
#define ADC_CH (ADC_CH_POTENTIOMETER)
#define ADC_CH_PORT (GPIO_PORT_C)
#define ADC_CH_PIN (GPIO_PIN_00)
#define ADC_SEQ (ADC_SEQ_A)
#define ADC_EOC_FLAG (ADC_FLAG_EOCA)
#define ADC_VREF (3.3F)
#define ADC_ACCURACY (1UL << 16U)
#define ADC_CAL_VOL(adcVal) (uint16_t)((((float32_t)(adcVal) * ADC_VREF) / ((float32_t)ADC_ACCURACY)) * 1000.F)
#define ADC_TIMEOUT_VAL (1000U)
static void ADC_InitGPIO(void)
{
stc_gpio_init_t stcGpioInit;
(void)GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
(void)GPIO_Init(ADC_CH_PORT, ADC_CH_PIN, &stcGpioInit);
}
static void ADC_Configuration(void)
{
stc_adc_init_t stcAdcInit;
/* 1. Enable ADC peripheral clock. */
FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE);
/* 2. Modify the default value depends on the application. Not needed here. */
(void)ADC_StructInit(&stcAdcInit);
/* 3. Initializes ADC. */
(void)ADC_Init(ADC_UNIT, &stcAdcInit);
/* 4. ADC channel configuration. */
/* 4.1 Set the ADC pin to analog input mode. */
ADC_InitGPIO();
/* 4.2 Enable ADC channels. Call ADC_ChCmd() again to enable more channels if needed. */
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CH, ENABLE);
/* 5. Conversion data average calculation function, if needed.
Call ADC_ConvDataAverageChCmd() again to enable more average channels if needed. */
ADC_ConvDataAverageConfig(ADC_UNIT, ADC_AVG_CNT64);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CH, ENABLE);
/* 6. Ser over sample mode and right shift number */
ADC_SetSampleMode(ADC_UNIT, ADC_SAMPLE_MD_OVER);
ADC_SetOverSampleShift(ADC_UNIT, ADC_OVER_SAMPLE_SHIFT_2BIT);
}
static void ADC_Polling(void)
{
uint16_t u16AdcValue;
int32_t iRet = LL_ERR;
__IO uint32_t u32TimeCount = 0UL;
/* Can ONLY start sequence A conversion.
Sequence B needs hardware trigger to start conversion. */
ADC_Start(ADC_UNIT);
do
{
if (ADC_GetStatus(ADC_UNIT, ADC_EOC_FLAG) == SET)
{
ADC_ClearStatus(ADC_UNIT, ADC_EOC_FLAG);
iRet = LL_OK;
break;
}
}
while (u32TimeCount++ < ADC_TIMEOUT_VAL);
if (iRet == LL_OK)
{
/* Get any ADC value of sequence A channel that needed. */
u16AdcValue = ADC_GetValue(ADC_UNIT, ADC_CH);
DDL_Printf("The ADC value of potentiometer is %u, voltage is %u mV\r\n", u16AdcValue, ADC_CAL_VOL(u16AdcValue));
}
else
{
ADC_Stop(ADC_UNIT);
DDL_Printf("ADC exception.\r\n");
}
}
int32_t main(void)
{
/* Register write enable for some required peripherals. */
LL_PERIPH_WE(LL_PERIPH_ALL);
/* Initialize BSP system clock. */
BSP_CLK_Init();
/* Initializes UART for debug printing. Baudrate is 115200. */
DDL_PrintfInit(BSP_PRINTF_DEVICE, 115200UL, BSP_PRINTF_Preinit);
/* LED initialize */
LED_Init();
/* Configures ADC. */
ADC_Configuration();
/* Register write protected for some required peripherals. */
LL_PERIPH_WP(LL_PERIPH_ALL);
stc_clock_freq_t stc_clock_freq;
CLK_GetClockFreq(&stc_clock_freq);
DDL_Printf("\r\n");
DDL_Printf("\r\nEV_F448_LQ80_Rev1.0 %s %s", __DATE__, __TIME__);
DDL_Printf("\r\nSYSCLK Frequency : %7.3f MHz", (double)stc_clock_freq.u32SysclkFreq / (double)1000000.0);
DDL_Printf("\r\nHCLK Frequency : %7.3f MHz", (double)stc_clock_freq.u32HclkFreq / (double)1000000.0);
DDL_Printf("\r\nPCLK0 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk0Freq / (double)1000000.0);
DDL_Printf("\r\nPCLK1 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk1Freq / (double)1000000.0);
DDL_Printf("\r\nPCLK2 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk2Freq / (double)1000000.0);
DDL_Printf("\r\nPCLK3 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk3Freq / (double)1000000.0);
DDL_Printf("\r\nPCLK4 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk4Freq / (double)1000000.0);
DDL_Printf("\r\nEXCLK Frequency : %7.3f MHz", (double)stc_clock_freq.u32ExclkFreq / (double)1000000.0);
DDL_Printf("\r\n");
for ( ;; )
{
LED_G_TOGGLE();
ADC_Polling();
DDL_DelayMS(500);
}
}
5.2.运行结果
6.程序附件
替换HC32F448_DDL_Rev1.1.0\projects\ev_hc32f448_lqfp80目录下的template目录内容即可