ADC独立单通道采集
使用的是野火stm32f103vet6指南者开发板,硬件连接图如下:
实验一:独立单通道中断读取ADC值
编程要点:
初始化ADC用到的GPIO;
初始化ADC初始化结构体;
配置ADC时钟,配置通道的转换顺序和采样时间;
使能ADC转换完成中断,配置中断优先级;
使能ADC,准备开始转换;
校准ADC;
软件触发ADC,真正开始转换;
编写中断服务函数,读取ADC转换数据;
编写main函数,把转换的数据打印出来;
代码如下:
bsp_adc.c
#include "bsp_adc.h"
static void ADCx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 打开 ADC IO端口时钟
ADC_GPIO_APBxClock_FUN(ADC_GPIO_CLK, ENABLE);
// 配置 ADC IO 引脚模式
// 必须为模拟输入
GPIO_InitStructure.GPIO_Pin = ADC_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
// 初始化 ADC IO
GPIO_Init(ADC_PORT, &GPIO_InitStructure);
}
static void ADCx_Mode_Config(void)
{
ADC_InitTypeDef ADC_InitStruct;
// 打开ADC的时钟
ADC_APBxClock_FUN(ADC_CLK, ENABLE);
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; // 独立模式
ADC_InitStruct.ADC_ScanConvMode = DISABLE; // 不使用扫描模式
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; // 连续转换
/* 不使用外部触发 */
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_NbrOfChannel = 1;
ADC_Init(ADC_x, &ADC_InitStruct);
RCC_ADCCLKConfig(RCC_PCLK2_Div8); // 配置ADC时钟为8分频 ADCCLK = 9M
ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5);
ADC_ITConfig(ADC_x, ADC_IT_EOC, ENABLE); // 配置ADC转换完成中断
ADC_Cmd(ADC_x, ENABLE); // 使能ADC
ADC_ResetCalibration(ADC_x); // 初始化ADC 校准寄存器
while(ADC_GetResetCalibrationStatus(ADC_x)); // 等待校准寄存器初始化完成
ADC_StartCalibration(ADC_x); // ADC开始校准
while(ADC_GetCalibrationStatus(ADC_x)); // 等待校准完成
ADC_SoftwareStartConvCmd(ADC_x, ENABLE); // 使用软件触发
}
static void ADC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// 优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// 配置中断优先级
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief ADC初始化
* @param 无
* @retval 无
*/
void ADCx_Init(void)
{
ADCx_GPIO_Config();
ADCx_Mode_Config();
ADC_NVIC_Config();
}
bsp_adc.h
#ifndef __BSP_ADC_H
#define __BSP_ADC_H
#include "stm32f10x.h"
// ADC GPIO宏定义
#define ADC_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define ADC_GPIO_CLK RCC_APB2Periph_GPIOC
#define ADC_PORT GPIOC
#define ADC_PIN GPIO_Pin_1
// ADC 编号选择
// 可以是 ADC1/2,如果使用ADC3,中断相关的要改成ADC3的
#define ADC_APBxClock_FUN RCC_APB2PeriphClockCmd
#define ADC_x ADC2
#define ADC_CLK RCC_APB2Periph_ADC2
// ADC 通道宏定义(PC1对应通道11)
#define ADC_CHANNEL ADC_Channel_11
// ADC 中断相关宏定义
#define ADC_IRQ ADC1_2_IRQn
#define ADC_IRQHandler ADC1_2_IRQHandler
void ADCx_Init(void);
#endif /* __BSP_ADC_H */
中断服务函数中,当转换完成后,把转换值不断刷新到全局变量中:
void ADC_IRQHandler(void)
{
if (ADC_GetITStatus(ADC_x, ADC_IT_EOC) == SET)
{
ADC_ConvertedValue = ADC_GetConversionValue(ADC_x);
}
ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC); // 清中断标志位,防止一直在中断里
}
最后在主函数中进行测试:
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_adc.h"
#include __IO uint16_t ADC_ConvertedValue; // 局部变量,用于保存转换计算后的电压值 float ADC_ConvertedValueLocal; void Delay(__IO uint32_t nCount) { for(; nCount != 0; nCount--); } int main(void) { LED_GPIO_Config(); USART_config(); ADCx_Init(); printf("这是一个ADC独立单通道读取实验tn"); while (1) { ADC_ConvertedValueLocal =(float) ADC_ConvertedValue / 4096 * 3.3; printf("The current AD value = %#X tn", ADC_ConvertedValue); printf("The current voltage = %f V tn", ADC_ConvertedValueLocal); printf("n"); LED_B_TOGGLE; Delay(0x2fffee); } } 实验现象如下: 实验二:独立单通道DMA读取 当要传输大量的数据时,一般都是采用DMA。ADC + DMA本身的配置非常简单,就只需要注意,只能使用ADC1或ADC3,而ADC2无DMA传输功能。 这里主要看一下ADC + DMA配置: /** * @brief ADC - DMA配置 * @note 注意,ADC - DMA只能使用ADC1 或 ADC3,ADC2无DMA功能 */ static void ADCx_DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(ADC_DMA_CHANNEL); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC_x->DR)); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure); DMA_Cmd(ADC_DMA_CHANNEL , ENABLE); } 然后在ADC配置函数中进行调用,再使能ADC + DMA: /* ADC - DMA设置要在使能ADC完成 */ ADCx_DMA_Config(); // 配置ADC - DMA ADC_DMACmd(ADC_x, ENABLE); // 使能 ADC DMA 请求 然后在main.c中进行测试,结果如下:
上一篇:stm32专题二十四:ADC 标准库函数分析
下一篇:stm32专题二十四:ADC + DMA 多通道 规则同步
推荐阅读
史海拾趣
在2006年至2007年期间,A1 PROS的技术实力得到了业界的广泛认可。韩国技术信用保证基金将A1 PROS评选为杰出技术公司,这是对A1 PROS在技术研发和创新方面所取得成就的肯定。同时,A1 PROS还被韩国工业银行选定为家族企业,获得了更多的资金支持和发展机会。
随着公司在韩国本土市场的稳步发展,A1 PROS开始积极寻求国际市场的拓展。公司以韩国母公司为研发和生产中心,面向台湾、香港、中国大陆以及中东、欧美等地区开展业务。通过不断优化产品设计和提升生产效率,A1 PROS的产品逐渐在国际市场上占据了一席之地。同时,公司还积极参加各类国际电子展会和技术交流会,与全球同行建立了广泛的合作关系。
经过多年的发展,协顺电子已经成为中国电子连接器行业的领军企业之一。展望未来,公司将继续坚持“以顾客为中心”的经营理念,不断提升产品质量和技术水平;同时,公司也将积极探索新的业务领域和市场机会,推动公司的持续发展。此外,协顺电子还将加强与国际知名企业的合作与交流,共同推动电子行业的发展和进步。
请注意,以上故事框架仅供参考,具体的故事内容需要根据协顺电子(Finecables)公司的实际情况和发展历程进行创作和补充。
南京中科微电子有限公司(CSM)的创立源于一群海归科学家和工程师的激情与梦想。他们曾在国外知名半导体公司如Marvell、ADI、Linear Tech等积累了丰富的研发经验,并在国家重点研究院所中从事前沿研究。这群人深感国内在射频/模拟关键芯片领域的落后,于是决定回国创立CSM,旨在打破国外技术垄断,实现自主创新和产业化。
为了更好地服务于中国市场,Futaba在2002年成立了双叶电子科技开发(北京)有限公司。该公司专营Futaba的全线产品,包括VFD真空荧光显示管和RC无线遥控设备等。这一举措标志着Futaba在全球化布局上迈出了重要一步,也为公司在中国市场的快速发展奠定了基础。北京分公司的成立不仅加强了Futaba与中国客户的联系,还促进了公司在技术、产品和市场等方面的全方位合作。
芯力微深知人才是企业发展的核心动力。因此,公司一直注重人才的培养和引进。公司建立了一套完善的人才培养机制,为员工提供广阔的发展空间和良好的职业前景。同时,芯力微还积极引进国内外优秀人才,打造了一支高素质、专业化的团队。这支团队不仅具备丰富的行业经验和技术能力,还具备高度的责任感和使命感。他们为公司的发展贡献了自己的智慧和力量。
各位英雄: 小弟最近开始接触wince下wifi模块驱动,有几个基本的问题还没有弄明白,恳请各位英雄指教! 小弟对wince下的以太网卡驱动有一定的了解,知道它是基 ...… 查看全部问答∨ |
如果我禁能了一个中断源, 不论什么平台吧, ARM或51都无所谓. 那么当这个中断到来时, 中断标志位会被置上吗? "禁能"的意思究竟是中断标志位不会被置上, 还是说标志位会被置上, 但不会跳转到相应的处理函数? 如果被置上了, 我在什么时候清中断 ...… 查看全部问答∨ |
我修改了触摸屏驱动导致出现只显示上半个屏幕的现象,下半个屏幕是白色的;并且上半个屏幕的分辨率是正常的,程序窗口正适合3.5寸液晶屏幕。 ------------比以前有进步。 红色部分为修改后的内容: 修改部分:s2410.h &nb ...… 查看全部问答∨ |
|
在单片机里开发usb的驱动,并支持fat的文件系统。 根据fat16的规则在usb文件系统中创建新的文件。 首先在FAT区查找可用的簇 然后根目录区查找可用的目录项,填充32字节的内容。 然后把FAT中的簇标记为0xffff 然后往实际的簇填入文件的内容。 ...… 查看全部问答∨ |
|
我用T0定时,输出两个不同的频率,先输出一个低点的频率,延时一段时间输出高点的频率,本来是想通过改变装不同的初值来实现输出不同的频率,但程序下载在单片机后,用示波器观察不正确,一直只有低的频率,不论等 ...… 查看全部问答∨ |
都说电压跟随器有高输入阻抗,低输出阻抗。在网上也查了 高输入阻抗为什么好:“假设讯源输出一个固定电压,传送往下一级,如果这一级的输入阻抗高,是不是由讯源所提供的讯号电流就可以降低?如果输入阻抗非常非常的高,则几乎不会消耗讯号电流(当 ...… 查看全部问答∨ |