广州空港经济区门户网站,大连做网站孙晓龙,2021世界500强,北京seo做排名028 - STM32学习笔记 - 结构体学习#xff08;二#xff09; 上节对ADC基础知识进行了学习#xff0c;这节在了解一下ADC相关的结构体。
一、ADC初始化结构体
在标准库函数中基本上对于外设都有一个初始化结构体xx_InitTypeDef#xff08;其中xx为外设名#xff0c;例如…028 - STM32学习笔记 - 结构体学习二 上节对ADC基础知识进行了学习这节在了解一下ADC相关的结构体。
一、ADC初始化结构体
在标准库函数中基本上对于外设都有一个初始化结构体xx_InitTypeDef其中xx为外设名例如之前使用过的GPIO_InitTypeDef结构体成员用来设置外设的工作模式通过标准库函数xx_Init()调用将这些设定的参数送入外摄对应的寄存器。
对于ADC来说也是这样的操作先看一下ADC_InitTypeDef结构体的定义
ADC_InitTypeDef结构体
typedef struct {uint32_t ADC_Resolution; //设置ADC分辨率选择FunctionalState ADC_ScanConvMode; //设置ADC扫描选择FunctionalState ADC_ContinuousConvMode; //设置ADC连续转换模式选择uint32_t ADC_ExternalTrigConvEdge; //设置ADC外部触发极性uint32_t ADC_ExternalTrigConv; //设置ADC外部触发选择uint32_t ADC_DataAlign; //设置输出数据对齐方式uint8_t ADC_NbrOfChannel; //设置转换通道数目
} ADC_InitTypeDef;ADC_Resolution用于配置ADC的分辨率可选的分辨率有12 位、10 位、8 位和 6 位。分辨率越高 AD转换数据精度越高转换时间也越长分辨率越低AD转换数据精度越低转换时间也越短。
ADC_Resolution_12b //12位精度
ADC_Resolution_10b //10位精度
ADC_Resolution_8b //8位精度c
ADC_Resolution_6b //6位精度ADC_ScanConvMode该成员主要用于配置ADC是否使用扫描可选参数为ENABLE和DISABLE如果只用到一个通道配置为DISABLE如果时多个通道则选择ENABLE。
ADC_ContinuousConvMode用于配置启动自动连续转换还是单次转换可选参数为ENABLE连续转换和DISABLE单次转换。如果选择为单次转换那么每次转换完成后都需要手动控制才能重新启动转换。
ADC_ExternalTrigConvEdge设置外部触发极性如果使用外部触发可选有
ADC_ExternalTrigConvEdge_None //禁止触发检测
ADC_ExternalTrigConvEdge_Rising //上升沿触发检测
ADC_ExternalTrigConvEdge_Falling //下降沿触发检测
ADC_ExternalTrigConvEdge_RisingFalling //上升下降沿均检测ADC_ExternalTrigConv外部触发模式选择可选的触发条件如下图-4常用的一般使用软件自动触发 ADC_DataAlign设置转换结果数据对其模式可选有右对齐ADC_DataAlign_Right或者左对齐ADC_DataAlign_Left这里我们选择右对齐。
ADC_NbrOfChannel设置AD转换通道数目。
ADC_CommonInitTypeDef结构体
除了ADC_InitTypeDef初始化结构体外还有ADC_CommonInitTypeDef通用初始化结构ADC_CommonInitTypeDef结构体内容决定了三个ADC共用的工作环境。
typedef struct{uint32_t ADC_Mode; //ADC模式选择uint32_t ADC_Prescaler; //ADC分频系数uint32_t ADC_DMAAccessMode; //DMA模式配置uint32_t ADC_TwoSamplingDelay; //采样延迟
}ADC_CommonInitTypeDef;ADC_ModeADC工作模式选择在前面有学习过有独立模式、双重模式以及三重模式
ADC_PrescalerADC时钟分频系数选择ADC时钟是由PCLK2分频而来分频系数决定ADC时钟频率可选的分频系数位2、4、6和8在之前也学习过ADC的最大时钟配置为36MHz。
ADC_DMAAccessModeDMA模式设置在双重或者三重模式下才需要设置可以设置三种模式分别为
ADC_DMAAccessMode_Disabled //独立模式下选择
ADC_DMAAccessMode_1 //模式1
ADC_DMAAccessMode_2 //模式2
ADC_DMAAccessMode_3 //模式3ADC_TwoSamplingDelay2个采样阶段之前的延迟仅适用于双重或三重交错模式。
二、独立模式单通道采集实验
在F429实验板上提供了一个板载贴片滑动变阻器供我们调试ADC时使用原理图如下 滑动变阻器动触点连接到STM32的ADC通道引脚GPIOC_3固定触点一边接0V一边接3.3V因此旋转滑动变阻器调节旋钮时动触点的电压会在0~3.3V之间变化。
根据以上电路设计设计个模拟量采集程序具体需要实现如下步骤
初始化配置ADC目标引脚为模拟输入模式使能ADC时钟再次强调使用外设一定要先开启时钟配置通用ADC为独立模式采样4分频设置目标ADC为12位分辨率1通道的连续转换不需要外部触发设置ADC转换通道顺序及采样时间配置使能ADC转换完成中断在中断内读取转换完数据启动ADC转换使能软件触发ADC转换。
这里需要注意没用使用到DMA进行数据传输而是使用中断方式进行读取。
bsp_adc.h
#ifndef __BSP_ADC_H_
#define __BSP_ADC_H_#include stm32f4xx.h#define R_ADC_IRQ ADC_IRQn
#define R_ADC_INT_FUNCTION ADC_IRQHandler
#define R_ADC_GPIO_PORT GPIOC
#define R_ADC_GPIO_PIN GPIO_Pin_3
#define R_ADC_GPIO_CLK RCC_AHB1Periph_GPIOC#define R_ADC ADC1
#define R_ADC_CLK RCC_APB2Periph_ADC1
#define R_ADC_CHANNEL ADC_Channel_13void R_ADC_Init(void);
#endif
bsp_adc.c
#include bsp_adc.h/** brief 初始化ADC GPIO引脚* parm 无* retval 无*/
static void R_ADC_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(R_ADC_GPIO_CLK,ENABLE); //开启ADC外设引脚时钟GPIO_InitStructure.GPIO_Pin R_ADC_GPIO_PIN; //配置引脚位3引脚GPIO_InitStructure.GPIO_Mode GPIO_Mode_AIN; //配置引脚为模拟输入GPIO_InitStructure.GPIO_PuPd GPIO_PuPd_NOPULL; //配置为无上下拉GPIO_Init(R_ADC_GPIO_PORT,GPIO_InitStructure); //初始化引脚
}/** brief 配置ADC引脚工作模式* parm 无* retval 无*/
static void R_ADC_Mode_Config(void)
{ADC_InitTypeDef ADC_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;RCC_APB2PeriphClockCmd(R_ADC_CLK,ENABLE);//-----------------ADC Common结构体参数初始化--------------//ADC_CommonInitStructure.ADC_Mode ADC_Mode_Independent; //设置模式为独立模式ADC_CommonInitStructure.ADC_Prescaler ADC_Prescaler_Div4; //设置为4分频ADC_CommonInitStructure.ADC_DMAAccessMode ADC_DMAAccessMode_Disabled; //禁止DMA直接访问模式ADC_CommonInitStructure.ADC_TwoSamplingDelay ADC_TwoSamplingDelay_10Cycles; //设置采样间隔周期为10个周期ADC_CommonInit(ADC_CommonInitStructure);//-----------------ADC Init结构体参数初始化--------------//ADC_InitStructure.ADC_Resolution ADC_Resolution_12b; //设置ADC采样分辨率为12位ADC_InitStructure.ADC_ScanConvMode DISABLE; //多通道下才会用到扫描模式这里直接禁止ADC_InitStructure.ADC_ContinuousConvMode ENABLE; //设置为连续转换ADC_InitStructure.ADC_ExternalTrigConvEdge ADC_ExternalTrigConvEdge_None; //禁用外部边沿触发ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right; //设置为右对齐ADC_InitStructure.ADC_NbrOfConversion 1; //转换通道只有1个ADC_Init(R_ADC,ADC_InitStructure);ADC_RegularChannelConfig(R_ADC,R_ADC_CHANNEL,1,ADC_SampleTime_56Cycles); //配置ADC通道转换顺序为1第一个转换才压根时间为56个时钟周期ADC_ITConfig(R_ADC,ADC_IT_EOC,ENABLE); //ADC转换结束产生中断在中断服务程序中读取转换数值ADC_Cmd(R_ADC,ENABLE); //使能ADCADC_SoftwareStartConv(R_ADC); //开始ADC转换由软件触发
}static void R_ADC_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置中断向量组为1NVIC_InitStructure.NVIC_IRQChannel R_ADC_IRQ; //配置中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 1; //设置主优先级为1NVIC_InitStructure.NVIC_IRQChannelSubPriority 1; //设置此优先级为1NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; //通道使能NVIC_Init(NVIC_InitStructure); //初始化中断
}
void R_ADC_Init(void)
{R_ADC_GPIO_Config();R_ADC_Mode_Config();R_ADC_NVIC_Config();
}main.c
#include stm32f4xx.h
#include bsp_usart_dma.h
#include bsp_systick.h
#include bsp_adc.h
#include stdio.h
__IO uint16_t ADC_Value;
float ADC_Vol 0;
int main(void)
{DEBUG_USART1_Config();R_ADC_Init();SysTick_Init();printf(\r\n---------------ADC实验中断模式----------------\r\n);while(1){Delay_ms(1000);printf(\r\n ADC数据未转换 0x%04X \r\n,ADC_Value);ADC_Vol (float)(ADC_Value*3.3/4096); // 读取转换的 AD 值 printf(\r\n ADC数据已转换 %.2f V \r\n,ADC_Vol);}
}stm32f4xx_it.c
//此处记得在头文件中声明函数
extern __IO uint16_t ADC_ConvertedValue;
void ADC_IRQHandler(void)
{if (ADC_GetITStatus(R_ADC,ADC_IT_EOC)SET) //获取ADC中断状态{ADC_ConvertedValue ADC_GetConversionValue(R_ADC); // 等待转换完成后读取ADC的转换值}ADC_ClearITPendingBit(R_ADC,ADC_IT_EOC); //清除状态寄存器
}输出结果如下调整电位器会发现数值在0V~3.3V之间变化。
单通道相对比较简单这里先了解一下后面在学习一下多通道并且启用DMA传输模式。