STM32的HAL库开发---高级定时器---输出比较模式实验
一、高级定时器输出比较模式实验原理
定时器的输出比较模式总共有8种,本文使用其中的翻转模式,当TIMXCCR1=TIMXCNT时,翻转OC1REF的电平,OC1REF为输出参考信号,高电平有效,OC1REF信号连接到0C1上面,然后控制CH1输出,CH1通过IO口复用功能,连接到IO口上面,最后输出到外部。
计时器工作在递增模式:

当CNT的值不断递增,递增到于输出比较寄存器CCR1的值相同时,IO电平翻转,然后CNT值继续递增,递增到ARR时,产生计数器溢出事件,计数器值从0开始重新递增,通过这种方式产生方波或者称为PWM波。
周期:IO口输出高电平和低电平总和为一个方波周期,从图上可以看出,一个方波周期为两次计数器溢出的事件,也就是2*(ARR + 1)*t,t为计时器计一个数所需时间。
占空比:再翻转模式下,占空比固定为50%,不可以改变。
总结:PWM波周期或频率由ARR决定,占空比固定50%,相位由CCRX决定。
二、高级定时器输出比较模式实验配置步骤
1、HAL_TIM_OC_Init()函数,配置定时器基础工作参数。
2、HAL_TIM_OC_Msplnit()函数,配置NVIC、CLOCK、GPIO等
3、HAL_TIM_OC_Configchannel()函数,配置输出比较模式。
4、__HAL_TIM_ENABLE_OCxPRELOAD()宏定义,使能通道预装载。
5、HAL_TIM_OC_Start()函数,使能输出、主输出、计数器。
6、__HAL_TIM_SET_COMPARE()宏定义,修改捕获/比较寄存器的值。

三、高级定时器输出比较模式实验
实验:通过定时器8通道1/2/3/4输出相位分别为25%、50%、75%、100%的PWM

1、寄存器版本
#include "./BSP/TIMER/atim.h"//配置定时器8通道1 PC6、PC7、PC8、PC9为翻转模式输出
void Advanced_TIM_Init(void)
{//开启TIM8时钟RCC->APB2ENR |= (1 << 13);//开启ARR寄存器缓冲功能TIM8->CR1 |= (1 << 7);//设置PSC预分频系数TIM8->PSC = 71;//设置重装载寄存器值 配置PWM方波为500HZ//在翻转模式下 两个ARR溢出时间为PWM一个周期TIM8->ARR = (1000000 / (500 * 2)) - 1;/**************TIM8_CH1*****************///CC1S 设置捕获比较为输出模式TIM8->CCMR1 &= ~(0x03 << 0);//OC1PE 开启输出比较寄存器预装载功能TIM8->CCMR1 |= (1 << 3);//OC1M 设置为翻转模式TIM8->CCMR1 |= (0X03 << 4);TIM8->CCMR1 &= ~(1 << 6);//设置CCR1捕获/比较寄存器值 25%相位TIM8->CCR1 = 0.25 * (1000000 / (500 * 2)) - 1;//TIM8->CCR1 =1;//设置输出极性为高电平有效 CC1PTIM8->CCER &= ~(1 << 1);//使能输出比较 CC1ETIM8->CCER |= (1 << 0);/**************TIM8_CH2*****************///CC2S 设置捕获比较为输出模式TIM8->CCMR1 &= ~(0x03 << 8);//OC2PE 开启输出比较寄存器预装载功能TIM8->CCMR1 |= (1 << 11);//OC2M 设置为翻转模式TIM8->CCMR1 |= (0X03 << 12);TIM8->CCMR1 &= ~(1 << 14); //设置CCR2捕获/比较寄存器值 50%相位TIM8->CCR2 = 0.50 * (1000000 / (500 * 2)) - 1;//设置输出极性为高电平有效 CC2PTIM8->CCER &= ~(1 << 5);//使能输出比较 CC2ETIM8->CCER |= (1 << 4);/**************TIM8_CH3*****************///CC3S 设置捕获比较为输出模式TIM8->CCMR2 &= ~(0x03 << 0);//OC3PE 开启输出比较寄存器预装载功能TIM8->CCMR2 |= (1 << 3);//OC3M 设置为翻转模式TIM8->CCMR2 |= (0X03 << 4);TIM8->CCMR2 &= ~(1 << 6);//设置CCR3捕获/比较寄存器值 75%相位TIM8->CCR3 = 0.75 * (1000000 / (500 * 2)) - 1;//设置输出极性为高电平有效 CC3PTIM8->CCER &= ~(1 << 9);//使能输出比较 CC3ETIM8->CCER |= (1 << 8);/**************TIM8_CH4*****************///CC4S 设置捕获比较为输出模式TIM8->CCMR2 &= ~(0x03 << 8);//OC4PE 开启输出比较寄存器预装载功能TIM8->CCMR2 |= (1 << 11);//OC4M 设置为翻转模式TIM8->CCMR2 |= (0X03 << 12);TIM8->CCMR2 &= ~(1 << 14); //设置CCR4捕获/比较寄存器值 100%相位TIM8->CCR4 = 1 * (1000000 / (500 * 2)) - 1;//设置输出极性为高电平有效 CC4PTIM8->CCER &= ~(1 << 13);//使能输出比较 CC4ETIM8->CCER |= (1 << 12);//软件更新事件 主要为将PSC的值转移到影子寄存器里边TIM8->EGR |= (1 << 0);//MOE 开启主输出TIM8->BDTR |= (1 << 15);//开启GPIOC时钟RCC->APB2ENR |= (1 << 4);//设置PC6为复用推挽输出GPIOC->CRL |= (0X03 << 24);GPIOC->CRL |= (1 << 27);GPIOC->CRL &= ~(1 << 26);//设置PC7为复用推挽输出GPIOC->CRL |= (0X03 << 28);GPIOC->CRL |= (1 << 31);GPIOC->CRL &= ~(1 << 30);//设置PC8为复用推挽输出GPIOC->CRH |= (0X03 << 0);GPIOC->CRH |= (1 << 3);GPIOC->CRH &= ~(1 << 2);//设置PC9为复用推挽输出GPIOC->CRH |= (0X03 << 4);GPIOC->CRH |= (1 << 7);GPIOC->CRH &= ~(1 << 6);//使能计数器TIM8->CR1 |= (1 << 0); }
2、库函数版本
atim.h头文件程序
#ifndef __ATIM_H
#define __ATIM_H#include "stm32f1xx.h"
void Advanced_TIM_Init(void);#endif
atim.c
#include "./BSP/TIMER/atim.h"//配置定时器8通道1 PC6为翻转模式输出
TIM_HandleTypeDef htim;
void Advanced_TIM_Init(void)
{htim.Instance = TIM8;htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;htim.Init.CounterMode = TIM_COUNTERMODE_UP;htim.Init.Period = 1000000/(500 * 2) - 1;htim.Init.Prescaler = 71;HAL_TIM_OC_Init(&htim);TIM_OC_InitTypeDef sConfig = {0};sConfig.OCMode = TIM_OCMODE_TOGGLE;sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;sConfig.Pulse = 0.25 * (TIM8->ARR + 1) - 1;//配置TIM8 CH1为翻转输出模式HAL_TIM_OC_ConfigChannel(&htim,&sConfig,TIM_CHANNEL_1);//配置TIM8 CH2为翻转输出模式sConfig.Pulse = 0.50 * (TIM8->ARR + 1) - 1;HAL_TIM_OC_ConfigChannel(&htim,&sConfig,TIM_CHANNEL_2);//配置TIM8 CH3为翻转输出模式sConfig.Pulse = 0.75 * (TIM8->ARR + 1) - 1;HAL_TIM_OC_ConfigChannel(&htim,&sConfig,TIM_CHANNEL_3);//配置TIM8 CH4为翻转输出模式sConfig.Pulse = 1 * TIM8->ARR;HAL_TIM_OC_ConfigChannel(&htim,&sConfig,TIM_CHANNEL_4);//使能捕获/比较寄存器通道1预装载__HAL_TIM_ENABLE_OCxPRELOAD(&htim,TIM_CHANNEL_1);//使能捕获/比较寄存器通道2预装载__HAL_TIM_ENABLE_OCxPRELOAD(&htim,TIM_CHANNEL_2);//使能捕获/比较寄存器通道3预装载__HAL_TIM_ENABLE_OCxPRELOAD(&htim,TIM_CHANNEL_3);//使能捕获/比较寄存器通道4预装载__HAL_TIM_ENABLE_OCxPRELOAD(&htim,TIM_CHANNEL_4);TIM8->EGR |= (1 << 0);//启动TIM8 CH1计数器 主输出 输出比较HAL_TIM_OC_Start(&htim, TIM_CHANNEL_1);//启动TIM8 CH2计数器 主输出 输出比较HAL_TIM_OC_Start(&htim, TIM_CHANNEL_2);//启动TIM8 CH3计数器 主输出 输出比较HAL_TIM_OC_Start(&htim, TIM_CHANNEL_3);//启动TIM8 CH4计数器 主输出 输出比较HAL_TIM_OC_Start(&htim, TIM_CHANNEL_4);
}void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{//开启定时器8时钟__HAL_RCC_TIM8_CLK_ENABLE();//开启GPIOC时钟__HAL_RCC_GPIOC_CLK_ENABLE();GPIO_InitTypeDef GPIO_Init = {0};GPIO_Init.Mode = GPIO_MODE_AF_PP;GPIO_Init.Pin = GPIO_PIN_6;//设置为输出模式时 这个没有用 可以不写 GPIO_Init.Pull = GPIO_NOPULL;GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;//设置PC6为复用推挽输出HAL_GPIO_Init(GPIOC, &GPIO_Init);GPIO_Init.Pin = GPIO_PIN_7;//设置PC7为复用推挽输出HAL_GPIO_Init(GPIOC, &GPIO_Init);GPIO_Init.Pin = GPIO_PIN_8;//设置PC8为复用推挽输出HAL_GPIO_Init(GPIOC, &GPIO_Init);GPIO_Init.Pin = GPIO_PIN_9;//设置PC9为复用推挽输出HAL_GPIO_Init(GPIOC, &GPIO_Init);}
main.c主函数程序
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/atim.h"extern TIM_HandleTypeDef htim;
int main(void)
{HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */led_Init(); /* LED初始化 */Advanced_TIM_Init(); //高级定时器初始化
// __HAL_TIM_SET_COMPARE(&htim, TIM_CHANNEL_1, 0);
// __HAL_TIM_SET_COMPARE(&htim, TIM_CHANNEL_2, 500 - 1);
// __HAL_TIM_SET_COMPARE(&htim, TIM_CHANNEL_3, 750 - 1);
// __HAL_TIM_SET_COMPARE(&htim, TIM_CHANNEL_4, 1000 - 1);while(1){ LED0(1);LED1(0);delay_ms(500);LED0(0);LED1(1);delay_ms(500);}
}
在配置过程中发现,如果捕获比较寄存器的值在初始化的时候设置成0,会导致相位错误,设置成1就不会。但是在初始化之后再将比较寄存器的值设置成0,相位正确。这个问题具体原因还没找到,如果有人有思路,可以私信我。
相关文章:
STM32的HAL库开发---高级定时器---输出比较模式实验
一、高级定时器输出比较模式实验原理 定时器的输出比较模式总共有8种,本文使用其中的翻转模式,当TIMXCCR1TIMXCNT时,翻转OC1REF的电平,OC1REF为输出参考信号,高电平有效,OC1REF信号连接到0C1上面ÿ…...
python Excel 表读取合并单元格以及清除空格符
读取合并单元格并保留合并信息 读取合并单元格并保留合并信息清除各单元格的空格和换行符,并去除列名中的空格和换行符 读取合并单元格并保留合并信息 当我们只是使用 pandas 的 read_excel 方法读取 Excel 文件时,我们可能会遇到一个很棘手的问题&…...
额外题目汇总2-链表
链表 1.24. 两两交换链表中的节点 力扣题目链接(opens new window) 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 思路 使用虚拟头结点会很方便ÿ…...
C#控件开发6—指示灯
按钮功能:手自动旋转,标签文本显示、点击二次弹框确认(源码在最后边); 【制作方法】 找到控件的中心坐标,画背景外环、内圆;再绘制矩形开关,进行角度旋转即可获得; 【关…...
探索从传统检索增强生成(RAG)到缓存增强生成(CAG)的转变
在人工智能快速发展的当下,大型语言模型(LLMs)已成为众多应用的核心技术。检索增强生成(RAG)(RAG 系统从 POC 到生产应用:全面解析与实践指南)和缓存增强生成(CAG&#x…...
【学习总结|DAY036】Vue工程化+ElementPlus
引言 在前端开发领域,Vue 作为一款流行的 JavaScript 框架,结合 ElementPlus 组件库,为开发者提供了强大的构建用户界面的能力。本文将结合学习内容,详细介绍 Vue 工程化开发流程以及 ElementPlus 的使用,助力开发者快…...
【GitHub】GitHub 2FA 双因素认证 ( 使用 Microsoft Authenticator 应用进行二次验证 )
文章目录 一、GitHub 的 2FA 双因素认证二、使用 Microsoft Authenticator 应用进行二次验证1、TOTP 应用2、下载 Microsoft Authenticator 应用3、安装使用 Authenticator 应用 三、恢复码重要性 一、GitHub 的 2FA 双因素认证 现在登录 GitHub 需要进行二次身份验证 ; 先登录…...
c# 2025/2/7 周五
13.《表达式,语句详解1》 18未完。。 表达式,语句详解_1_哔哩哔哩_bilibili...
蓝桥杯思维训练(五)
文章目录 子集II1191.K次串联后最大子数组之和 子集II 子集II 思路分析: 求解子集的问题的关键就是,通过递归与回溯,我们就是得确定以某个元素开始的子集,对于这个题目来说,比较麻烦的一点就是,存在重复的…...
I.MX6ULL 中断介绍下
GIC重点寄存器 1.中断分发器寄存器(Distributor register ) a.Distributor Control Register(中断分发控制寄存器), GICD_CTLR Purpose Enables the forwarding of pending interrupts from the Distributor to the CPU interfaces 使能将挂起的中断从…...
Elasticsearch 生产集群部署终极方案
Elasticsearch 集群部署 1.集群部署1.1 新增用户1.2 优化操作系统1.3 JDK1.4 elasticsearch1.5 开机自启动 2.安全认证功能2.1 生成CA证书2.2 生成密钥2.3 上传至其他节点2.4 修改属主、属组2.5 配置文件添加参数2.6 各节点添加密钥库密码2.7 设置用户密码 1.集群部署 1.1 新增…...
Python用langchain、OpenAI大语言模型LLM情感分析苹果股票新闻数据及提示工程优化应用...
全文链接:https://tecdat.cn/?p39614 本文主要探讨了如何利用大语言模型(LLMs)进行股票分析。通过使用提供的股票市场和金融新闻获取数据,结合Python中的相关库,如Pandas、langchain等,实现对股票新闻的情…...
【正点原子K210连载】第六十七章 音频FFT实验 摘自【正点原子】DNK210使用指南-CanMV版指南
第六十七章 音频FFT实验 本章将介绍CanMV下FFT的应用,通过将时域采集到的音频数据通过FFT为频域。通过本章的学习,读者将学习到CanMV下控制FFT加速器进行FFT的使用。 本章分为如下几个小节: 32.1 maix.FFT模块介绍 32.2 硬件设计 32.3 程序设…...
Centos Ollama + Deepseek-r1+Chatbox运行环境搭建
Centos Ollama Deepseek-r1Chatbox运行环境搭建 内容介绍下载ollama在Ollama运行DeepSeek-r1模型使用chatbox连接ollama api 内容介绍 你好! 这篇文章简单讲述一下如何在linux环境搭建 Ollama Deepseek-r1。并在本地安装的Chatbox中进行远程调用 下载ollama 登…...
ReactNative进阶(五十九):存量 react-native 项目适配 HarmonyOS NEXT
文章目录 一、前言二、ohos_react_native2.1 Fabric2.2 TurboModule2.2.1 ArkTSTurboModule2.2.2 cxxTurboModule: 三、拓展阅读 一、前言 2024年10月22日19:00,华为在深圳举办“原生鸿蒙之夜暨华为全场景新品发布会”,主题为“星河璀璨&…...
go并发和并行
进程和线程 进程(Process)就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位,进程是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,每一个进程都有一个自己的地址空间。…...
一种解决SoC总线功能验证完备性的技术
1. 前言 通过总线将各个IP通过总线连接起来的SoC芯片是未来的大趋势,也是缩短芯片开发周期,抢先进入市场的常用方法。如何确保各个IP是否正确连接到总线上,而且各IP的地址空间分配是否正确,是一件很棘手的事情。本文提出了一种新…...
Web3 与区块链:开启透明、安全的网络新时代
在这个信息爆炸的时代,我们对网络的透明性、安全性和隐私保护的需求日益增长。Web3,作为新一代互联网的代表,正携手区块链技术,引领我们走向一个更加透明、安全和去中心化的网络世界。本文将深入探讨 Web3 的基本概念、区块链技术…...
c#中Thread.Join()方法的经典示例
在 C# 中,Thread.Join 是一个非常有用的方法,它可以让主线程(调用线程)等待子线程(被调用线程)执行完毕后再继续执行。 1、经典示例1 using System; using System.Threading;public class Example {stati…...
深入了解越权漏洞:概念、危害与防范
前言 越权漏洞作为一种常见且极具威胁的安全隐患,就像隐藏在暗处的 “黑客帮凶”,时刻威胁着我们的数据安全和隐私。就让我们一起揭开越权漏洞的神秘面纱,深入了解它的来龙去脉、危害以及应对之策。 一、什么是越权漏洞 想象一下࿰…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
