一元云购网站开发,河北建设厅网站首页,seo 海外,河南省建设劳动学会网站文章目录
1. STM32单片机ADC功能详解
2. AD单通道
2.1 初始化
2.2 ADC.c
2.3 ADC.h
2.4 main.c
3. AD多通道
3.1 ADC.c
3.2 ADC.h
3.3 main.c
3.4 完整工程文件 1. STM32单片机ADC功能详解
STM32单片机ADC功能详解 2. AD单通道
这个代码实现通过ADC功能采集三脚电…文章目录
1. STM32单片机ADC功能详解
2. AD单通道
2.1 初始化
2.2 ADC.c
2.3 ADC.h
2.4 main.c
3. AD多通道
3.1 ADC.c
3.2 ADC.h
3.3 main.c
3.4 完整工程文件 1. STM32单片机ADC功能详解
STM32单片机ADC功能详解 2. AD单通道
这个代码实现通过ADC功能采集三脚电位器的数据并将数据在OLED上显示单片机为STM32F103C8T6。
2.1 初始化
对于配置ADCclk所使用的函数在stm32f10x_rcc.h中的最下面可以找到。
对于配置ADC所需要使用的函数在stm32f10x_adc.h中的最下面可以找到。 首先要进行ADC初始化函数的编写参考框架图
第一步为开启RCC时钟包括ADC和GPIO的时钟并且ADCCLK的分频器也需要配置一下第二步配置GPIO将需要使用的引脚配置为模拟输入模式第三步配置多路开关将输入通道接入到规则组列表。在库函数中使用结构体去配置参数包括ADC是单次转换还是连续转换扫描模式还是非扫描模式使用几个通道触发源数据采用左对齐还是右对齐。第四步如果需要使用看门狗就需要使用函数来配置阈值和检测通道如果需要使用中断就需要使用ITconfig函数来开启对应的中断输出。然后在NVIC中配置优先级就可以触发中断了。第五步调用ADC_Cmd函数开启ADC。 2.2 ADC.c
因为只使用一个通道所以采用非扫描模式。
#include stm32f10x.h //AD初始化
void AD_Init(void)
{//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟//设置ADC时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6); //选择时钟6分频ADCCLK 72MHz / 6 12MHz//GPIO初始化GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure); //将PA0引脚初始化为模拟输入//规则组通道配置ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); //规则组序列1的位置配置为通道0//ADC初始化ADC_InitTypeDef ADC_InitStructure; //定义结构体变量ADC_InitStructure.ADC_Mode ADC_Mode_Independent; //模式选择独立模式即单独使用ADC1ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right; //数据对齐选择右对齐ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; //外部触发使用软件触发不需要外部触发ADC_InitStructure.ADC_ContinuousConvMode DISABLE; //连续转换失能每转换一次规则组序列后停止ADC_InitStructure.ADC_ScanConvMode DISABLE; //扫描模式失能只转换规则组的序列1这一个位置ADC_InitStructure.ADC_NbrOfChannel 1; //通道数为1仅在扫描模式下才需要指定大于1的数在非扫描模式下只能是1ADC_Init(ADC1, ADC_InitStructure); //将结构体变量交给ADC_Init配置ADC1//ADC使能ADC_Cmd(ADC1, ENABLE); //使能ADC1ADC开始运行//ADC校准ADC_ResetCalibration(ADC1); //固定流程内部有电路会自动执行校准while (ADC_GetResetCalibrationStatus(ADC1) SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1) SET);
}//获取AD转换的值
uint16_t AD_GetValue(void)
{ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发AD转换一次while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) RESET); //等待EOC标志位即等待AD转换结束return ADC_GetConversionValue(ADC1); //读数据寄存器得到AD转换的结果
}2.3 ADC.h
接着是ADC.h文件这部分引用声明一下即可
#ifndef __AD_H
#define __AD_Hvoid AD_Init(void);
uint16_t AD_GetValue(void);#endif2.4 main.c
#include stm32f10x.h
#include Delay.h
#include OLED.h
#include AD.huint16_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手动增加一些转换的间隔时间}
}3. AD多通道
这个代码实现通过ADC功能采集多个传感器和电位器的数据并将数据在OLED上显示单片机为STM32F103C8T6传感器为光敏传感器热敏传感器反射式红外传感器电位器采用三脚电位器均连接AO引脚代表模拟量输入。
这里依然使用非扫描模式只需要在每次触发转换之前手动更改列表第一个位置的通道。比如第一次转换写入通道0触发并且读值后在第二次转换时改为通道1。
3.1 ADC.c
对比单通道的代表将填充通道的函数代码ADC_RegularChannelConfig放到AD_GetValue中在触发转换之前重新填充通道。
#include stm32f10x.h //AD初始化
void AD_Init(void)
{//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟//设置ADC时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6); //选择时钟6分频ADCCLK 72MHz / 6 12MHz//GPIO初始化GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure); //将PA0、PA1、PA2和PA3引脚初始化为模拟输入//不在此处配置规则组序列而是在每次AD转换前配置这样可以灵活更改AD转换的通道//ADC初始化ADC_InitTypeDef ADC_InitStructure; //定义结构体变量ADC_InitStructure.ADC_Mode ADC_Mode_Independent; //模式选择独立模式即单独使用ADC1ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right; //数据对齐选择右对齐ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; //外部触发使用软件触发不需要外部触发ADC_InitStructure.ADC_ContinuousConvMode DISABLE; //连续转换失能每转换一次规则组序列后停止ADC_InitStructure.ADC_ScanConvMode DISABLE; //扫描模式失能只转换规则组的序列1这一个位置ADC_InitStructure.ADC_NbrOfChannel 1; //通道数为1仅在扫描模式下才需要指定大于1的数在非扫描模式下只能是1ADC_Init(ADC1, ADC_InitStructure); //将结构体变量交给ADC_Init配置ADC1//ADC使能ADC_Cmd(ADC1, ENABLE); //使能ADC1ADC开始运行/*ADC校准*/ADC_ResetCalibration(ADC1); //固定流程内部有电路会自动执行校准while (ADC_GetResetCalibrationStatus(ADC1) SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1) SET);
}//获取AD转换的值
uint16_t AD_GetValue(uint8_t ADC_Channel)
{ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5); //在每次转换前根据函数形参灵活更改规则组的通道1ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发AD转换一次while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) RESET); //等待EOC标志位即等待AD转换结束return ADC_GetConversionValue(ADC1); //读数据寄存器得到AD转换的结果
}3.2 ADC.h
#ifndef __AD_H
#define __AD_Hvoid AD_Init(void);
uint16_t AD_GetValue(uint8_t ADC_Channel);#endif3.3 main.c
#include stm32f10x.h
#include Delay.h
#include OLED.h
#include AD.huint16_t AD0, AD1, AD2, AD3; //定义AD值变量int main(void)
{//模块初始化OLED_Init(); //OLED初始化AD_Init(); //AD初始化//显示静态字符串OLED_ShowString(1, 1, AD0:);OLED_ShowString(2, 1, AD1:);OLED_ShowString(3, 1, AD2:);OLED_ShowString(4, 1, AD3:);while (1){AD0 AD_GetValue(ADC_Channel_0); //单次启动ADC转换通道0AD1 AD_GetValue(ADC_Channel_1); //单次启动ADC转换通道1AD2 AD_GetValue(ADC_Channel_2); //单次启动ADC转换通道2AD3 AD_GetValue(ADC_Channel_3); //单次启动ADC转换通道3OLED_ShowNum(1, 5, AD0, 4); //显示通道0的转换结果AD0OLED_ShowNum(2, 5, AD1, 4); //显示通道1的转换结果AD1OLED_ShowNum(3, 5, AD2, 4); //显示通道2的转换结果AD2OLED_ShowNum(4, 5, AD3, 4); //显示通道3的转换结果AD3Delay_ms(100); //延时100ms手动增加一些转换的间隔时间}
}3.4 完整工程文件
STM32通过ADC单通道检测数据
STM32通过ADC多通道检测数据