完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在网上看到的关于stm32的adc功能的例程,大多数是stmf103的,基于stm32f030的相当少。而我就是用stm32f030,在开发过程中,颇为遇到一些坑,所以总结一下。
本文关于ADC的内容,分为下面几部分: 1,ADC的初始化; 2,读取ADC值; 3,ADC值的解析; 先简单介绍下开发环境,芯片类型是stm32F030C8,集成开发环境用的是Keil5 MDK-ARM,仿真器使用JLINK。 一,ADC的初始化 ADC设置的一般步骤如下: 1、时钟配置,包括ADC时钟与GPIO时钟; 2、GPIO设置; 3、ADC参数配置; 4、中断的配置(若有必要就配置,本文未涉及)。 为了比较好对比读取数据的变化,我在这个函数中,考虑到了3种ADC数据源: 内部温度传感器,通道号为 ADC_Channel_16 内部参考电压,通道号为 ADC_Channel_17 一个gpio输入,PA5,通道号为 ADC_Channel_5 只需要在 ADC_ChannelConfig() 中指定好相应的ADC通道号即可。 内部温度传感器与内部参考电压,每个stm32芯片都支持,方便测试运行。 而对于gpio输出,就需要有相应的硬件支持了。否则,读取的值不知道意义。 ADC初始化的代码如下: void initADC(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; uint32_t adc_clk = RCC_ADCCLK_PCLK_Div4; log(“initADC: to GPIO_Configurationn”); /* Config System clocks, GPIO ports -----------------------------------------------------*/ RCC_ADCCLKConfig(adc_clk);//配置ADC的时钟频率 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;// GPIO_Init(GPIOA,&GPIO_InitStructure); /* Config ADC1 --------------------------------------------------------------*/ ADC_DeInit(ADC1); ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b;//ADC_Resolution_12b ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//不开启连续转换模式 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //不使用外部触发转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐 ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward; //扫描方向 ADC_Init(ADC1, &ADC_InitStructure); ADC_TempSensorCmd(ENABLE);//使能内部温度传感器 ADC_VrefintCmd(ENABLE); //使能内部参考电压 //按 频率=8/1/4=2M 来计算,t=(71.5+12.5)/2M=42us // ADC_ChannelConfig(ADC1, ADC_Channel_16, ADC_SampleTime_71_5Cycles);//内部温度传感器 ADC_ChannelConfig(ADC1, ADC_Channel_17, ADC_SampleTime_71_5Cycles);//内部参考电压 // ADC_ChannelConfig(ADC1, ADC_Channel_5, ADC_SampleTime_71_5Cycles);//配置ADC1通道5的采样周期 PA5 ADC_GetCalibrationFactor(ADC1);//Active the Calibration operation 返回校准因子 //The Calibration can be initiated only when ADC is still in the reset configuration (ADEN must be equal to 0)。 ADC_Cmd(ADC1,ENABLE);//ADEN set to 1 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); } 二,读取ADC值 本例程采用的是手动启动ADC,然后等待ADC转换完成,然后读取ADC值。 具体代码如下: void startADC(void) { uint16_t ADC_ConvertedValue=0; ADC_StartOfConversion(ADC1); while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=1){} //等待ADC转换完成 ADC_ConvertedValue = ADC_GetConversionValue(ADC1); log(“ADC_ConvertedValue=%drn”,ADC_ConvertedValue); ADC_StopOfConversion(ADC1); } 由于是一个demo例程,这里只关心了如何读取到值,具体这个值的意义,就需要另外来分析了。 三,ADC值的解析 这里分析了3种值得解析: 1,内部温度传感器,通道号为 ADC_Channel_16 由于我对精度并没有很高的期望,所以配置为8位精度,ADC_Resolution_8b 取值范围:0-255 利用下列公式得出温度 温度(°C) = {(V25 - VSENSE) / Avg_Slope} + 25 这里: V25 = VSENSE在25°C时的数值 Avg_Slope = 温度与VSENSE曲线的平均斜率(单位为mV/ °C 或 μV/ °C) 参考数据手册的电气特性章节中V25 和Avg_Slope的实际值。 vol = (float)adcx*(3.3/256); //电压值 temperate = (1.43-vol)/0.0043+25; //转换为温度值 2,内部参考电压,通道号为 ADC_Channel_17 取值范围:0-255,总共有256个取值 电压最大值对应3.3V 那么,计算公式就是: V=3.3*value/256 3,一个gpio输入,PA5,通道号为 ADC_Channel_5 如果是测量电压,则其与内部参考电压的计算是一样的; V=3.3*value/256 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1814 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1631 浏览 1 评论
1098 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
738 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1690 浏览 2 评论
1950浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
753浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
585浏览 3评论
604浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
568浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-29 19:36 , Processed in 0.871868 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号
|