STM32——通用定时器脉冲计数实验

1.脉冲计数实验原理

在这里插入图片描述

2.从模式配置结构体

typedef struct
{
uint32_t SlaveMode; /* 从模式选择 /
uint32_t InputTrigger; /
输入触发源选择 /
uint32_t TriggerPolarity; /
输入触发极性 /
uint32_t TriggerPrescaler; /
输入触发预分频 /
uint32_t TriggerFilter; /
输入滤波器设置 */
} TIM_SlaveConfigTypeDef;

3.实验要求

1.将定时器2通道1输入的高电平脉冲作为定时器2的时钟,并通过串口打印脉冲数。
2.配置从模式:外部时钟模式1、触发选择、上升沿触发、不分频、不滤波。

4.输入脉冲实验配置步骤

1,配置定时器基础工作参数 HAL_TIM_IC_Init()
2,定时器输入捕获MSP初始化 HAL_TIM_IC_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置定时器从模式等 HAL_TIM_SlaveConfigSynchro()
4,使能输入捕获并启动计数器 HAL_TIM_IC_Start()
5,获取计数器的值 __HAL_TIM_GET_COUNTER()
6,设置计数器的值 __HAL_TIM_SET_COUNTER()

5.输入脉冲实验配置步骤

5.1 gtim.c

#include "./BSP/TIMER/gtim.h"
#include "./BSP/LED/led.h"
#include "./SYSTEM/usart/usart.h"


/******************************定时器脉冲计数实验*****************************************/
//1.定时器句柄定义
TIM_HandleTypeDef    g_timx_cnt_chy_handle;                     //定时器x句柄
uint32_t g_timxchy_cnt_ofcnt = 0;                               //溢出累计次数

//2.通用定时器脉冲通道 初始化函数
//基本工作参数配置
// * @note
// *              通用定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候
// *              通用定时器的时钟为APB1时钟的2倍, 而APB1为42M, 所以定时器时钟 = 84Mhz
// *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
// *              Ft=定时器工作频率,单位:Mhz
// *
// * @param       arr: 自动重装值
// * @param       psc: 预分频系数
// * @retval      无
void gtim_timx_cnt_chy_init(uint16_t psc)
{
    TIM_SlaveConfigTypeDef timx_slave_config = {0};                
    
    //2.1定时器句柄初始化、包括定时器2基地址、自动重装载值、预分频系数
    g_timx_cnt_chy_handle.Instance = GTIM_TIMX_CNT;                //定时器2 
    g_timx_cnt_chy_handle.Init.Prescaler = psc;                    //预分频系数 
    g_timx_cnt_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;   //向上计数模式 
    g_timx_cnt_chy_handle.Init.Period = 65535;                     //自动重装载值为65535
    HAL_TIM_IC_Init(&g_timx_cnt_chy_handle);                       //初始化定时器 
    
    //3 定时器从模式配置
    timx_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;           //从模式:外部触发模式1
    timx_slave_config.InputTrigger = TIM_TS_TI1FP1;                  //输入触发:选择 TI1FP1(TIMX_CH1) 作为输入源
    timx_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;  // 极性选择:上升沿  
    timx_slave_config.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;  //触发预分频:无
    timx_slave_config.TriggerFilter = 0;                             // 配置输入滤波器,不滤波 
    HAL_TIM_SlaveConfigSynchro(&g_timx_cnt_chy_handle,&timx_slave_config);//定时器从模式初始化配置

    //4 使能更新中断
    __HAL_TIM_ENABLE_IT(&g_timx_cnt_chy_handle, TIM_IT_UPDATE);
    //5 输入捕获使能、启动计数器
    HAL_TIM_IC_Start(&g_timx_cnt_chy_handle,GTIM_TIMX_CNT_CHY);
}

//3.定时器输入捕获MSP(MCU Specific Package)初始化
// @param       htim:定时器句柄
// @note        此函数会被HAL_TIM_IC_Init()调用
// @retval      无
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == GTIM_TIMX_CNT)
    {
        GPIO_InitTypeDef gpio_init_struct;           //gpio结构体定义
        //定时器时钟使能
        GTIM_TIMX_CNT_CHY_CLK_ENABLE();
        //GPIO时钟使能
        GTIM_TIMX_CNT_CHY_GPIO_CLK_ENABLE();
        
        //GPIO初始化
        gpio_init_struct.Pin = GTIM_TIMX_CNT_CHY_GPIO_PIN;        //输入捕获的GPIO口
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;                  //复用推挽输出
        gpio_init_struct.Pull = GPIO_PULLDOWN;                    //下拉
        gpio_init_struct.Alternate =GTIM_TIMX_CNT_CHY_GPIO_AF;    //复用为捕获TIM2的通道1
        HAL_GPIO_Init(GTIM_TIMX_CNT_CHY_GPIO_PORT, &gpio_init_struct);
        
    }
  
}

//6.获取计数器的值
// * @param       无
// * @retval      当前计数值
uint32_t gtim_timx_cnt_chy_get_count()
{
    uint32_t count = 0;                                            //定义计数总值变量
    count = g_timxchy_cnt_ofcnt * 65536;                          //计算溢出次数 x arr 之积
    count += __HAL_TIM_GET_COUNTER(&g_timx_cnt_chy_handle);        //加上当前CNT的值
    return count;
}
//7.计数器的值重置函数
// * @param       无
// * @retval      无
void gtim_timx_cnt_chy_restart()
{
    __HAL_TIM_DISABLE(&g_timx_cnt_chy_handle);       //关闭定时器
    g_timxchy_cnt_ofcnt = 0;                         //累计溢出次数清零
    __HAL_TIM_SET_COUNTER(&g_timx_cnt_chy_handle,0); //计数器清零
    __HAL_TIM_ENABLE(&g_timx_cnt_chy_handle);        //定时器使能
   
}

//8.更新中断服务函数
// * @param       无
// * @retval      无
void GTIM_TIMX_CNT_IRQHandler()
{
    //没有使用定时器HAL库公共处理函数,通过判断中断标注为实现溢出次数的累加
    if(__HAL_TIM_GET_FLAG(&g_timx_cnt_chy_handle,TIM_FLAG_UPDATE) != RESET)
    {
        g_timxchy_cnt_ofcnt++;              //累计溢出次数
    }
    __HAL_TIM_CLEAR_IT(&g_timx_cnt_chy_handle,TIM_IT_UPDATE);  //清理TIM开启时的中断标识
}

5.2 gtim.h

#ifndef __GTIM_H
#define __GTIM_H

#include "./SYSTEM/sys/sys.h"

/* TIMX 输入计数定义
* 这里的输入计数使用定时器TIM2_CH1,捕获WK_UP按键的输入
* 默认是针对TIM2~TIM5, 只有CH1和CH2通道可以用做输入计数, CH3/CH4不支持!
* 注意: 通过修改这几个宏定义,可以支持TIM1~TIM8任意一个定时器,CH1/CH2对应IO口做输入计数
*       特别要注意:默认用的PA0,设置的是下拉输入!如果改其他IO,对应的上下拉方式也得改!
*/
#define GTIM_TIMX_CNT_CHY_GPIO_PORT            GPIOA
#define GTIM_TIMX_CNT_CHY_GPIO_PIN             GPIO_PIN_0
#define GTIM_TIMX_CNT_CHY_GPIO_AF              GPIO_AF1_TIM2                                /* AF功能选择 */
#define GTIM_TIMX_CNT_CHY_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)  /* PA口时钟使能 */

#define GTIM_TIMX_CNT                          TIM2
#define GTIM_TIMX_CNT_IRQn                     TIM2_IRQn
#define GTIM_TIMX_CNT_IRQHandler               TIM2_IRQHandler
#define GTIM_TIMX_CNT_CHY                      TIM_CHANNEL_1                                /* 通道Y,  1<= Y <=2 */
#define GTIM_TIMX_CNT_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM2_CLK_ENABLE(); }while(0)   /* TIM2 时钟使能 */

void gtim_timx_cnt_chy_init(uint16_t psc);              /* 通用定时器 脉冲计数初始化函数 */
uint32_t gtim_timx_cnt_chy_get_count();                 /* 通用定时器 获取脉冲计数 */
void gtim_timx_cnt_chy_restart();                       /* 通用定时器 重启计数器 */

#endif

5.3 main.c

int main(void)
{

    //变量定义:包括新、老计数值、key值、以及循环计数
    uint32_t curcnt =0;
    uint32_t oldcnt =0;
    uint8_t key =0;
    uint8_t t =0;
    
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */
    delay_init(168);                            /* 延时初始化 */
    usart_init(115200);                         /* 串口初始化为115200 */
    led_init();                                 /* 初始化LED */
    key_init();                                 /* 初始化按键 */
    //调用通用定时器通道计数初始化函数与计数器的值重置函数
    gtim_timx_cnt_chy_init(0);                  //通用定时器初始化 不分屏
    gtim_timx_cnt_chy_restart();                //计数器重置
    
    while (1)
    {
        //KEY0控制计数器重置
        key = key_scan(0);                      //扫描按键
        if(key == KEY0_PRES)
        {
            printf("KEY0 PRESS\r\n");
            gtim_timx_cnt_chy_restart();        //重置
        
        }
        //获取计数值,打印计数值
        curcnt = gtim_timx_cnt_chy_get_count();
        if (oldcnt != curcnt)
        {
            oldcnt = curcnt;
            printf("CNT:%d\r\n", oldcnt);       /* 打印脉冲个数 */
        }
        //每200msLED0闪烁一次
        t++;
        if(t>20)
        {
            t=0;
            LED0_TOGGLE();
        }
        delay_ms(10);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法回忆录——排序

文章目录 1. 插入排序2. 选择排序3. 冒泡排序4. 希尔排序5. 归并排序6. 快速排序7. 堆排序8. 计数排序9. 桶排序10. 基数排序 1. 插入排序 分为两个序列&#xff0c;前面一个序列是排好序的&#xff0c;后面一个序列是未排好的。未排好的序列的第一个元素&#xff08;a&#x…

STM32H5培训(二)性能提升与功耗优化

文章目录 1. 前言2. 性能提升3. 功耗优化参考&#xff1a; 1. 前言 本篇主要介绍STM32H5系列的性能提升和功耗优化方面的具体表现。H5系列相比于F4系列在性能和功能上有较大的升级&#xff0c;包括更强的内核、更高的主频、更快的flash访问速度、更丰富的通信接口和先进的安全…

【算法Hot100系列】有效的数独

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

在wsl中安装miniconda

下载安装包 打卡miniconda的官网https://docs.conda.io/projects/miniconda/en/latest/,下载下来安装包&#xff0c;或者直接在乌班图中运行命令wget https://repo.anaconda.com/miniconda/Miniconda3-py38_23.5.2-0-Linux-x86_64.sh,等待下载完毕 安装 到下载目录下执行命令…

Spring MVC入门案例!!!

1.先加入架包&#xff08;我这里使用了tomcat插件&#xff0c;你也可以直接按照原本的方式使用tomcat&#xff09; <packaging>war</packaging><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8&l…

R语言(12):绘图

12.1 创建图形 12.1.1 plot函数 plot(c(1,2,3),c(1,2,4)) plot(c(1,2,3),c(1,2,4),"b") plot(c(-3,3),c(-1,5),"n",xlab "x",ylab "y")12.1.2 添加线条&#xff1a;abline()函数 x <- c(1,2,3) y <- c(1,3,8) plot(x,y) lm…

飞塔FortiGate-1000C设备引进助力易天构建网络安全新防线

在当今数字化浪潮的推动下&#xff0c;企业对网络安全的需求日益迫切。为了应对不断升级的网络威胁&#xff0c;给客户提供最为优质的产品&#xff0c;易天引进了最新兼容性测试设备飞塔FortiGate-1000C&#xff0c;为光模块产品交付提供了更强劲的性能保障。 FortiGate-1000C是…

还不了解 Dockerfile 的同学不是好测试人

前言&#xff1a;近年来 Docker 非常火&#xff0c;想要玩好 Docker 的话 Dockerfile 是绕不开的&#xff0c;这就好比想要玩好 Linux 服务器绕不开 shell 道理是一样的。 今天我们就来聊一聊 Dockerfile 怎么写&#xff0c;那些指令到底是什么意思。 一、先来看一个简单的 D…

消息中间件

一、 消息中间件的介绍 消息中间件属于分布式系统中的子系统&#xff0c;关注数据的发送和接收&#xff0c;利用高效、可靠的异步消息传递机制&#xff0c;对分布式系统中的各个子系统进行集成。 1.1 为什么使用消息中间件 异步 解耦 缓冲能力 伸缩性 提高系统扩展性1.2 消息…

C++11新特性(也称c++2.0)

目录 1.输出C版本&#xff1a;cout << __cplusplus << endl; 2.Uniform Initialization(一致性初始化) 3.initializer_list&#xff08;形参&#xff09; 4.explicit 5.for循环的新用法 6.default和delete 7.Alias Template&#xff08;模板化名&#xff09…

Linux ssh 实现远程免密登录

一、背景 我搭建了一个 zookeeper 集群&#xff0c;写了一个 shell 脚本来控制集群的启动和关闭&#xff0c;但是我发现每次我执行 shell 脚本的时候&#xff0c;都需要我输入各个服务器的密码才可以运行&#xff0c;感觉很麻烦。shell 脚本里面连接其他服务器用的就是 ssh 的方…

HarmonOS 日期选择组件(DatePicker)

本文 我们一起来看基础组件中的 DatePicker 这就是 日程开发中的日期组件 他可以创建一个日期的范围 并创建一个日期的滑动选择器 这里 我们先写一个组件的骨架 Entry Component struct Index {build() {Row() {Column() {}.width(100%)}.height(100%)} }然后 我们先在Column组…

Redis:原理速成+项目实战——Redis实战5(互斥锁、逻辑过期解决缓存击穿问题)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理速成项目实战——Redis实战4&#xff08;解决Redis缓存穿透、雪崩、击穿&#xff09; &#x1f4da;订阅专…

想学习云计算么?教你如何免费白嫖微软和AWS的云资源一年

在这个数字化飞速发展的时代&#xff0c;云计算已成为IT行业的未来趋势。作为一名渴望进步的IT专业人员&#xff0c;掌握云计算不仅意味着技能的提升&#xff0c;更是升职加薪、拓宽职业道路的重要跳板。这里教你如何免费利用微软Azure和亚马逊AWS的云资源&#xff0c;为期一年…

oracle11范围表空间实例

1.表分区&#xff1a;范围分区&#xff0c;散列分区&#xff0c;列表分区&#xff0c;组合分区&#xff0c;inetrval分区 范围分区&#xff1a;商品零售表&#xff0c;按照销售日期所在的季度创建4个分区 --先建立表空间&#xff1a;临时表空间是不可以存放数据的&#xff0c;…

Python——数据类型转换

# 将数字类型转换成字符串 num_str str(111) print(type(num_str), num_str) \# 将浮点类型转换成字符串 float_str str(12.34) print(type(float_str), float_str) # 将字符串转变成数字 num int("234") print(type(num)) # 将字符串转变成浮点型 num2 float(&q…

Java学习笔记-day05-响应式编程初探-自定义实现Reactive Streams规范

最近在学响应式编程&#xff0c;这里先记录下&#xff0c;响应式编程的一些基础内容 1.名词解释 Reactive Streams、Reactor、WebFlux以及响应式编程之间存在密切的关系&#xff0c;它们共同构成了在Java生态系统中处理异步和响应式编程的一系列工具和框架。 Reactive Streams…

12.8-1.8

2023.12.8 redis容器 docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf redis.conf不存在&#xff0c;需先在宿主机创建该目录下文件&#xff0c…

知识点整理[(GraphGeo)RELATED WORK]

2 RELATED WORK 2.1 IP Geolocation 问题一:IP定位预测方法之一:Data mining-based methods 回答: 依赖于在公开的资源中挖掘位置线索来对目标IP(target IP)进行地理定位。其中一些数据分析了来自与IP相关的数据库,如WHOIS数据库和DNS的数据。 (1)例如,Moore等…

Transformer架构的局限已凸显,被取代还有多久?

江山代有才人出&#xff0c;各领风骚数百年。这句话无论是放在古往今来的人类身上&#xff0c;还是放在当今人工智能领域的大模型之上&#xff0c;都是最贴切不过的。无论是一个时代的伟人&#xff0c;还是统治一个领域的技术&#xff0c;最终都会有新的挑战者将其替代。Transf…