STM32 定时器TIM

定时器基础知识

定时器就是用来定时的机器,是存在于STM32单片机中的一个外设。STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TIM6、TIM7),如下图所示:

STM32F10X系列总共最多有八个定时器

三种STM32定时器的区别:

向上是指1234逐个递增计数,向下是指逐个递减计数,向上/向下是指中央对齐模式(基本定时器只能向上,上图写错了) ,捕获指的是输入捕获,比较指的是输出比较

基本定时器

1. 时钟源 2. 控制器 3. 时基单元

时钟源

时钟源来自RCC的TIMx_CLK(属于内部的CK_INIT)

外设挂载在总线下的APB1对应的是时钟2~时钟7(所以我们的基本定时器TIM6 TIM7在APB1下的)

根据时钟树

因为AHB 72M,(AHB默认分频是2)所以APB1是 36M,(APB1默认分频是2)所以根据(如果APB1预分频系数=1则频率不变,否则频率x2.)可知定时器的频率 = 72M

时基(定时器的心脏)

        定时器最重要的就是时基部分:包括预分频器、计数器、自动重装载寄存器  

        预分频器:1-16位预分频器PSC对内部时钟CK_PSC进行分频之后,得到计数器时钟CK_INT=CK_PSC/(PSC+1)

        CNT在计数器时钟的驱动下开始计数,计数一次的时间为1/CK_INT

        计数器、重装在寄存器:定时器使能(CEN置1)后,计数器CNT在CK_CNT驱动 下计数,当CNT值与ARR的设定值相等时就自动生成事件并CNT自动清零,然后 自动重新开始计数,如此重复以上过程。

影子寄存器

1.PSC和ARR都有影子寄存器,功能框图上有个影子

2.影子寄存器的存在起到一个缓冲的作用,用户值->寄存器->影子寄存器->起作用, 如果不使用影子寄存器则用户值在写到寄存器之后则里面起作用,ARR影子, TIMx_CR1:APRE位控制。

 定时时间的计算

定时器时间=(PSC+1)*(ARR+1)/72M

因为我们的计数器是从0开始计数的,所以要加1

基本定时器的功能

1.计数器16bit,只能向上计数,只有TIM6和TIM7

2.没有外部的GPIO,是内部资源,只能用来定时

3.时钟来自PCKL1,为72M,可实现1~65536分频

通用定时器

STM32 的通用定时器功能:

位于低速的APB1总线上(APB1)

16 位/32 位(仅 TIM2 和 TIM5)向上、向下、向上/向下自动装载计数器 (TIMx_CNT),注意:TIM9~TIM14 只支持向上(递增)计数方式

16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~ 65535 之间的任意数值

4 个独立通道(TIMx_CH1~4,TIM9~TIM14 最多 2 个通道),这些通道可以用来作为:

                输入捕获

                输出比较

                PWM 生成(边缘或中间对齐模式) ,注意:TIM9~TIM14 不支持中间对齐模式

                单脉冲模式输出

可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外 一个定时器)的同步电路。

        如下事件发生时产生中断/DMA(TIM9~TIM14 不支持 DMA):

                更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)

                触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)

                输入捕获

                输出比较

                支持针对定位的增量(正交)编码器和霍尔传感器电路(TIM9~TIM14 不支持)

                触发输入作为外部时钟或者按周期的电流管理(TIM9~TIM14 不支持) 

STM32的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)等

使用定时器分频器和RCC时钟控制分频器,脉冲长度和波型周期可以在几个微妙到几个毫秒间调整,STM32的每个通用定时器都是完全独立的,没有互相共享的任何资源        

计数器模式  

        向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且 产生一个计数器溢出事件

        向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装 入的值重新开始,并产生一个计数器向下溢出事件

        中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个 计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数

通用定时器框图

框图可以分为四个大部分,分别是:

时钟产生部分

时基单元部分

输入捕获部分

输出捕获部分

时钟产生部分 

内部时钟(CKINT)
外部时钟模式:外部触发输入(ETR)
内部触发输入(TRX):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Iimer2的预分频器。
外部时钟模式:外部输入脚(TIx)

时机单元

时基单元就是定时器框图的第二部分,它包括三个寄存器,分别是:计教器寄存器(TIMXCND、预分频器寄存器(TIMXPSC)和自动装载寄存器(TIMX ARR)。对这三个寄存器的介绍如下:
计数器寄存器(TIMx_CNT)
        向上计数、向下计数或者中心对齐计数;
预分频器寄存器(TIMx_PSC)
       可将时钟频率按1到65535之间的任意值进行分频,可在运行时改变其设置值;
自动装载寄存器(TIMX ARR)
        如果TIMx_CR1寄存器中的ARPE位为0,ARR寄存器的内容将直接写入影子寄存器;如果ARPE为1,ARR寄存器的那日同将在每次的更新时间UEV发生时,传送到影子寄存器;

输入捕获通道

1.IC1、2和IC3、4可以分别通过软件设置将其映射到T11、TI2和TI3、TI4;
2.4个16位捕捉比较寄存器可以编程用于存放检测到对应的每一次输入捕捉时计数器的值,
3.当产生一次捕捉,相应的CCxIF标志位被置1;同时如果中断或DMA请求使能,则产生中断或DMA请求。
4.如果当CCxIF标志位已经为1,当又产生一个捕捉,则捕捉溢出标志位CCxOF将被置1。

输出比较通道

PWM模式运行产生:
        定时器2、3和4可以产生独立的信号:频率和占空比可以进行如下设定一个自动重载寄存器用于设定PWM的周期;每个PWM通道有一个
捕捉比较寄存器用于设定占空时间。

两种可设置PWM模式:
        边沿对齐模式
        中心对齐模式

常用库函数

定时器参数初始化函数(第一个参数定时器几,第二个参数结构体指针)

 void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

结构体内部成员

typedef struct
{uint16_t TIM_ClockDivision;     //外部输入时钟分频因子,基本定时器没有uint16_t TIM_CounterMode;       //计数模式,基本定时器只能向上计数uint16_t TIM_Period;           //自动重装载值 //注意重装载值和分频因子的数配置不能超过65535uint16_t TIM_Prescaler;    //分频因子      uint8_t TIM_RepetitionCounter;  //重复计数值,基本定时器没有,高级定时器专用} TIM_TimeBaseInitTypeDef;  
65535

 定时器控制LED灯软件流程设计

初始化系统

        初始化定时器和LED的IO时钟、初始化LED的引脚IO

        使能定时器时钟、初始化定时器、开启中断配置、使能定时器、

编写定时器中断函数

定时器时间= (ARR+1)*(PSC+1)/TCLK(72M=72 000 000)

假如定时1秒 1= 72 00*10000/72M

#include "stm32f10x.h"
#include "tim.h"void Base_Tim_Init()
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);TIM_TimeBaseInitTypeDef TIM_TimeIinitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_TimeIinitStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeIinitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeIinitStruct.TIM_Period = 7200 - 1;TIM_TimeIinitStruct.TIM_Prescaler = 10000 - 1;TIM_TimeIinitStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_TimeIinitStruct);TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);TIM_Cmd(TIM2, ENABLE);NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStruct);}
  TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);
第二个参数
输入捕获输出比较所用到的通道
如果我们只是想产生定时器的更新源中断用第一个参数

#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "bear.h"
#include "key.h"
#include "relay.h"
#include "shake.h"
#include "usart.h"
#include "stdio.h"
#include "tim.h"void delay(uint16_t time) {uint16_t i = 0;while (time--) {i = 12000;while (i--);}
}int main() 
{Led_Init();Base_Tim_Init();while (1){       			}
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){GPIO_ResetBits(GPIOA, GPIO_Pin_1);delay(1000);GPIO_SetBits(GPIOA, GPIO_Pin_1);delay(1000);}TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}

定时器中断应用 

超声波模块

                         

 1.工作原理

首先单片机给Trig引脚,给至少10us(10微秒)的高电平信号。

模块自动发送8个40KHz的方波,自动检测是否有信号返回。

有信号返回,通过Echo引脚输出高电平,高电平持续时间就是超声波从发射到返回的时间

HC-SR04超声波测距模块提供2cm-400cm的测距功能,精度达3mm。

2.硬件接线

四根杜邦线,VCC连接单片机3.3-5V(推荐5V供电),GND接到板子的GND,Trig为外部触发信号输入,输入一个10us的高电平即可触发模块测距,Echo(接收引脚)即为 回响信号输出,测距结束时此管引脚输出一个低电平,电平宽度反映超声波往返时间之和。

3.控制超声波测距步骤

初始化定时器时钟和定时器中断

初始化超声波时钟和超声波引脚模式

编写定时器中断函数测距

先发送10us的高电平信号,发送了之后我的定时器就开始捕获Echo的高电平的时间,什么时候低电平就什么时候关闭定时器,就开始算比如说我们产生了多少次定时器的中断,比如是一次定时器中断是1秒,多少个定时器中断就是多少个秒,通过一系列公式就能知道距离是多少

1. 发送 10μs 的高电平信号(触发信号)

  • 目的:启动一次测距操作。
    这里的 “发送高电平” 通常是通过单片机的 IO 口输出一个持续 10 微秒(μs) 的高电平脉冲(如 HC-SR04 模块需要这样的触发信号)。

  • 为什么是 10μs?
    这是目标设备(如超声波传感器)的协议规定,用于告知传感器 “开始发射信号”(例如超声波传感器会在接收到 10μs 高电平后,发射一束超声波)。

2. 定时器开始捕获 Echo 信号的高电平时间

  • Echo 信号是什么?
    Echo 是 “回波信号”,即目标设备接收到反射回来的信号后,输出的电信号。例如:

    • 发送端发射超声波后,Echo 信号保持低电平;

    • 当超声波遇到障碍物反射回来被接收端检测到,Echo 信号变为高电平;

    • 直到信号接收完毕,Echo 信号重新变为低电平。

  • 定时器的作用
    从触发信号发送完成的时刻起,定时器开始记录 Echo 信号 高电平的持续时间(即从 “收到回波” 到 “回波结束” 的时间)。

3. 检测到低电平时关闭定时器

  • 何时关闭定时器?
    当 Echo 信号从高电平跳转为低电平时(即回波接收完毕),立即停止定时器计数。

  • 本质
    定时器记录的是 “回波信号高电平的持续时间 T”,这个时间 T 等于信号从发射到接收的 往返时间(即信号从发射端→障碍物→接收端的总时间)。

4. 通过定时器中断次数计算时间 T

  • 定时器中断机制
    定时器通常配置为按固定周期产生中断(例如每 1μs、1ms 产生一次中断),每次中断时计数器加 1。

    • 假设定时器中断周期为 1μs(即每 1 微秒产生一次中断),中断次数为 N 次,则总时间 T = N × 1μs

    • (原句中 “一次中断是 1 秒” 是简化举例,实际应用中中断周期远小于 1 秒,通常为微秒或毫秒级,否则精度不足。)

  • 如何计算中断次数?
    定时器启动后,每当 Echo 为高电平时,中断计数器持续累加,直到 Echo 变低时停止计数,此时计数器的值即为高电平期间的中断次数。

5. 通过公式计算距离

  • 核心公式(以超声波测距为例)
    距离 = (信号速度 × 时间 T) / 2

    • 除以 2 的原因:信号往返一次(发射→障碍物→接收),实际距离是单程距离。

    • 信号速度:超声波在空气中约为 340m/s(即 0.034cm/μs),光速约为 3×10⁸m/s(用于激光测距)。

  • 举例计算
    若 T = 1000μs(1 毫秒),则距离 = (0.034cm/μs × 1000μs) / 2 = 17cm。

 超声波代码框架

只有收到回响信号的时候,我们的trigr,在信号发出的时候我的echo引脚输入给我们的单片机,然后如果我们的单片机之前是低电平,检测高电平的瞬间才开始打开定时器(怎么打开和关闭定时器呢)之前配置定时器的时候结构体配置和中断的配置TIM_Cmd(TIM2, DISABLE);函数,先关闭

当收到信号的时候再打开,怎么计算高电平时间?首先要先判断echo引脚什么时候变成高电平
用GPIO_ReadInputDataBit函数然后这里再打开定时器这时就开始我们的中断函数,中断函数去计数定时器进入的次数,因为我们用定时器的开启的时候用定时器的中断计算进入定时器的时间,注意  这里定时器的配置TIM_Initstruct.TIM_Period = 1000 -1;  TIM_Initstruct.TIM_Prescaler = 72 -1;

所以定时器的定时周期的1毫秒,计数器每计1次代表1微秒 ,中断1次是1毫秒,因为我们对应的时间是高电平的时间等于中断次数加上不足一个中断的次数(不足一个中断的次数是说不到1毫秒但有多少个微秒呢)打开定时器,就会跳到定时器中断函数void TIM2_IRQHandler()让mscount++;这里需要定义一个新变量,然后关闭定时器,计算总电平时间,定义一个变量uint16_t t=0;定义一个函数专门用来封装总的高电平时间int Get_Echon_Time()(这里返回值是int)然后将总时间换算成距离以种种方式将t换算距离然后返回值length
 

#include "stm32f10x.h"
#include "tim.h"uint16_t mscount = 0;//定义一个变量专门用来记录中断的次数void delay_us(uint32_t us)
{us*= 8;while(us--);//延时微秒函数}	
void delay_ms(uint32_t ms)
{while(ms--){delay_us(1000);}	//延时毫秒函数}void Base_Tim_Init()
{TIM_TimeBaseInitTypeDef TIM_Initstruct;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_TIM_Initstruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_Initstruct.TIM_ClockDivision =TIM_CKD_DIV1;TIM_Initstruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_Initstruct.TIM_Period = 1000 -1;TIM_Initstruct.TIM_Prescaler = 72 -1;TIM_Initstruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_Initstruct);TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);TIM_Cmd(TIM2, DISABLE);NVIC_TIM_Initstruct.NVIC_IRQChannel =  TIM2_IRQn;NVIC_TIM_Initstruct.NVIC_IRQChannelCmd = ENABLE;NVIC_TIM_Initstruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_TIM_Initstruct.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_TIM_Initstruct);}
void HC04_Iint()
{GPIO_InitTypeDef GPIO_Initstruction;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);//Tring B11GPIO_Initstruction.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Initstruction.GPIO_Pin = GPIO_Pin_11;GPIO_Initstruction.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(GPIOB, &GPIO_Initstruction);//Echo B10GPIO_Initstruction.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Initstruction.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOB, &GPIO_Initstruction);}void Open_Tim()
{TIM_SetCounter(TIM2, 0);mscount = 0;TIM_Cmd(TIM2, ENABLE);}
void Close_Tim()
{TIM_Cmd(TIM2, DISABLE);}
//获取定时器中断的次数
void TIM2_IRQHandler()
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){mscount++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}}//获取总的高电平时间
int Get_Echon_Time()
{uint16_t t = 0;t = mscount * 1000;t = t +TIM_GetCounter(TIM2);delay_ms(50);TIM_SetCounter(TIM2, 0);return t;}float Get_Length()
{float sum = 0;uint16_t t=0;float length = 0;int i = 0;while(i != 5){//1.hc04开始工作 Tring引脚输出高电平20usGPIO_SetBits(GPIOB,  GPIO_Pin_11)delay_us(20);//延时20微秒GPIO_ResetBits(GPIOB,  GPIO_Pin_11);//然后关闭//2.定时器计算高电平时间while(GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_10) == 0);//当GPIO 10引脚高电平时 会卡在这Open_Tim();//打开定时器while(GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_10) == 1);//当高电平跳成低电平时Close_Tim();//关闭定时器t = Get_Echon_Time();//3.将时间换算成距离length = ((float)t/58.0);sum = sum+length;}length = sum/5.0;return length;}
int main() 
{float length = 0;my_usart_init();Ch04_Init();Led_Init();Base_Tim_Init();while (1){length = Get_Length();printf("%f\r\n",length);}
}

 通用定时输出PWM

第一步内部时钟的选择,第二步是预分频器,计数器,去配置输出 捕获和比较

定时器3的通道2 

TIM3为例,STM32的通用定时器氛围TIM2,TIM3,TIM4,TIM5,每个定时器都有独立的四个通道可以用来作为: 输入捕获,输出比较,PWM输出,单脉冲模式输出等。

STM32的定时器除了TIM6TIM7(基本定时器)之外,其他的定时器都可以产生PWM波输出,高级定时器TIM1,TIM8可以同时产生7PWM输出,而通用定时器可以同时产生4PWM输出,这样STM32可以最多同时输出30PWM输出。

 PWM的工作原理

以向上计数为例,讲述PWM原理:

①在PWM输出模式下除了CNT(计数器当前值)ARR(自动重装载值)CCRx(捕获/比较寄存器值)

②当CNT小于CCRx时,TIMx_CHx通道输出低电平

③当CNT等于或大于CCRx时,TIMx_CHx通道输出高电平

假设ARR设置是100CRRX是80,在0加到80过程中都属于低电平,在80加到100都属于高电平,这就是一个周期,所以占空比为百分之二十,

          所谓脉宽调制信号(PWM),就是一个TIMx_ARR自动重装载寄存器确定频率=周期的导数(由它决定PWM周期),TIM_CCRx寄存器确定占空比信号。

占空比=高电平占低电平的时间

 PWM的内部运作机制

CCR1:设置捕获比较寄存器,设置比较值。      

CCMR1寄存区:设置PWM模式1 或者PWM模式2

CCER:  P位:输出/捕获   :设置极性: 0 高电平有效,1 低电平有效

             E位:输出/捕获   : 使能端口

PWM的模式 

模式一    边沿对齐模式

向上计数时: 当TIMx_CNT<TIMx_CCRx时通道1为有效电平,否则为无效电平(计数值小于有效值是有效电平)

向下计数时:   一旦TIMx_CNT>TIMx_CCRx,CCR1通道1为无效电平,否则为有效电平(计数值大于比较值为无效电平)

但是这里的有效电平是高电平还是低电平有极性( 0 高电平有效,1 低电平有效)去选择

模式二    中央对齐模式

向上计数时: 当TIMx_CNT<TIMx_CCRx时通道1为无效电平,否则为无效电平;

向下计数时:   一旦TIMx_CNT>TIMx_CCRx,CCR1通道1为有效电平,否则为无效电平。

和模式一相反

 但是这里的有效电平是高电平还是低电平有极性( 0 高电平有效,1 低电平有效)去选择

 自动加载的预加载寄存器

 

简单的说:

APER =1 ,ARR立即生效

APER =0,ARR下个周期生效

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

 定时器输出PWM 结构体

typedef struct
{uint16_t TIM_OCMode;            //配置PWM模式1还是模式2uint16_t TIM_OutputState;       //配置输出使能/ OR失能uint16_t TIM_OutputNState;     uint16_t TIM_Pulse;                  //配置比较值,CCRxuint16_t TIM_OCPolarity;         //比较输出极性uint16_t TIM_OCNPolarity;   uint16_t TIM_OCIdleState;  uint16_t TIM_OCNIdleState;  
} TIM_OCInitTypeDef;

定时器输出PWM 库函数

void TIM_OCxInit                      //结构体初始化
(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_SetCompare1            //设置比较值函数
(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_OC1PreloadConfig     //使能输入比较预装载
(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_Cmd                            //开启定时器(TIM_TypeDef* TIMx, FunctionalState NewState)
void TIM_ARRPreloadConfig     //使能自动重装载的预装载寄存器允许位
(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_OC1PolarityConfig      //配置修改极性
(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);

定时器输出PWM 库函数

TIM3 PWM输出  驱动SG90电机    配置过程:

1.GPIO结构体

2.配置通用定时器结构体

3.配置定时去输出PWM结构体

4.打开时钟  ---> GPIO时钟,TIM定时器时钟,部分重映射时钟

5.配置PWM比较值

void motor_config(void)
{GPIO_InitTypeDef GPIO_MotorInitStruct;TIM_TimeBaseInitTypeDef TIM_MotorInit;TIM_OCInitTypeDef TIMPWM_MotorInit;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//部分重映射配置GPIO_MotorInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_MotorInitStruct.GPIO_Pin = GPIO_Pin_5;GPIO_MotorInitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_MotorInitStruct);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);TIM_MotorInit.TIM_ClockDivision = TIM_CKD_DIV1;       //设置时钟分割TIM_MotorInit.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式TIM_MotorInit.TIM_Period = 200-1;//设置下一个更新事件装入活动的自动重装载值TIM_MotorInit.TIM_Prescaler = 7200 -1;	//分频周期TIM_TimeBaseInit(TIM3, &TIM_MotorInit);TIMPWM_MotorInit.TIM_OCMode = TIM_OCMode_PWM1;//选择定时器模式1TIMPWM_MotorInit.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能TIMPWM_MotorInit.TIM_OCNPolarity = TIM_OCPolarity_Low;//选择有效输出极性TIM_OC2Init(TIM3, &TIMPWM_MotorInit);//因为选择的是定时器3的通道2 所以选OC2TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);TIM_Cmd(TIM3, ENABLE);}
int main() 
{uint16_t pwmval = 155;motor_config();while(1){for(pwmval = 195;pwmval >= 175;pwmval-=5){TIM_SetCompare2(TIM2,  pwmval);delay(500);}}}

垃圾桶项目 

int main() 
{int  pwmval =195;float Length =0;Ch04_Init();	my_usart_init();motor_config();while(1){pwmval =155;Length= Get_Length();printf("%.3f\r\n",Length);if(Length<5){for(pwmval=195;pwmval>=155;pwmval-=15){TIM_SetCompare2(TIM3, pwmval);delay(500);	}}else if(Length>5){TIM_SetCompare2(TIM3, pwmval-20);}}}

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

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

相关文章

OpenObserve API Usage Guide for Log Management

OpenObserve API Usage Guide for Audit Log Management 1. 概述 1.1 目标 本文档旨在详细介绍 OpenObserve 的 API 使用方法&#xff0c;帮助用户通过 API 实现日志管理功能&#xff0c;包括日志摄入、查询、模糊匹配&#xff08;类似 SQL 的 LIKE&#xff09;、stream 管理…

消防岗位技能竞赛流程方案策划

一、比赛目的&#xff1a; 为大力倡导“11.9”全国消防安全活动月&#xff0c;紧紧围绕“人人参与消防&#xff0c;共创平安和谐”的活动主题&#xff0c;结合公司实际情况&#xff0c;特开展一次消防技能竞赛活动。开展一场比思想、比工作作风、比消防业务技能、比业余文化生…

DAY9-USF4.0技术文档笔记

目录 1.概述 2.参考协议标准 3.术语与定义 4.引言 5.UFS架构 6.UFS电气特性&#xff1a;时钟、复位、信号与电源 7.复位、加电升压和断电降压 8. M-PHY 9.UniPro 10.UTP 11.SCSI 12.UFS安全 13.UFS功能描述 14.描述符、标志与属性 15.UFS机械标准 SCSI 查询命令 1.重要产品…

安装kubernetes 1.33版本

一、环境准备 1、内核升级 #升级内核&#xff1a; yum -y install kernel-ml-5.10.3-1.el7.elrepo.x86_64.rpm kernel-ml-devel-5.10.3-1.el7.elrepo.x86_64.rpm# 查询可用内核版本 # awk -F\ $1"menuentry " {print i " : " $2} /etc/grub2.cfg# 调整默…

【IPMV】图像处理与机器视觉:Lec8 Image Pyramid 图像金字塔

【IPMV】图像处理与机器视觉 本系列为2025年同济大学自动化专业**图像处理与机器视觉**课程笔记 Lecturer: Rui Fan、Yanchao Dong Lec0 Course Description Lec3 Perspective Transformation Lec7 Image Filtering Lec8 Image Pyramid 持续更新中 文章目录 【IPMV】图像处…

产品经理.产品设计.产品设计工具

一、 产品经理常用工具 1. 业务流程图---系统流程图 业务流程图&#xff0c;面向用户调研&#xff0c;描述业务的流转和数据的处理要求&#xff0c;跟用户和业务方确认&#xff1b;---业务角色的泳道流程图。 系统流程图&#xff0c;面向产品需求设计&#xff0c; prd系描述各…

6轴、智能、低功耗惯性测量单元BMI270及其OIS接口

BOSCH惯性传感器IMUs 芯片代码 通过00寄存器读回的芯片编码可以判断芯片型号,BMI270为(0x24) &#xff0c;如不是该值&#xff0c;则说明不是BMI270。 型号芯片代码BMI085CHIP_ID ( 0x1F)BMI088CHIP_ID ( 0x1E)BMI160CHIP_ID (0xD1)BMI270CHIP_ID (0x24)BMI323CHIP_ID (0x004…

【文献速递】邻位连接技术(PLA)在细胞器相互作用中的应用

在神经科学研究领域&#xff0c;细胞死亡机制一直是关注的重点&#xff0c;尤其是与神经退行性疾病相关的细胞死亡形式。荷兰格罗宁根大学的研究人员在2025年发表了“Regulation of calcium signaling prevents neuronal death mediated by NIST DEP in xenoferroptotic cell d…

六.割草机技术总结--6.RTK定位精度分析

六.割草机技术总结–6.RTK定位精度分析 6.1 1cm+1ppm 中的ppm是什么意思? 精度 RTK 位置精度(在 RTK 时)1 cm + 1 ppm ( 水 平 ) 1 . 5 cm + 1 ppm ( 垂 直 ),其中的ppm是什么意思? 在RTK(实时动态定位)技术中,ppm表示 Parts Per Million(百万分之一),是一种与距离…

MCP的基础知识

一、了解MCP的基础知识 1.函数调用Function Calling Function Calling是openai在2023年推出的一个非常重要的概念&#xff1a;Function Calling&#xff08;函数调用&#xff09;本质上就是提供了大模型与外部系统的交互能力&#xff0c;类似于给大模型安装了一个“外挂工具箱…

量化交易之数学与统计学基础2.4——线性代数与矩阵运算 | 矩阵分解

量化交易之数学与统计学基础2.4——线性代数与矩阵运算 | 矩阵分解 第二部分&#xff1a;线性代数与矩阵运算 第4节&#xff1a;矩阵分解&#xff1a;奇异值分解&#xff08;SVD&#xff09;在数据压缩和风险分解的应用 一、奇异值分解&#xff08;SVD&#xff09;基础&#xf…

极简主义在 UI 设计中的应用与实践:打造简洁高效界面

极简主义理念&#xff1a;简洁不简单​ 极简主义起源于 20 世纪初的包豪斯运动&#xff0c;它不仅是一种设计风格&#xff0c;更代表着一种生活态度与价值观。其核心理念 “少即是多”&#xff0c;并非简单地削减元素&#xff0c;而是在精简中追求极致&#xff0c;将设计简化到…

2025年“深圳杯”数学建模挑战赛C题-分布式能源接入配电网的风险分析

布式能源接入配电网的风险分析 小驴数模 背景知识&#xff1a; 随着我国双碳目标的推进&#xff0c;可再生分布式能源在配电网中的大规模应用不可避免&#xff0c;这对传统配电网运行提出挑战。为了量化分析配电网中接入分布式能源的风险&#xff0c;需要对其进行建模与分析…

《解锁LibTorch:开启C++深度学习新征程》

《解锁LibTorch:开启C++深度学习新征程》 深度学习与 LibTorch 在当今数字化时代,深度学习已成为人工智能领域的核心驱动力,广泛应用于计算机视觉、自然语言处理、语音识别等诸多领域,深刻改变着我们的生活和工作方式。它的发展历程充满了创新与突破,从最初的理论探索到如…

理想药用植物的特征综述-理想中药材”的系统定义-文献精读125

Decoding and designing: Promising routes to tailor-made herbs 解码与设计&#xff1a;定制化草药的潜力路径 摘要 理想药用植物的特征可归纳为高次生代谢产物含量、高抗逆性、理想的形态以及高产量。本研究提出了两种策略&#xff0c;用于解析中药活性成分的生物合成与质…

如何在Dify沙盒中安装运行pandas、numpy

如何在Dify沙盒中安装运行pandas、numpy 1. 创建python-requirements.txt文件2. 创建config.yaml文件3. 重启 docker-sandbox-14. 为什么要这样改的一些代码解析&#xff08;Youtube视频截图&#xff09; 1. 创建python-requirements.txt文件 在 Dify 的 Docker 目录下面&…

深度卷积模型:案例研究

1 为什么要进行案例研究&#xff1f; 过去&#xff0c;计算机视觉中的大量研究都集中在如何将卷积层、池化层以及全连接层这些基本组件组合起来&#xff0c;形成有效的卷积神经网络。 找感觉的最好方法之一就是去看一些示例&#xff0c;就像很多人通过看别人的代码来学习编程一…

RabbitMQ Linux 安装教程详解

RabbitMQ Linux 安装教程详解 在 Linux 系统上安装 RabbitMQ 并确保其稳定运行&#xff0c;对于构建可靠的分布式消息系统至关重要。本文将详细介绍如何在 Linux 系统上安装 RabbitMQ&#xff0c;并提供关键的注意事项&#xff0c;帮助您避免常见的坑点&#xff0c;确保安装过…

Godot笔记:入门索引

文章目录 前言游戏引擎软件界面关键概念GDScript导出成品创建非游戏应用后记 前言 最近对游戏引擎这块感兴趣&#xff0c;特别是因为游戏引擎自带的很多工具&#xff0c;作为图形化软件的开发应该也不错。 Godot 是一款这几年比较流行的开源游戏引擎。这里记录下入门学习使用 …

[C语言]猜数字游戏

文章目录 一、游戏思路揭秘二、随机数生成大法1、初探随机数&#xff1a;rand函数的魔力2、随机数种子&#xff1a;时间的魔法3、抓住时间的精髓&#xff1a;time函数 三、完善程序四、游戏成果1、游戏效果2、源代码 一、游戏思路揭秘 猜数字游戏&#xff0c;这个听起来就让人…