细说MCU用定时器控制ADC采样频率的实现方法

目录

一、工程依赖的硬件及背景

二、设计目的

三、 建立工程

1.选择时钟源和Debug模式

2.配置系统时钟和ADC时钟

3.配置串口

4.配置ADC

5.设置TIM3

6.设置TIM4 

7.配置中断

8.GPIO

四、代码修改

1.重新定义ADC回调函数

2.在主程序中编写数据发送代码

3.使能ADC和开启定时器

4.查看结果


        在细说MCU的ADC模块单通道连续采样的实现方法-CSDN博客  https://blog.csdn.net/wenchm/article/details/140008718icon-default.png?t=N7T8http://xn--https-rfa//blog.csdn.net/wenchm/article/details/140008718中,通过使能AD配置参数中的连续转换模式(Continuous Conversion Mode),并结合ADC中断,实现了连续采样。该例中,ADC的采样频率约为1.58 kHz,是通过设置ADC的时钟频率和采样时间得到的。实际中,有时希望ADC以给定的采样频率转换数据,譬如1 kHz。在这种情况下靠配置ADC时钟频率和采样时间的方法就非常不方便。

        本例子使用定时器来控制ADC连续采样。

一、工程依赖的硬件及背景

        文章依赖的硬件及工程配置参考本文作者的其他文章:细说MCU的ADC模块单通道连续采样的实现方法-CSDN博客  https://blog.csdn.net/wenchm/article/details/140008718icon-default.png?t=N7T8http://xn--https-rfa//blog.csdn.net/wenchm/article/details/140008718

二、设计目的

        信号源为TIM4的TIM_CHANNEL_1,管脚PA11,给ADC1_IN1输入信号;也可以用管脚PA5的LD2作为信号源给ADC1_IN1输入信号;

       ADC1_IN1采集到信号后,按缓冲大小的规定,循环给串口发送数据;

       ADC采集样品的频率由TIM3设置的规则控制;

三、 建立工程

1.选择时钟源和Debug模式

        使用片外时钟晶体作为HSE的时钟源。将Debug设置为Serial Wire。

2.配置系统时钟和ADC时钟

        将系统时钟(SYSCLK)频率配置为170 MHz,并设置ADC1的时钟为34 MHz。

3.配置串口

        配置USART2模式(Mode)为异步(Asychronous),其他参数设置均保持默认(波特率为115200),不开启中断。将USART2的两引脚PA2和PA3均设置为上拉(Pull-up)。

4.配置ADC

        配置ADC1的通道1(IN1),选择IN1 Single-ended;在下面的配置(Configuration)区,对几个参数进行调整:

  • ADC的时钟预分频参数(Clock Prescaler)选择Asynchronous clock mode divided by 1,也就是不分频(前面的例子是分频256倍,目的是想得到所需要的采样频率)。本例将用定时器实现对采样频率的控制,所以ADC的时钟可以不用进行分频处理。
  • 将ADC设置(ADC_Settings)参数栏中连续转换模式(Continuous Conversion Mode)设置为Disabled,即不使能,因为本例中ADC采样频率要通过定时器来控制。
  • 转换结束选择(End Of Conversion Selection)参数仍保持单次转换结束(End of single conversion);由于目前只使用了一个ADC通道,还可以选择序列转换结束(End of sequence conversion),对结果没有影响。
  • 在ADC规则转换模式(ADC_Regular_Conversion Mode)栏中,外部触发转换源(External Trigger Conversion Source)选择Timer 3 Trigger Out event,使用TIM3的触发输出作为ADC的触发源。
  • 位于Rank下的采样时间选择2.5个周期。前面提到过,这个参数决定着ADC的转换时间。如果选择2.5个周期,则在12位分辨率时ADC的转换时间为2.5+12+0.5=15个周期。
  • 使能ADC1的中断。

5.设置TIM3

        TIM3的模式(Mode)区,选择时钟源(Clock Source)为内部时钟(InterClock);计数器的预分频因子设置为169,则定时器的时钟频率为系统频率的1/170,如果系统频率为170 MHz,则定时器的时钟频率为1 MHz;计数器的周期设置为999,则计数器的溢出频率为1MHz/1000 =1 kHz。在Trigger Output参数栏中将发事件设置为更新事件(Update Event)。

6.设置TIM4 

        TIM4的模式(Mode)区,选择时钟源(Clock Source)为内部时钟(InterClock);通道1选择PWM Generation CH1;GPIO管脚默认PA11;计数器的预分频因子设置为999,计数器的周期设置为8499,auto reload=Enable;Pulse=2125;

7.配置中断

        将ADC1中断的优先级设为1。此外,由于将会用到HAL_Delay函数,所以要将tick timer中断的占式优先级设为0。

        TIM4的全局中断的优先级设置为2;

8.GPIO

        设置 PA5(LD2) 为GPIO OUTPUT,OUTput level默认LOW,PP,Pullup,High;别名LED;

四、代码修改

1.重新定义ADC回调函数

        在主程序中重写回调函数HAL_ADC_ConvCpltCallback()和串口发数据的putchar函数,并且将它们放到main.c的注释对中:

/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{ADC1ConvertedData[ADC1Data_index] = HAL_ADC_GetValue(&hadc1);if(ADCSampleFlag == 0)ADC1Data_index ++;if(ADC1Data_index == ADC_CONVERTED_DATA_BUFFER_SIZE){ADCSampleFlag = 1;ADC1Data_index = 0;}
}//信号源
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
}//串口打印
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */

2.在主程序中编写数据发送代码

        将数据发送代码放置到main函数的while(1)循环中。

while(1)
/* USER CODE BEGIN 3 */
if(ADCSampleFlag == 1)
{for(uint16_t i=1;i<ADC_CONVERTED_DATA_BUFFER_SIZE;i++){printf("ADC1ConvertedData[%d] = %d\r\n",i,ADC1Convertedata[i]);}ADCSampleFlag = 0;
}
HAL_Delay(1000);
/*USER CODE END 3 */

        上述函数中用到的变量需要定义。仍然是将它们定义为全局变量,放到主程序中的注释中:

/*USER CODE BEGIN PV*/
uint16_t ADC1ConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE];
uint16_t ADC1Data_index =0;
uint8_t ADCSampleFlag =0;
/*USER CODE END PV*/

        其中,数组长度ADC_CONVERTED_DATA_BUFFER_SIZE可以定义到main.h中:

/* USER CODE BEGIN Private defines */
#define ADC_CONVERTED_DATA_BUFFER_SIZE(uint16_t) 65
/* USER CODE END Private defines */

        同时,在main.c中,包含头文件stdio.h:

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

3.使能ADC和开启定时器

        在主程序初始化代码中使能ADC中断,并开启定时器TIM3、TIM4。将HAL_ADC_Sta IT()、HAL_ADCEx_Calibration_Start()、HAL_TIM_Base_Start()、HAL_TIM_Base_Start_IT()HAL_TIM_PWM_Start()放到while(1)之前, MX_ADC1_Init()之后的注释对中: 

  /* USER CODE BEGIN 2 */HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);HAL_ADC_Start_IT(&hadc1);HAL_TIM_Base_Start(&htim3);HAL_TIM_Base_Start_IT(&htim4);HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);/* USER CODE END 2 */

4.查看结果

        把PA5(LD2)信号或者PA11(TIM4_CH1)信号施加信号到ADC1_IN1输入端PA0上,打开串口助手即可收到送上来的数据。

        为了实测ADC的采样频率,同样可以配置PC3作为输出引脚,在回调函数HAL_ADC _ ConvCpltCallback()中加入控制PC3输出状态的语句,并通过示波器测量PC3引脚的输出 形,此时测得的频率为采样频率。

        实测的PA5(LD2)信号:

         实测的串口接收的数据:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/45578.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

json-server服务使用教程

目录标题 安装 json-server启动 json-server 本地服务 安装 json-server npm install -g json-server0.17.4json-server -v报错请参考&#xff1a;执行json-server -v报错 因为在此系统上禁止运行脚本。 启动 json-server 本地服务 查看本机IP&#xff1a;ipconfig Shift右…

220.贪心算法:根据身高重建队列(力扣)

代码解决 class Solution { public:// 定义排序规则&#xff1a;首先按身高降序排序&#xff0c;如果身高相同则按k值升序排序static bool cmp(const vector<int>&a, const vector<int>&b){if (a[0] b[0]) return a[1] < b[1]; // 如果身高相同&#…

51单片机-第三节-LCD1602调试工具,矩阵键盘

一、LCD调试工具函数&#xff1a; 使用&#xff1a; 所有函数&#xff0c;前两个参数&#xff0c;均为指定显示位置。 四个参数的&#xff0c;第四个参数&#xff0c;为保留位数&#xff0c;少的保留后面&#xff08;123,2 -> 23&#xff09;&#xff0c;多的前面补零。 …

Web开发 —— 放大镜效果(HTML、CSS、JavaScript)

目录 一、需求描述 二、实现效果 三、完整代码 四、实现过程 1、HTML 页面结构 2、CSS 元素样式 3、JavaScript动态控制 &#xff08;1&#xff09;获取元素 &#xff08;2&#xff09;控制大图和遮罩层的显隐性 &#xff08;3&#xff09;遮罩层跟随鼠标移动 &…

k8s核心操作_k8s中的存储抽象_基本概念与NFS搭建_Deployment使用NFS进行挂载---分布式云原生部署架构搭建028

然后我们继续开始看 如果我们使用容器部署,比如我们有三个节点,一个是master,一个node1 一个是node2 那么pod 中我们可以看到,容器中的 /data 等各个目录都映射了出来了,但是 如果比如上面红色的部分,有个pod,原来在node2上,最右边那个,但是这个pod宕机了 那么,k8s会在node…

永磁同步电机谐波抑制算法(7)——基于自适应陷波(adaptive notch filter,ANF)的精确谐波电流抑制策略

1.前言 1.1经典谐波抑制策略存在的问题 在之前的谐波抑制专题中&#xff0c;主要介绍了两种谐波抑制策略——基于多同步旋转坐标系的谐波抑制策略以及基于比例积分谐振PIR调节器的谐波抑制策略&#xff0c;同时还介绍了这两种策略的改进办法&#xff0c;进而使得这两种策略在…

Go:基本变量与数据类型

目录 前言 前期准备 Hello World! 一、基本变量 1.1 声明变量 1.2 初始化变量 1.3 变量声明到初始化的过程 1.4 变量值交换 1.5 匿名变量 1.6 变量的作用域 二、数据类型 1.1 整型 1.2 浮点型 1.3 字符串 1.4 布尔类型 1.5 数据类型判断 1.6 数据类型转换 1.…

NewStarCTF 2023 week5--web

目录 Unserialize Again 法一:(非预期) 法二: Final Yes Pickle pppython? 4-复盘 Unserialize Again f12告诉了我们cookie, 查看一下,可以发现 pairing.php <?php highlight_file(__FILE__); error_reporting(0); class story{private $useradmin;public $p…

Centos7 新增yum源

背景&#xff1a;原来的yum源&#xff0c;无法下载yum包了。新增一个阿里云的&#xff08;网易163的源失效了&#xff0c;无法使用&#xff09; Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx86_64&repoos&infrastock error was …

three.js官方案例webgpu_reflection.html学习记录

目录 ​1 判断浏览器是否支持 2 THREE.DirectionalLight 2.1DirectionalLightShadow 3 Texture 3.1 .wrapS 3.2 .wrapT 3.3 .colorSpace 4 创建地面 5 WebGPURenderer 6 OrbitControls 控制器 7 屏幕后处理 import * as THREE from three;import { MeshPhongNodeMa…

简析“请求头”——可以用“头部字典”按需定制请求头

请求头是HTTP请求的重要部分&#xff0c;可以用“头部字典”按需定制请求头。 (笔记模板由python脚本于2024年07月12日 19:28:44创建&#xff0c;本篇笔记适合喜欢钻研web知识点的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free…

RSA算法(C++)

RSA加解密过程 RSA为非对称加密算法&#xff0c;由一对公钥和一对私钥构成&#xff0c;私钥加密公钥解密&#xff0c;公钥加密私钥解密 如下图,D为私密的&#xff0c;假设传输英文字母&#xff0c;我们给英文字母编号A1,B2,C3… RSA加解密过程 两对密钥产生方法如下 C Op…

【RHCE】基于密钥的身份验证(Win-Linux)

目的&#xff1a;要提⾼系统安全性&#xff0c;通过在 OpenSSH 服务器上禁⽤密码⾝份验证来强制进⾏基于密钥的⾝份验证。 1、一台虚拟机无需密码连接另一台虚拟机 .ssh目录 > 保存了ssh相关的key和一些记录文件 &#xff08;1&#xff09;生成密钥对 使⽤这个流程在本地…

U盘打不开的终极解决方案:原因剖析、恢复策略与预防之道

U盘困境&#xff1a;打不开的焦虑与应对 在数字化时代&#xff0c;U盘作为数据交换与存储的重要工具&#xff0c;几乎成为了每个人工作、学习和生活中的必需品。然而&#xff0c;当您满怀期待地将U盘插入电脑&#xff0c;却遭遇“无法识别”、“无法访问”等提示&#xff0c;U…

【人工智能】Transformers之Pipeline(一):音频分类(audio-classification)

​​​​​​​ 目录 一、引言 二、音频分类&#xff08;audio-classification&#xff09; 2.1 概述 2.2 技术原理 2.2.1 Wav2vec 2.0模型 2.2.1 HuBERT模型 2.3 pipeline参数 2.3.1 pipeline对象实例化参数 2.3.2 pipeline对象使用参数 2.4 pipeline实战 2.4.1 …

【Qt 基础】Qt Creator 的初步使用、创建项目的过程

文章目录 1. Qt SDK 中工具程序的介绍2. 创建第一个 Qt 项目的前置步骤 1. Qt SDK 中工具程序的介绍 下载之后会出现下面几个程序&#xff1a; Assistant 表示 Qt 自带的离线官方文档&#xff1b; Designer &#xff1a;Qt设计师&#xff0c;图形化的设计界面的工具&#xf…

C++程序进阶学习

目录 引言 C内存分区 一、内存分区模型 二、 程序运行前 三、程序执行后 C引用 引用的语法 作用 本质 优点 C封装 C对象特性 C对象模型和this指针 C友元 C运算符重载 C继承 C多态 C文件 引言 看过我博客的朋友可能都了解这篇文章内容了&#xff0c;这篇博…

超声波清洗机哪家好?家用超声波眼镜清洗机推荐

超声波清洗机现在已经成为了很多家庭的新宠&#xff0c;它能够帮助我们轻松解决日常生活中的清扫烦恼。但是&#xff0c;面对市面上品种繁多的清洗机产品&#xff0c;我们该如何选择一款适合自己的呢?毕竟不同的品牌和型号&#xff0c;在清洗效果、噪音水平、除菌能力等方面都…

RHCE-autofs自动挂载

要求 一、在主机上提供web&#xff0c;dns服务 服务端 IP&#xff1a;172.25.250.131/24 dns&#xff1a;172.25.250.131 [rootlocalhost ~]# cd /etc/httpd/conf.d[rootlocalhost conf.d]# vim vhost.conf [rootlocalhost conf.d]# mkdir /nfs/rhce -p[rootlocalhost conf…

雪深监测站的工作原理

TH-TS200雪深监测站是一种用于测量和记录雪层深度的设备&#xff0c;它在气象观测、交通管理、防灾减灾、水源管理等多个领域发挥着重要作用。雪深监测用来监测雪深的设备。它通过各种传感器和测量设备&#xff0c;如超声波测距仪、激光测距仪、压力传感器等&#xff0c;获取雪…