【NUCLEO-L496ZG评测】评测5:过采样ADC
本帖最后由 wenyangzeng 于 2018-10-30 16:35 编辑【NUCLEO-L469ZG评测】评测1:编译环境建立
【NUCLEO-L469ZG评测】评测2:Coremark跑分
【NUCLEO-L469ZG评测】评测3:低功耗测试
【NUCLEO-L469ZG评测】评测4:USB_FS_OTG
【NUCLEO-L496ZG评测】评测5:过采样ADC
【NUCLEO-L496ZG评测】评测6:可编程运放PGA
STM32L496的又一个亮点是具有过采样ADC功能。
通过配置最大过采样率(ADC_OVERSAMPLING_RATIO_128)其ADC转换结果为0xFFF * 128 = 0x7FF80,居然可以达到19位的精度。
硬件连接:
电位器连接开发板的A_VDD和A_GND,抽头接PA4(ADC_CHANNEL_9),PC8-PC11用于驱动OLED屏显示转换结果。
软件:
在STM32Cube_FW_L4_V1.7.0\Projects\STM32L496ZG-Nucleo\Examples\ADC\ADC_OverSampler提供了过采样ADC的演示软件包。可以直接应用,在工程中添加了OLED.C文件。在main()函数中添加调用OLED显示的函数。
#include "main.h"
#include "OLED.h"
ADC_HandleTypeDef AdcHandle;
ADC_ChannelConfTypeDef sConfig;
uint32_t uwConvertedValue;
uint32_t uwInputVoltage;
void SystemClock_Config(void);
static void Error_Handler(void);
uint8_t disp_buf;
int main(void)
{
HAL_Init();
SystemClock_Config();
BSP_LED_Init(LED1);
OLED_Init();
OLED_Print(0, 0,"STM32L469ZG",TYPE16X16,TYPE8X16);
OLED_Print(0, 16, "ADC_OVERSAMPLING",TYPE16X16,TYPE8X16);
AdcHandle.Instance = ADCx;
if (HAL_ADC_DeInit(&AdcHandle) != HAL_OK)
{
Error_Handler();
}
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.ScanConvMode = DISABLE;
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
AdcHandle.Init.LowPowerAutoWait = DISABLE;
AdcHandle.Init.ContinuousConvMode = ENABLE;restart after each conversion) */
AdcHandle.Init.NbrOfConversion = 1;
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
AdcHandle.Init.NbrOfDiscConversion = 1;
AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
AdcHandle.Init.ExternalTrigConvEdge= ADC_EXTERNALTRIGCONVEDGE_NONE;
AdcHandle.Init.DMAContinuousRequests = DISABLE;
AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
AdcHandle.Init.OversamplingMode = ENABLE;
AdcHandle.Init.Oversampling.Ratio = OVERSAMPLING_RATIO;
AdcHandle.Init.Oversampling.RightBitShift = RIGHTBITSHIFT;
AdcHandle.Init.Oversampling.TriggeredMode = TRIGGEREDMODE;
AdcHandle.Init.Oversampling.OversamplingStopReset = OVERSAMPLINGSTOPRESET;
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADCx_CHANNEL;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start(&AdcHandle) != HAL_OK)
{
Error_Handler();
}
while (1)
{
if (HAL_ADC_PollForConversion(&AdcHandle, 10) != HAL_OK)
{
Error_Handler();
}
uwConvertedValue = HAL_ADC_GetValue(&AdcHandle);
uwInputVoltage = uwConvertedValue * 3300;
uwInputVoltage = uwInputVoltage / 0xFFF0;
disp_buf=uwInputVoltage%10000/1000+0x30;
disp_buf='.';
disp_buf=uwInputVoltage%1000/100+0x30;
disp_buf=uwInputVoltage%100/10+0x30;
disp_buf=uwInputVoltage%10+0x30;
disp_buf=' ';
disp_buf='V';
OLED_Print(36, 40, disp_buf,TYPE16X16,TYPE8X16);
}
}
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLP = 7;
RCC_OscInitStruct.PLL.PLLQ = 4;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
while(1);
}
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
while(1);
}
}
static void Error_Handler(void)
{
BSP_LED_On(LED1);
while (1)
{
}
}编译下载运行.
http://player.youku.com/player.php/sid/XMjY5MTE3NTg2NA==/v.swf
https://v.youku.com/v_show/id_XMjY5MTE3NTg2NA==.html?spm=a2hzp.8253869.0.0
注:读数出现变化时是因为正在调整电位器
运行结果令人满意,本评测的ADC转换电压范围是0.000-3.300V,分辨率为1mV,ADC转换结果未作任何滤波处理,当电位器调整到某个位置不动后,读数最后一位数居然纹丝不动。可见该方案的ADC转换结果具有极高的分辨率和信噪比,如果用于数字表头产品是非常优秀的选择。
不错,很给力!~ strang 发表于 2017-4-7 16:30
不错,很给力!~
谢谢支持 很强大且实用的一项功能,以后留意一下,本来想买16位的采集模块 anywill 发表于 2017-4-8 12:24
很强大且实用的一项功能,以后留意一下,本来想买16位的采集模块
这个系列芯片的这个功能应该是可以考虑选择的。 过采样DMA传输函数是哪个呢? 楼主视频好像打不开了,能否再传一份? 本帖最后由 wenyangzeng 于 2018-10-30 16:27 编辑
yl19960531 发表于 2018-10-30 14:48
楼主视频好像打不开了,能否再传一份?好像是社区网页的问题,破总能否帮助解决一下。@zero99
本帖最后由 wenyangzeng 于 2018-10-30 16:33 编辑
yl19960531 发表于 2018-10-30 14:48
楼主视频好像打不开了,能否再传一份?https://v.youku.com/v_show/id_XMjY5MTE3NTg2NA==.html?spm=a2hzp.8253869.0.0
请问这个采样频率是多少?辛苦楼主了
页:
[1]
2