stm32 嵌入式开发 用标准库进行 ADC 实验总结
------------恢复内容开始------------
硬件原理图 ,滑动电位器与芯片PC3引脚连接
根据开发板可知:STM32F429IGT6 有 3 个 ADC,每个 ADC 有 12 位、 10 位、 8 位和 6 位可选,每个ADC 有 16 个外部通道。
每个ADC 同时还有3个内部通道:通道16/17/18
工作模式有3种:独立模式、双重模式和三重模式 。
转换顺序可分为:规则序列,注入序列。如下图所示:
规则序列寄存器设置根据表由上到下选择通道进行配置
注入序列寄存器JSQR转换顺序为JSQR[X][4:0],
X=4-JL,JL为需要转换的通道
触发源可选择:ADC2_CR2->ADON
外部事件触发:内部定时器、外部IO (EXTSEL[2:0] JEXTSEL[2:0]控制 )
时间设置: ADC 的输入时钟ADC_CLK由PCLK2经过分频产生36MH最大z频率
采样时间:每个通道可以设置不同的采样频率,最小的采样时间是3个周期1/ADC_CLK
ADC总转换时间= 采样时间+12个时钟周期
数据寄存器:ADC_DR 1个32位寄存器,最低16位有效。独立模式时使用,可以开启DMA模式
ADC_JDRX 4个32位寄存器,低16位有效
ADC_CDR 适用于双重和三重模式
转换结束中断:规则通道转换结束中断
注入转换通道转换结束中断
模拟看门狗中断:模拟电压控制
溢出中断 :数据丢失
DMA请求:
库文件结构体使用: ADC_InitTypeDef --------->>>>>>>>>stm32f4xx_adc.h
ADC_CommonInitTypeDe ------->>>>stm32f4xx_adc.h
ADC_Init ----------------------->>>>>>>stm32f4xx_adc.c
编程要点:其中串口发送子程序直接移植
1) 初始化配置 ADC 目标引脚为模拟输入模式;
2) 使能 ADC 时钟;
3) 配置通用 ADC 为独立模式,采样 4 分频;
4) 设置目标 ADC 为 12 位分辨率, 1 通道的连续转换,不需要外部触发;
5) 设置 ADC 转换通道顺序及采样时间;
6) 配置使能 ADC 转换完成中断,在中断内读取转换完数据;
7) 启动 ADC 转换;
8) 使能软件触发 ADC 转换
引脚宏定义代码
1 #ifndef BSP_ADC_H 2 #define BSP_ADC_H 3 #include "stm32f4xx.h" 4 5 // 中断定义 6 #define Rheostat_ADC_IRQ ADC_IRQn//中断号 7 #define Rheostat_ADC_INT_FUNCTION ADC_IRQHandler//中断接口函数 8 // 变阻器接口GPIO 9 #define Rheostat_ADC_GPIO_PORT GPIOC 10 #define Rheostat_ADC_GPIO_PIN GPIO_Pin_3 11 #define Rheostat_ADC_GPIO_CLK RCC_AHB1Periph_GPIOC 12 13 #define Rheostat_ADC ADC1 14 #define Rheostat_ADC_CLK RCC_APB2Periph_ADC1 15 #define Rheostat_ADC_CHANNEL ADC_Channel_13 16 17 18 19 void Rheostat_Init(void); 20 21 22 23 #endif
配置ADC工作代码
#include "./adc/bsp_adc.h" /* 编程要点: 初始化配置 ADC 目标引脚为模拟输入模式 使能 ADC 时钟 配置通用 ADC 为独立模式,采样 4 分频 配置目标 ADC 为 12 位分辨率,1 通道的连续转换,不需要外部触发 设置 ADC 转换通道顺序及采样时间 配置使能 ADC 转换完成中断,在中断内读取转换完数据 启动 ADC 转换 使能软件触发 ADC 转换 ADC 转换结果数据使用中断方式读取,这里没有使用 DMA 进行数据传输。 */ // 变阻器 ADC_GPIO 初始化 static void Rheostat_ADC_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // 使能 GPIO 时钟 RCC_AHB1PeriphClockCmd(Rheostat_ADC_GPIO_CLK, ENABLE); //配置 IO GPIO_InitStructure.GPIO_Pin = Rheostat_ADC_GPIO_PIN; // 模拟输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 不上拉不下拉 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(Rheostat_ADC_GPIO_PORT,&GPIO_InitStructure); } // 配置 ADC 工作模式 static void Rheostat_ADC_Mode_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; // 使能 ADC 时钟 RCC_APB2PeriphClockCmd(Rheostat_ADC_CLK,ENABLE); // ----------ADC Common 结构体 参数 初始化-------------- // 独立 ADC 模式 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; // 时钟为 fpclk x 分频 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//90/4 // 禁止 DMA 直接访问模式 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; // 采样时间间隔 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_10Cycles; ADC_CommonInit ( &ADC_CommonInitStructure ); // -----------ADC Init 结构体 参数 初始化----------------- // ADC 分辨率 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b ;//电压值=(读取到的值*3.3v / 2^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_ExternalTrigConv = // 转换通道1个 ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init ( Rheostat_ADC, &ADC_InitStructure) ; //配置 ADC 通道转换顺序为 1,第一个转换,采样时间为 56 个时钟周期 ADC_RegularChannelConfig ( Rheostat_ADC, Rheostat_ADC_CHANNEL, 1, ADC_SampleTime_56Cycles) ; // ADC 转换结束产生中断,在中断服务程序中读取转换 ADC_ITConfig ( Rheostat_ADC,ADC_IT_EOC, ENABLE) ; // 使能 ADC ADC_Cmd (Rheostat_ADC,ENABLE); // 开始 ADC 转换,软件触发 ADC_SoftwareStartConv ( Rheostat_ADC) ; } // 中断配置ADC static void Rheostat_ADC_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig ( NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = Rheostat_ADC_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void Rheostat_Init(void) { Rheostat_ADC_NVIC_Config(); Rheostat_ADC_GPIO_Config(); Rheostat_ADC_Mode_Config(); }
中断响应
extern uint16_t ADC_ConvertedValue;// main 中定义的全局变量 void Rheostat_ADC_INT_FUNCTION(void) { if(ADC_GetITStatus (Rheostat_ADC,ADC_IT_EOC) == SET) { // 读取ADC 转换的值 ADC_ConvertedValue = ADC_GetConversionValue(Rheostat_ADC); } ADC_ClearITPendingBit(Rheostat_ADC,ADC_IT_EOC); }
实验结果
实验总结:
ADC_IRQn//中断号 ---->>>>>>在文件stm32f4xx.h(外设寄存器定义文件)
ADC_IRQHandler//中断接口函数 ----->>>>>在文件startup_stm32f429_439xx.s(汇编编写的启动文件中找,不能随便定义)
AD挂载在 APB2外设上 ADC_Channel_13 通道13对应的GPIO接口PC3
ADC时钟频率=90/4=22.5mhz
// 采样时间间隔
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_10Cycles;
//配置 ADC 通道转换顺序为 1,第一个转换,采样时间为 56 个时钟周期
ADC_RegularChannelConfig ( Rheostat_ADC, Rheostat_ADC_CHANNEL,
1, ADC_SampleTime_56Cycles) ;
2020-03-0909:07:16
------------恢复内容结束------------