【 STM32WB55 测评】7# STM32WB开发板ADC的使用和配置
<div class='showpostmsg'> 本帖最后由 北方 于 2019-5-16 11:32 编辑1. ADC的使用和配置STM32WB55标称ADC的精度达到16位,这个是一个专用ADC芯片所能达到的标准。不过,再其文档中,只是提到能达到12位的精度。因此这里面还是有些差异的,应该是用其他方法达到的16位。
总共的19个通道,其中有3个事内部使用的,分别的hi温度,电池电压,和参考电压,对应于不同的地址。
ADC还有一个有意思的watchdog功能,可以实现ADC超过范围时的闭锁功能。低功耗ADC是STM32的传统,这里仍然保留。
2. 主要特性
- 12,10,8,6bit的设置精度,
- 转换时间,0.234us --12bit,或者0.297us--12bit,更低的精度如10位可以达到0.203us。
- 数据自我矫正,这个就减少了一个需要calibration的功能。
- oversampler,这个可以取样16位,但是应该是硬件仍然12位
具体结构参考下图,
具体时钟逻辑图,
3. 例程分析
3.1 连接开发板的arduino-A2接口,对应ADC_CHANNEL_6,这样可以显示其中连接在A2的电压变化
3.2 核心代码如下,
int main(void)
{
uint32_t tmp_index_adc_converted_data = 0;
HAL_Init();
SystemClock_Config();
MX_TIM2_Init();
for (tmp_index_adc_converted_data = 0; tmp_index_adc_converted_data < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index_adc_converted_data++)
{
aADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE;
}
BSP_LED_Init(LED2);
Configure_ADC();
/* Run the ADC calibration in single-ended mode */
if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK)
{
/* Calibration Error */
Error_Handler();
}
if (HAL_TIM_Base_Start(&htim2) != HAL_OK)
{
/* Counter enable error */
Error_Handler();
}
/* Start ADC group regular conversion with DMA */
if (HAL_ADC_Start_DMA(&AdcHandle,
(uint32_t *)aADCxConvertedData,
ADC_CONVERTED_DATA_BUFFER_SIZE
) != HAL_OK)
{
/* ADC conversion start error */
Error_Handler();
}
while (1)
{
}
}
3.3 代码简析
首先,初始化硬件,设定系统时钟和外设设定,
HAL_Init();
SystemClock_Config();
MX_TIM2_Init();
然后设置ADC
Configure_ADC();
最后就是启动DMA状态下的ADC,
HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);
HAL_TIM_Base_Start(&htim2);
HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE);
3.4 ADC 的设置
对应ADC的设置,是在config中确定的,如下代码,这个设定了用户手册中需要设定的时钟,精度,通道,矫正方式等,虽然内容很多,但是,注解和使用很直观,
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.ScanConvMode = ADC_SCAN_DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
AdcHandle.Init.LowPowerAutoWait = DISABLE;
AdcHandle.Init.ContinuousConvMode = ENABLE; /* Continuous mode to have maximum conversion speed (no delay between conversions) */
AdcHandle.Init.NbrOfConversion = 1; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.NbrOfDiscConversion = 1; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */
AdcHandle.Init.ExternalTrigConvEdge= ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because trig of conversion by software start (no external event) */
AdcHandle.Init.DMAContinuousRequests = ENABLE; /* ADC with DMA transfer: continuous requests to DMA to match with DMA configured in circular mode */
AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
AdcHandle.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
/* ADC initialization error */
Error_Handler();
}
/*## Configuration of ADC hierarchical scope: ##############################*/
/*## ADC group injected and channels mapped on group injected ##############*/
/* Note: ADC group injected not used and not configured in this example. */
/* Refer to other ADC examples using this feature. */
/* Note: Call of the functions below are commented because they are */
/* useless in this example: */
/* setting corresponding to default configuration from reset state. */
/*## Configuration of ADC hierarchical scope: ##############################*/
/*## channels mapped on group regular ##############################*/
/* Configuration of channel on ADCx regular group on sequencer rank 1 */
/* Note: On this STM32 serie, ADC group regular sequencer is */
/* fully configurable: sequencer length and each rank */
/* affectation to a channel are configurable. */
/* Note: Considering IT occurring after each ADC conversion */
/* (IT by ADC group regular end of unitary conversion), */
/* select sampling time and ADC clock with sufficient */
/* duration to not create an overhead situation in IRQHandler. */
sConfig.Channel = ADCx_CHANNELa; /* ADC channel selection */
sConfig.Rank = ADC_REGULAR_RANK_1; /* ADC group regular rank in which is mapped the selected ADC channel */
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;/* ADC channel sampling time */
sConfig.SingleDiff = ADC_SINGLE_ENDED; /* ADC channel differential mode */
sConfig.OffsetNumber = ADC_OFFSET_NONE; /* ADC channel affected to offset number */
sConfig.Offset = 0; /* Parameter discarded because offset correction is disabled */
此内容由EEWORLD论坛网友北方原创,如需转载或用于商业用途需征得作者同意并注明出处
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页:
[1]