当前位置:   article > 正文

STM32编写ADC功能,实现单路测量电压值(OLED显示)_stm32战舰v3 adc显示到oled

stm32战舰v3 adc显示到oled

先来看看本次实验的结果吧:stm32点电压测量范围为0-3.3V,数值为:0-4095

来看看这个工程的文件布局吧:

实现ADC功能总共分为六步:

第一步:开始RCC时钟,包括ADC和GPIO的时钟,ADCCLK的分频器也需要配置一下。

第二步:配置GPIO,把需要用的GPIO配置成模拟输入的模式

第三步:配置多路开关,把左边的通道接入规则组列表里

第四步:配置ADC转换器,用结构体配置,一大块的参数。

第五步:打开ADC_CMD()开启ADC。

第六步:校准ADC

接着来学习一下ADC相关的库函数:(看起来好像有点乱,后面有截图)

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2); 用来配置ADCCLK分频器的 void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); 这个是用来给ADC上电的函数 void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); 用来开启DMA输出信号的 void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); 中断输出控制 void ADC_ResetCalibration(ADC_TypeDef* ADCx); 复位校准 FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx); 获取复位校准状态 void ADC_StartCalibration(ADC_TypeDef* ADCx); 开始校准 FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx); 获取开始校准状态 void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); ADC软件开始转换控制 软件触发的函数 FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); ADC获取软件开始转换状态 FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); 获取转换完成标志位状态,判断EOC标志位是不是置1了。 void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); 间隔几个通道采集信

void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 是否启用间隔模式 void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); 规则组通道配置 void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); ADC 外部触发转换控制,就是是否允许外部触发转换 uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); ADC获取转换值 uint32_t ADC_GetDualModeConversionValue(void); ADC获取双模式转换值,这个是双ADC模式读取转换结果 void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);  //是否启动看门口 void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold); //配置高低阈值 void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); //配置看门的通道 配置模拟看门狗的三个函数 void ADC_TempSensorVrefintCmd(FunctionalState NewState);  //ADC温度传感器内部参考电压控制,用来开启内部通道 FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);  //获取标志位状态 void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);        // 清楚标志位状态 ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);     //获取中断状态 void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);   //清楚中断挂起位

接下来就是每个文件的源码了:

MyADC.c文件:

  1. #include "stm32f10x.h" // Device header
  2. void MyADC_Init(void)
  3. {
  4. //第一步:开始RCC时钟,包括ADC和GPIO的时钟,ADCCLK的分频器也需要配置一下。
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
  7. RCC_ADCCLKConfig(RCC_PCLK2_Div6); // ADC的时钟选择6分频,也就是72M/6=12M
  8. //第二步:配置GPIO,把需要用的GPIO配置成模拟输入的模式
  9. GPIO_InitTypeDef GPIO_InitStruct; //GPIO初始化的结构体
  10. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; // 模式为模拟输入
  11. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; // 初始化端口0
  12. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //端口频率50M
  13. GPIO_Init(GPIOA, &GPIO_InitStruct); // GPIOA初始化
  14. //第三步:配置多路开关,把左边的通道接入规则组列表里
  15. ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5); //ADC1规则配置(ADC1,通道1,列表1,转换时间28.5个时钟(12M))
  16. //第四步:配置ADC转换器,用结构体配置,一大块的参数。
  17. ADC_InitTypeDef ADC_InitStruct; //ADC初始化结构体
  18. ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; //连续转换模式:关闭
  19. ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; // 数据对齐:右对齐
  20. ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ADC中断触发:空,也就是软件触发
  21. ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; // ADC模式:独立模式
  22. ADC_InitStruct.ADC_NbrOfChannel = 1; //规则组中的通道数:1
  23. ADC_InitStruct.ADC_ScanConvMode = DISABLE; //扫描模式:关闭
  24. ADC_Init(ADC1, &ADC_InitStruct); //ADC初始化
  25. //第五步:打开ADC_CMD()开启ADC。
  26. ADC_Cmd(ADC1, ENABLE); // ADC开启
  27. //第六步:校准ADC
  28. ADC_ResetCalibration(ADC1); // 复位校准ADC
  29. while(ADC_GetResetCalibrationStatus(ADC1) == SET); // 等待校准标志位置0
  30. ADC_StartCalibration(ADC1); // 开始复位校准ADC
  31. while(ADC_GetCalibrationStatus(ADC1) == SET); // 等待开始校准结束标志位置0
  32. }
  33. uint16_t Get_val(void)
  34. {
  35. ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 软件触发ADC使能
  36. while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); // 等待获取EOC标志位置1
  37. return ADC_GetConversionValue(ADC1); // 返回ADC转换的结果值
  38. }

MyADC.h文件:

  1. #ifndef __MYADC_H
  2. #define __MYADC_H
  3. void MyADC_Init(void);
  4. uint16_t Get_val(void);
  5. #endif

主函数main.c文件:

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. #include "AD.h"
  5. uint16_t ADValue; //定义AD值变量
  6. float Voltage; //定义电压变量
  7. int main(void)
  8. {
  9. /*模块初始化*/
  10. OLED_Init(); //OLED初始化
  11. AD_Init(); //AD初始化
  12. /*显示静态字符串*/
  13. OLED_ShowString(1, 1, "ADValue:");
  14. OLED_ShowString(2, 1, "Voltage:0.00V");
  15. while (1)
  16. {
  17. ADValue = AD_GetValue(); //获取AD转换的值
  18. Voltage = (float)ADValue / 4095 * 3.3; //将AD值线性变换到0~3.3的范围,表示电压
  19. OLED_ShowNum(1, 9, ADValue, 4); //显示AD值
  20. OLED_ShowNum(2, 9, Voltage, 1); //显示电压值的整数部分
  21. OLED_ShowNum(2, 11, (uint16_t)(Voltage * 100) % 100, 2); //显示电压值的小数部分
  22. Delay_ms(100); //延时100ms,手动增加一些转换的间隔时间
  23. }
  24. }

还有一个OLED的代码就不展示了,没有的可以在之前的博文中找到,都有公布过,自己挨片的看就能找到的,编译后写入到STM32中就能看到实验结果了,调整电位器就能看到电压和数值的变化,电位器中间抽头接A0,另外两个头中的一个接3.3V电源,这就是整个的接线图了。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号