本文主要是介绍stm32学习-AD单通道,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
配置流程
初始化
1.开启RCC时钟(ADC、GPIO和ADCCLK的预分频器的时钟)
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);
作用:配置预分频器系数。(可以对APB2的72MHz时钟选择2/4/6/8分频,输入到ADCCLK中)
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
作用:外设时钟控制(根据外设连接的总线选择要开启的时钟)
RCC_AHBPeriph/RCC_APB2Periph/RCC_APB1Periph:选择外设
NewState:使能/使能
2.配置GPIO(把需要的GPIO配置为模拟输入的模式)
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
作用:用结构体的参数初始化GPIO。
用法:先定义一个结构体变量,再给变量赋值,最后调用这个函数即可(这个函数就会自动读取结构体的值,然后自动把外设的各个参数配置好)。
3.配置多路开关(把左边通道接到后边的规则组列表里)
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
作用:ADC规则组通道配置
ADCx:选择的ADC外设
ADC_Channel:指定ADC通道
Rank:序列几的位置
ADC_SampleTime:指定通道的采样时间
4.配置ADC转换器和AD数据寄存器
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
作用:用结构体的参数初始化ADC。
(如果需要模拟看门狗的话,可以通过库函数配置阈值和监测通道;如果想开启中断,就在中断输出控制里用ITConfig函数开启对应的中断输出,然后在NVIC里配置优先级,就可以触发中断了)
我们本篇先不需要配置看门狗和中断
5.开启ADC
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
作用:开启ADC
6.校准
(根据手册要求,在配置完后我们需要对其进行校准)
void ADC_ResetCalibration(ADC_TypeDef* ADCx);
作用:复位校准
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);
作用:获取复位校准状态
void ADC_StartCalibration(ADC_TypeDef* ADCx);
作用:开始校准
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);
作用:获取开始校准状态
获取AD值
流程:
1.软件触发转换
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
作用:ADC软件开始转换状态(用于软件触发)
2.等待转换完成(EOC标志位置1)
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
作用:获取标志位状态
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
作用:清除标志位状态
获取EOC的标志位,判断是否置1
3.读取ADC数据寄存器
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
作用:ADC获取转换值(获取AD转换的数据寄存器,读取转换结果就需要使用这个库函数)
代码
AD.c
#include "stm32f10x.h" // Device headervoid AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);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);ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);ADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1) == SET);
}uint16_t AD_GetValue(void)
{ADC_SoftwareStartConvCmd(ADC1, ENABLE);while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);return ADC_GetConversionValue(ADC1);
}
AD.h
#ifndef __AD_H
#define __AD_Hvoid AD_Init(void);
uint16_t AD_GetValue(void);#endif
例题
通过电位器调节电压,调节后的AD值和电压值显示在OLED上。
接线
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"uint16_t ADValue;
float Voltage;int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1, 1, "ADValue:");OLED_ShowString(2, 1, "Volatge:0.00V");while (1){ADValue = AD_GetValue();Voltage = (float)ADValue / 4095 * 3.3;OLED_ShowNum(1, 9, ADValue, 4);OLED_ShowNum(2, 9, Voltage, 1);OLED_ShowNum(2, 11, (uint16_t)(Voltage * 100) % 100, 2);Delay_ms(100);}
}
其他重要库函数
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);
作用:开启DMA输出信号(如果使用DMA转运数据,就得调用这个函数)
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
作用:中断输出控制(用于控制某个中断能不能通往NVIC)
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);
作用:获取软件开始转换状态(一般不用)
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
作用:配置间断模式(ADC_DiscModeChannelCountConfig是每隔几个通道间断一次;ADC_DiscModeCmd函数是确定要不要启用间断模式)
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
作用: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温度传感器内部电压控制(用于开启内部的两个通道)
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);
作用:获取中断状态
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);
作用:清除中断挂起位
有什么问题欢迎在评论区里提出来
这篇关于stm32学习-AD单通道的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!