STM32编写ADC功能,实现单路测量电压值(OLED显示) 您所在的位置:网站首页 个人怎么做量化交易赚钱 STM32编写ADC功能,实现单路测量电压值(OLED显示)

STM32编写ADC功能,实现单路测量电压值(OLED显示)

2024-06-14 09:43| 来源: 网络整理| 查看: 265

先来看看本次实验的结果吧: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文件:

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

MyADC.h文件:

#ifndef __MYADC_H #define __MYADC_H void MyADC_Init(void); uint16_t Get_val(void); #endif

主函数main.c文件:

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

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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有