STM32F103RET6 ADC配置流程

2023-11-15

STM32F103RET6 ADC基本配置流程

首先,使用RCC库函数RCC_APB2PeriphClockCmd使能ADC时钟。可以使用以下代码:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

接下来,需要定义一个ADC_InitTypeDef类型的结构体变量,用于存储ADC模块的配置参数如工作模式、扫描模式、转换模式、触发源、数据对齐方式、通道数等参数,可以使用以下代码:

ADC_InitTypeDef ADC_InitStruct;
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//独立通道模式
ADC_InitStruct.ADC_ScanConvMode = DISABLE;//表示ADC是否使用扫描模式进行转换。如果设置为ENABLE,则ADC会按照ADC_ScanConvMode的通道顺序进行扫描转换;如果设置为DISABLE,则只会转换ADC1的第一个通道。在本代码中,ADC_ScanConvMode被设置为DISABLE,表示不使用扫描模式,仅转换单个通道。
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//连续转换模式失能
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//ADC触发源配置:软件触发,非外部触发
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐方式:右对齐
ADC_InitStruct.ADC_NbrOfChannel = 1;//采样通道配置:1个通道

初始化ADC模块

ADC_Init(ADC1, &ADC_InitStruct);

然后,需要配置ADC模块的基本参数,配置ADC通道、转换顺序、采样时间。可以使用以下代码:

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//ADC_Channel_0表示要读取的通道,1表示转换序列的排列顺序,ADC_SampleTime_55Cycles5表示采样时间。

然后需要配置ADC转换完成后的中断。可以使用NVIC库中的函数,将ADC的中断优先级设置为适当的级别,从而实现中断的处理。
最后,启动ADC转换并等待转换完成。可以使用以下代码:

ADC_Cmd(ADC1, ENABLE);//ADC_Cmd函数启动ADC
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//ADC_SoftwareStartConvCmd函数启动转换
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//检查ADC1是否完成转换是否转换完成等待转换完成并清除结束标志

完成以上步骤后,可通过触发ADC中断,调用ADC_GetConversionValue函数来读取ADC转换的结果(ADC_DR)。

以下是较为完整的示例代码:

#include "stm32f10x.h"

void ADC_Configuration(void)
{
  // 使能ADC1时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  
  // ADC配置结构体定义
  ADC_InitTypeDef ADC_InitStructure;
  
  // ADC模式配置:独立模式
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  
  // ADC扫描模式配置:禁止
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  
  // ADC连续转换模式配置:禁止
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  
  // ADC触发源配置:软件触发
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  
  // ADC数据对齐方式配置:右对齐
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  
  // ADC采样通道数配置:1个通道
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  
  // 初始化ADC模块
  ADC_Init(ADC1, &ADC_InitStructure);
  
  // ADC通道配置:ADC通道0,采样时间为239.5个时钟周期
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
  
  // ADC GPIO配置
  GPIO_InitTypeDef GPIO_InitStructure;
  
  // ADC引脚为模拟输入模式
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  // 启动ADC转换
  ADC_Cmd(ADC1, ENABLE);
  
  // 等待ADC稳定
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
  
  // 启动ADC转换
  ADC_StartConversion(ADC1);
  
  // 等待转换完成
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
  
  // 读取ADC数据
  uint16_t adc_value = ADC_GetConversionValue(ADC1);
}

内容拓展: ADC_Mode

ADC_Mode:
1. ADC_Mode_Independent(独立模式,每个ADC工作在独立的模式下)
2. ADC_Mode_RegInjecSimult(常规、注入和同时模式,ADC工作在常规模式下,同时允许注入转换和触发)
3. ADC_Mode_RegSimult_AlterTrig(常规和同时模式,两个ADC交替工作并使用外部触发)
4. ADC_Mode_InjecSimult_FastInterl(注入和同时模式,所有转换都同时开始)
5. ADC_Mode_InjecSimult_SlowInterl(注入和同时模式,2个序列交替地工作)
6. ADC_Mode_InjecSimult(注入和同时模式,所有转换都同时开始,但是注入序列优先于常规序列)
7. ADC_Mode_RegSimult(常规和同时模式,所有转换都同时开始,但是常规序列优先于注入序列)
8. ADC_Mode_FastInterl(快速扫描模式,交替地执行转换)
9. ADC_Mode_SlowInterl(缓慢扫描模式,两个序列交替地工作)

内容拓展: ADC_GetConversionValue

/**
* @Brief Returns the last ADCx conversion result data for regular channel.
* @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
* @retval The Data conversion value.
*/
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
{
/* Check the parameters */
assert_param(IS_ADC_ALL_PERIPH(ADCx));
/* Return the selected ADC conversion value */
return (uint16_t) ADCx->DR;
}
//ADC_GetConversionValue 函数用于获取ADC转换的结果值。此函数返回一个无符号16位整数值,表示ADC的转换结果。其中ADC_DR寄存器存储着最近一次转换的结果值。

STM32F103RET6 ADC NTC采样示例:
思路实现:

1. 配置ADC模块

a. 设置ADC时钟,使能ADC时钟。

b. 配置ADC模式:单次转换模式/连续转换模式。

c. 配置采样时间,确定模拟输入信号稳定时间。

d. 配置参考电压,确定模拟量输入范围。

e. 配置ADC通道,确定转换的模拟量输入通道。

f. 开始ADC转换。

2. 配置DMA模块

a. 选择DMA通道,确定使用哪个DMA通道。

b. 配置传输方向,确定发送/接收方向。

c. 配置传输数据长度,确定每次传输数据的长度。

d. 配置存储器地址,确定源地址/目的地址。

e. 配置传输模式,确定连续/非连续传输模式。

f. 开启DMA传输。

3. 配置串口模块

a. 配置波特率,确定通信速度。

b. 配置数据位,确定每次传输数据的位数。

c. 配置校验位,用于传输数据的校验。

d. 配置停止位,确定每次传输数据的停止位数。

e. 开启串口发送/接收功能。

4. 使用定时器进行ADC采样和DMA传输

a. 配置定时器,设定定时时间。

b. 开启定时器。

c. 在定时器中断中获取ADC值,存储到DMA缓冲区中,并开启DMA传输。

5. 配置DMA中断处理函数

a. 在DMA传输完成中断中,将数据通过串口发送出去。

6. 在主函数中进行模块初始化并启动程序

a. 对ADC、DMA、串口、定时器等模块进行初始化。

b. 启动程序。

示例代码:
/* ADC Configuration */
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

/* DMA Configuration */
DMA_InitTypeDef DMA_InitStructure;

/* USART Configuration */
USART_InitTypeDef USART_InitStructure;

/* Timer Configuration */
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

int main(void)
{
  /* Initialization of ADC, DMA, USART, and Timer modules */
  ADC_DeInit(ADC1);
  DMA_DeInit(DMA1_Channel1);
  USART_DeInit(USART1);
  TIM_DeInit(TIM2);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_TIM1 | RCC_APB2Periph_TIM8, ENABLE);

  /* Configure ADC */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_Init(ADC1, &ADC_InitStructure);

  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);

  ADC_Cmd(ADC1, ENABLE);

  /* Configure DMA */
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &buffer;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  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(DMA1_Channel1, &DMA_InitStructure);
  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* Configure USART */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Tx;
  USART_Init(USART1, &USART_InitStructure);
  USART_Cmd(USART1, ENABLE);

  /* Configure Timer */
  TIM_TimeBaseStructure.TIM_Period = 720; // Period = (SystemCoreClock/2)/720 = 50kHz
  TIM_TimeBaseStructure.TIM_Prescaler = 0; // Prescaler = (SystemCoreClock/2)/7200000 = 5
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  /* Configure NVIC */
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  /* Start Timer */
  TIM_Cmd(TIM2, ENABLE);

  while(1)
  {
    // Main program loop
  }
}

/* DMA Interrupt Service Routine */

void DMA1_Channel1_IRQHandler(void)
{
  if (DMA_GetITStatus(DMA1_IT_TC1) != RESET)
  {
    DMA_ClearITPendingBit(DMA1_IT_TC1);
// Send data to USART
    USART_SendData(USART1, buffer);
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32F103RET6 ADC配置流程 的相关文章

  • STM32 - 利用SPI接口读写FLASH编程实践

    1 SPI 固件库介绍 可以直接查看 F103固件库手册 只有英文没有中文 chm 找到SPI章节 相关信息都在这里 初始化结构体及函数定义在库文件 stm32f4xx spi h 及 stm32f4xx spi c 中 编程 时我们可以结
  • 【Shell案例】【for循环、seq生成】3、输出7的倍数

    描述写一个 bash脚本以输出数字 0 到 500 中 7 的倍数 0 7 14 21 的命令 方法1 in方式循环 if的括号是中括号 中间的条件要有空格 循环体用do和done配对 判断用if和fi配对 循环条件内不用加 echo的时候

随机推荐

  • Canal报错:Could not find first log file name in binary log index file

    解决方案 rm home admin canal server conf example meta dat 然后重启 home admin canal server bin restart sh
  • RecyclerView实现九宫格和点击事件

    想要实现的效果如下 开始界面 点击界面展示 在屏幕中间弹出一个对话框 效果就如同将图片放大一样 不过当然 这里的图片放大并非真正意义上的拉伸 而是展示出较大的那张图片 若是不打算用两张图片 也可以自定义大小 这里因为只是简单的demo 也为
  • 异常:java lang AbstractMethodError

    通常在尝试调用抽象方法时抛出此 java lang AbstractMethodError 通常 此错误是在编译时本身识别的 如果在运行时抛出此错误 则该类必须不兼容 与先前存在的类不兼容 更改 因此 它是IncompatibleClass
  • 嵌入式 Linux 入门 环境篇(四、必备开发工具安装)

    嵌入式 Linux入门 环境篇第四课 开发工具软件的安装与说明 by 矜辰所致 前言 前面的环境篇我们把开发的基本环境安装好了 Ubuntu虚拟机 网络配置 为了从 0 开始说明 还特意买了一台新电脑 就问是不是不将就 在我们接下来做嵌入式
  • 思科实验18.网络层:OSPF路由协议(下)

    多区域OSPF和RIP结合 实验流程 1 设计拓扑 2 配置主机IP地址 3 配置路由器各端口ip 4 封装OSPF协议 5 封装RIP协议 6 剩余工作 7 验证主机连通 实验流程 mermaid svg k8yA2guPqb8dork0
  • @Autowired注解的底层原理

    Spring框架的便利让我们很容易地使用 Autowired注解实现依赖注入 本篇将深入Spring源码解析 Autowired注解的工作原理 一 Autowired注解的作用 1 Autowired 是一个注释 它可以对类成员变量 方法及
  • 微软服务器导入arm,微软发布Windows 10 Build 20277,在ARM上为Win10引入了x64仿真

    微软已经在开发通道中向Windows Insiders发布了Windows 10 Insider Preview Build 20277 FE PRERELEASE 完整的内部版本号 20277 1 fe release 201207 15
  • JVM的垃圾回收机制 总结(垃圾收集、回收算法、垃圾回收器)

    如果想了解Java内存模型参考 jvm内存模型 和内存分配以及jdk jre jvm是什么关系 阿里 美团 京东 相信和小编一样的程序猿们在日常工作或面试当中经常会遇到JVM的垃圾回收问题 有没有在夜深人静的时候详细捋一捋JVM垃圾回收机制
  • 关注公号: AI深度视线

    1 引言 摘要 在这项工作中 我们旨在构建一个性能强大的简单 直接和快速的实例分割框架 我们遵循SOLOv1方法的原理 SOLO 按位置分割对象 重要的是 我们通过动态学习目标分割器的mask head 具体来说 将mask分支解耦为mas
  • 秋招提前批!大厂offer的捷径!

    前言 又是一年秋招季 年年岁岁花相似 岁岁年年人不同 今天 博主在牛客上看到一个帖子 24届校招提前批已经开始了 24届大厂提前批 首先 跟大家科普一下提前批的概念 提前批是指企业在校园招聘季之前提前开展的招聘活动 它通常在暑假期间或上半年
  • 基于STM32F103C8T6的高速DMA传输多通道ADC数据

    文章目录 前言 一 软件设计思路 二 代码 总结 前言 ADC在STM32系列单片机的使用中占用着很大的比例 常见的案例是通过ADC单次转换电压值 这种方式的缺陷在于转换效率不高 一般的单片机带有ADC1和ADC2两个ADC转换 单次转换需
  • modbus协议详解_【实例】西门子PLC通过MODBUS控制变频器

    一 MODBUS通信概述 MODBUS协议分为串行链路上MODBUS协议和基于TCP IP协议的MODBUS 协议 串行链路上MODBUS协议有MODBUS ASCAII 字符串 和MODBUS RTU两种 200SMART所提供的MODB
  • 全面分析副业做什么更快速见收益?

    大家好 我是沐小沐 今天我们聊一聊全面分析副业做什么更快速见收益 如今副业刚需的时代 沒有副业 等于你就失去了几百万的车和房 并不夸张 在这个填满焦虑情绪的社会发展 每个人都是在整体规划自身的副业 哪些的副业才算是好的副业呢 我觉得最好是能
  • SAP 科目的 未清项管理的理解

    清账的事务代码 自动清账 F 13 总账清账 F 04 供应商清账 F 53 客户清账 F032 未清项管理是SAP的一个重要功能 通过未清项管理可以实现付款 收款 的一一对应 以及准确的账龄分析 会计科目设置此标志后 系统会将凭证行标记为
  • 在虚拟磁盘中安装Windows Server 2016

    说起来我一直没有安装过Windows服务器版的系统 所以最近想尝试一下Windows Server 2016 这个最新的Windows服务器系统 当然如果是家用的话 肯定还是安装桌面版的系统更好 服务器版的系统主要是企业使用 日常功能反而不
  • python读取每一行再按照空格分隔

    all with open number txt r as f for line in f readlines curLine line strip split print curLine all append curLine f clos
  • 附近商家位置java开发附近定位

    根据给定经纬度 lat lng 求出其左上角 left top 右上角 right top 左下角 left bottom 右下角 right bottom 的四个位置 所有在这个区域的范围都在该点附近 public class Test
  • 最新计算机毕业设计选题推荐 - 毕设选题建议

    文章目录 0 前言 1 java web 管理系统 毕设选题 2 java web 平台 业务系统 毕设选题 3 游戏设计 动画设计类 毕设选题 适合数媒的同学 4 算法开发 5 数据挖掘 毕设选题 6 大数据处理 云计算 区块链 毕设选题
  • 2020全国网络安全知识竞赛链工宝答案 爬取 自动答题

    要用浏览器打开公众号的练题库 然后就可以自动获取答案 最下面是我获取到的300多个题 差不多就这些了 可以进一个加个函数自动答题 def fu try browser refresh time sleep 2 xx browser find
  • STM32F103RET6 ADC配置流程

    STM32F103RET6 ADC基本配置流程 首先 使用RCC库函数RCC APB2PeriphClockCmd使能ADC时钟 可以使用以下代码 RCC APB2PeriphClockCmd RCC APB2Periph ADC1 ENA