STM32入门——定时器
内容为江科大STM32标准库学习记录
TIM简介
- TIM(Timer)定时器
- 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
- 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时(这里计算就是72MHz主频通过预分频继续分频(假设分频为最大65536),分频后的频率给到计数器,我们只需要知道计数器的范围为为2^16,计数加1的时间为65536/72MHz,那么最大定时就是65536/72MHz * 65536 = 59.65s)
- 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
- 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
定时器类型
基本定时器
- CK_PSC:预分频器,对输入的基准频率提前进行一个分频操作,实际分频系数 = 预分频器的值+1;
- 计数器:自增,16位,0——65535
- 自动重装载寄存器:16位,存放的是写入的计数目标
- 更新中断:计数器计数自增,不断与自动重装寄存器比较,当计数自增到到计数目标,就会产生一个更新中断和更新事件,CPU更新中断并且清零计数器。
- 主模式触发DAC:可以把产生的更新事件映射到TRGO的位置,然后TRGO直接接到DAC的触发转换引脚上,这样定时器的更新就不再需要通过中断触发DAC的转换,只需要把更新事件通过主模式映射到TRGO,然后TRGO就会直接去触发DAC了,实现硬件的自动化。
通用定时器
- 通用定时器支持向上计数模式、向下计数模式和中央对齐模式。
- 内部时钟源:基本定时器只能选择内部时钟源(系统频率72MHz),通用定时器还可以选择外部时钟,外部时钟模式2(ETR外部时钟),外部时钟模式1(ERT外部时钟、ITRx其他定时器、TIx捕获通道)
高级定时器
重复次数计数器:可以实现每隔几个周期才发生一次更新事件和更新中断,相当于对更新的输出信号作了一次分频。
定时中断基本结构
预分频器时序
- 预分频缓冲器:可以防止在一个周期里改变了预分频值,从而导致一个周期里的频率前后不一致导致计数目标不一致。这个只有在产生了更新事件后,进入下一个周期的时候才会真正改变预分频值
- 计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)
计数器时序:
- 更新中断标志UIF:置1会申请中断,然后响应中断,需要在中断程序中手动清零
- 计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)
= CK_PSC / (PSC + 1) / (ARR + 1)
计算溢出时间取倒数
计数器无预装时序
计数器有预装时序
通过设置AREP位就可以选择是否使用预装功能
RCC时钟树
定时器的内部基准时钟都是72MHZ
定时器相关的寄存器可以看下手册
案列1:定时器每隔1s自加,使用内部时钟
#include "Timer.h"uint16_t num;void Timer_Init(void)
{//开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);TIM_InternalClockConfig(TIM2);//使用内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseStructure.TIM_Period = 10000 - 1;//ARR自动重装值TIM_TimeBaseStructure.TIM_Prescaler = 7200 - 1;//PCS 预分频器的值TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);TIM_ClearFlag(TIM2,TIM_FLAG_Update);//解决上电立刻先进入一次中断,手动把更新中断标志位清除一下//配置启用指定的TIM中断TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//配置优先级分组:抢占优先级和子优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置NVICNVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2,ENABLE);//启动定时器}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){//判断定时器中断标志num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断定时器中断标志}}
案列二:使用外部时钟计数,其实内部时钟计数就是按照内部定时自加,使用外部时钟就是计外面进来的信号(例如电平信号和边沿信号)
#include "Timer.h"uint16_t num;void Timer_Init(void)
{//开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//配置外部时钟模式2,数外面进来的信号TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0F);TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseStructure.TIM_Period = 10 - 1;//ARR自动重装值TIM_TimeBaseStructure.TIM_Prescaler = 1 - 1;//PCS 预分频器的值TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);TIM_ClearFlag(TIM2,TIM_FLAG_Update);//解决上电立刻先进入一次中断,手动把更新中断标志位清除一下//配置启用指定的TIM中断TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//配置优先级分组:抢占优先级和子优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置NVICNVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2,ENABLE);//启动定时器}uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){//判断定时器中断标志num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断定时器中断标志}}
输出比较简介
- OC(Output Compare)输出比较
- 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
- 每个高级定时器和通用定时器都拥有4个输出比较通道
- 高级定时器的前3个通道额外拥有死区生成和互补输出的功能
PWM简介
-
PWM(Pulse Width Modulation)脉冲宽度调制
-
在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域
-
PWM参数:
频率 = 1 / TS 占空比 = TON / TS 分辨率 = 占空比变化步距
输出比较通道(通用)
输出模式控制器:是CNT和CCR的大小关系,输出的是REF的高低电平
具体看下面输出比较模式
置有效电平:可以理解为高电平
置无效电平:可以理解为低电平
PWM基本结构
黄色线:ARR的值
红色线:CCR的值
蓝色线:CNT的计数值
绿色线为REF输出,极性是否翻转取决于极性选择了,最终通向GPIO口
参数计算
上图看出PWM的频率等于计数器的更新频率
输出比较通道(高级)
舵机简介
- 舵机是一种根据输入PWM信号占空比来控制输出角度的装置
- 输入PWM信号要求:周期为20ms,高电平宽度为0.5ms~2.5ms
0.5ms-------------(-)90度; 2.5%
1.0ms------------(-)45度; 5.0%
1.5ms------------0度; 7.5%
2.0ms-----------45度; 10.0%
2.5ms-----------90度; 12.5%
直流电机及驱动简介
- 直流电机是一种将电能转换为机械能的装置,有两个电极,当电极正接时,电机正转,当电极反接时,电机反转
- 直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作
- TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向
硬件电路
这里的就是IN1和IN2控制正反转,PWM控制速度
左转:左边轮子不动,右边轮子往前走
右转:右边轮子不动,左边轮子往前走
案例一:呼吸灯,通过改变CCR寄存器的值,改变占空比
#include "pwm.h"void PWM_Init(void)
{//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//选择内部时钟TIM_InternalClockConfig(TIM2);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;//ARR自动重装值TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;//PCS 预分频器的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);TIM_OCInitTypeDef TIM_OCInitStructure;TIM_OCStructInit(&TIM_OCInitStructure);//给结构体赋予初始值,再更改需要的值TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//指定TIM模式TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //指定输出极性。 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//指定TIM输出比较状态TIM_OCInitStructure.TIM_Pulse = 0;//CCR寄存器的值TIM_OC1Init(TIM2,&TIM_OCInitStructure);//初始化TIM2 Channel1TIM_Cmd(TIM2,ENABLE);//启动定时器}void Set_Compare1(uint16_t Set_Compare1)
{TIM_SetCompare1(TIM2,Set_Compare1);}
LED_PWM_Init();PWM_Init();while(1){for(i=0;i<=100;i++){Set_Compare1(i);Delay_ms(10);OLED_ShowNum(2,3,i,5);}for(i=0;i<=100;i++){Set_Compare1(100-i);Delay_ms(10);OLED_ShowNum(2,3,(100-i),5);}}}
引脚端口复用
打开AFIO时钟,再使用AFIO重映射外设复用的引脚,如果重映射的GPIO是调试端口,需要解除调试功能,变为普通的GPIO才可以正常使用
//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//IO复用RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//重映射GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//解除JTAG的调试端口GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);
案例二:控制舵机
#include "pwm.h"void PWM_Init(void)
{//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//选择内部时钟TIM_InternalClockConfig(TIM2);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;//ARR自动重装值TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;//PCS 预分频器的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);TIM_OCInitTypeDef TIM_OCInitStructure;TIM_OCStructInit(&TIM_OCInitStructure);//给结构体赋予初始值,再更改需要的值TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//指定TIM模式TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //指定输出极性。 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//指定TIM输出比较状态TIM_OCInitStructure.TIM_Pulse = 0;//CCR寄存器的值TIM_OC1Init(TIM2,&TIM_OCInitStructure);//初始化TIM2 Channel1TIM_Cmd(TIM2,ENABLE);//启动定时器}void Set_Compare1(uint16_t Compare)
{//Set_Compare1 = Set_Compare1*20;TIM_SetCompare1(TIM2,Compare);}void Servo_SetAngle(uint16_t Angle)
{uint16_t reNum;reNum = (Angle*2000)/180 + 500;Set_Compare1(reNum);}
案例三:控制电机
#include "motor.h"
void Motor_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;PWM_Init();
}void Motor_SetSpeed(int8_t speed)
{if(speed >= 0){GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_ResetBits(GPIOA,GPIO_Pin_5);//正转Set_Compare1(speed);//控制占空比来调整速度}else {GPIO_SetBits(GPIOA,GPIO_Pin_5);GPIO_ResetBits(GPIOA,GPIO_Pin_4);//反转Set_Compare1(speed);//控制占空比来调整速度}}
第三部分:输入捕获
输入捕获简介
- IC(Input Capture)输入捕获
- 输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
- 每个高级定时器和通用定时器都拥有4个输入捕获通道
- 可配置为PWMI模式,同时测量频率和占空比
- 可配合主从触发模式,实现硬件全自动测量
频率的定义:在时间T内出现N个重复的周期,那么f = N/T
频率测量
测频法适合测量高频信号,测周法适合测量低频信号,以中界频率为界限。
输入捕获通道
主从触发模式
输入捕获基本结构
输入捕获基本结构
PWMI基本结构
案例一:PA0输出pwm,使用PA6捕获输入pwm,测量频率
#include "IC.h"void IC_Init(void)
{//开启对应时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置GPIOGPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//配置时基单元TIM_InternalClockConfig(TIM3);//选择内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器模式TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;//ARRTIM_TimeBaseInitStructure.TIM_Prescaler = 72 -1;//PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//输入捕获配置TIM_ICInitTypeDef TIM_ICInitStructure;TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;TIM_ICInitStructure.TIM_ICFilter = 0xF;//指定输入捕获过滤器。TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//指定输入信号的活动边缘TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//指定输入捕获预calerTIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//指定输入TIM_ICInit(TIM3,&TIM_ICInitStructure);//根据指定初始化TIM外设TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//选择输入触发器源TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//选择TIMx从模式TIM_Cmd(TIM3,ENABLE);
}//f = 标准频率/计时次数;目前标准频率为1MHz
uint32_t Get_Frequency(void)
{return (1000000/TIM_GetCapture1(TIM3));
}
案例二:PA0输出pwm,使用PA6捕获输入pwm,测量频率和占空比
#include "IC2.h"void IC2_Init(void)
{//开启对应时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置GPIOGPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//配置时基单元TIM_InternalClockConfig(TIM3);//选择内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器模式TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;//ARRTIM_TimeBaseInitStructure.TIM_Prescaler = 72 -1;//PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//输入捕获配置TIM_ICInitTypeDef TIM_ICInitStructure;TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;TIM_ICInitStructure.TIM_ICFilter = 0xF;//指定输入捕获过滤器。TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//指定输入信号的活动边缘,上升沿TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//指定输入捕获预calerTIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//指定输入,这里直接TIM_ICInit(TIM3,&TIM_ICInitStructure);//根据指定初始化TIM外设TIM_PWMIConfig(TIM3,&TIM_ICInitStructure);//传入配置好的通道1,就可以配置和通道1的相反配置TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//选择输入触发器源TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//选择TIMx从模式TIM_Cmd(TIM3,ENABLE);
}//f = 标准频率/计时次数;目前标准频率为1MHz
uint32_t Get_Frequency2(void)
{return (1000000/TIM_GetCapture1(TIM3));
}uint32_t Get_Duty(void)
{return ((TIM_GetCapture2(TIM3)+1)*100/TIM_GetCapture1(TIM3));
}
编码器接口简介
- Encoder Interface 编码器接口
- 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度
- 每个高级定时器和通用定时器都拥有1个编码器接口
- 两个输入引脚借用了输入捕获的通道1和通道2
正交编码器
编码器接口基本结构
工作模式
实例(均不反相)
实例(TI1反相)
案例一:编码器接口测速
A相——PA6 B相——PA7 对应TIM3的通道1和通道2
#include "Encoder.h"void Encoder_Init(void)
{//开启对应时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIO初始化GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 65506 - 1;//ARR 自动重装值TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1; //PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//输入捕获配置TIM_ICInitTypeDef TIM_ICInitStructure;TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;TIM_ICInitStructure.TIM_ICFilter = 0xF;TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM_ICInit(TIM3,&TIM_ICInitStructure);TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;TIM_ICInitStructure.TIM_ICFilter = 0xF;TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM_ICInit(TIM3,&TIM_ICInitStructure);//编码器接口配置TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);TIM_Cmd(TIM3,ENABLE);//开启定时器
}uint16_t Encoder_Get(void)
{uint16_t temp;TIM_GetCounter(TIM3);//获取CNT的值TIM_SetCounter(TIM3,0);//CNT清0
}
相关文章:

STM32入门——定时器
内容为江科大STM32标准库学习记录 TIM简介 TIM(Timer)定时器定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时&…...

企业工商信息:知识产权出质
一、出质是什么?质权是什么? 出质,作为一种物权行为,是指将个人或企业所拥有的财产权益移交给他人作为抵押,以获得资金支持。这一概念在商业活动中扮演着重要的角色,为企业创造了融资渠道。特别是在知识密…...

batch_softmax_loss
每个用户抽取一定数量的困难负样本,然后ssm def batch_softmax_loss_neg(self, user_idx, rec_user_emb, pos_idx, item_emb):user_emb rec_user_emb[user_idx]product_scores torch.matmul(F.normalize(user_emb, dim1), F.normalize(item_emb, dim1).transpose(…...

刘汉清:从生活到画布,宠物成为灵感源泉
出生于中国镇江的艺术家刘汉清,其作品展现出他对日常生活的深入洞察力,以及对美的独特理解。他的作品通常没有视觉参考,而是通过对他周围环境的理解,尤其是他的宠物,来进行创作。 在刘汉清的创作过程中,他…...

【LeetCode】240.搜索二维矩阵Ⅱ
题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1: 输入:matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,…...

SED正则表达式中[方括号]的特殊处理
今天被这个方括号懵晕了,特此记录 例如: 去除输入字符串“1[2.3]4[ab,c]”中的所有方括号和逗号: $ echo "1[2.3]4[ab,c]"|sed -e "s/[,\]\[]//g" 1[2.3]4[ab,c] It doesnt work! 原因:Regular Expressi…...

Android 音频开发
在Android平台上进行音频开发,您需要掌握以下关键知识点: Android平台基础知识:熟悉Android操作系统的基本架构、组件和应用开发的基本概念。 音频API:了解Android提供的音频相关API,主要包括android.media.AudioReco…...

Java8新特性,Lambda,Stream流
Java8新特性,Lambda,Stream流 Java8版本在2014年3月18日发布,为Java语言添加了很多重要的新特性。新特性包括:Lambda表达式、方法引用、默认方法、新的时间日期API、Stream API、Optional类等等。这些新特性大大增强了Java语言的表达能力,使…...

模型训练之train.py代码解析
题目 作者:安静到无声 个人主页 from __future__ import absolute_import from __future__ import division from __future__ import print_function这段代码使用了Python 2.x的__future__模块来导入Python 3.x的一些特性。在Python 2.x中,使用print语句来输出内容,而在Py…...

linux 复习
vim 使用 一般模式 、 命令模式、编辑模式 esc 进入一般模式 i 进入编辑模式 shift: 进入命令模式 yy p 复制粘贴 5yy 复制当前开始的5行 dd 删除 5dd 删除当前开始的5行 u撤销操作 ctrlr 恢复 shiftg 滚动最底部 gg 滚动最顶 输入数字 然后shiftg 跳转到指定行 用户操作…...

C语言刷题------(2)
C语言刷题——————(2) 刷题网站:题库 - 蓝桥云课 (lanqiao.cn) First Question:时间显示 题目描述 小蓝要和朋友合作开发一个时间显示的网站。 在服务器上,朋友已经获取了当前的时间,用一个整数表…...

JVM 之 OopMap 和 RememberedSet
前几天看周志明的《深入 Java 虚拟机》,感觉对 OopMap 和 RememberedSet 的介绍,看起来不太容易理解清楚。今天查了一些资料,并结合自己的一些猜想,把对这两种数据结构的理解写出来。目的只是为了简单易懂,而且多有推测…...

Original error: gsmCall method is only available for emulators
在夜神模拟器执行报错 self.driver.make_gsm_call(5551234567, GsmCallActions.CALL)意思是gsmCall这个命令不支持,只支持下面这些命令 selenium.common.exceptions.UnknownMethodException: Message: Unknown mobile command "gsmCall". Only shell,exe…...

React Native从文本内容尾部截取显示省略号
<Textstyle{styles.mMeNickname}ellipsizeMode"tail"numberOfLines{1}>{userInfo.nickname}</Text> 参考链接: https://www.reactnative.cn/docs/text#ellipsizemode https://chat.xutongbao.top/...

机器学习笔记之优化算法(十一)凸函数铺垫:梯度与方向导数
机器学习笔记之优化算法——凸函数铺垫:梯度与方向导数 引言回顾:偏导数方向余弦方向导数方向导数的几何意义方向导数的定义 方向导数与偏导数之间的关联关系证明过程 梯度 ( Gradient ) (\text{Gradient}) (Gradient) 引言 本节作为介绍凸函数的铺垫&a…...

探究Vue源码:mustache模板引擎(11) 递归处理循环逻辑并收尾算法处理
好 在上文 探究Vue源码:mustache模板引擎(10) 解决不能用连续点符号找到多层对象问题,为编译循环结构做铺垫 我们解决了js字符串没办法通过 什么点什么拿到对象中的值的问题 这个大家需要记住 因为这个方法的编写之前是当做面试题出现过的 那么 本文 我们就要去写上…...

STM32 CubeMX USB_CDC(USB_转串口)
STM32 CubeMX STM32 CubeMX 定时器(普通模式和PWM模式) STM32 CubeMX一、STM32 CubeMX 设置USB时钟设置USB使能UBS功能选择 二、代码部分添加代码实验效果 printf发…...

机器学习——卷积神经网络基础
卷积神经网络(Convolutional Neural Network:CNN) 卷积神经网络是人工神经网络的一种,是一种前馈神经网络。最早提出时的灵感来源于人类的神经元。 通俗来讲,其主要的操作就是:接受输入层的输入信息&…...

端到端自动驾驶前沿论文盘点(pdf+代码)
现在的自动驾驶,大多数还是采用的模块化架构,但这种架构的缺陷十分明显:在一个自动驾驶系统里,可能会包含很多个模型,每个模型都要专门进行训练、优化、迭代,随着模型的不断进化,参数量不断提高…...

2023年中期奶粉行业分析报告(京东数据开放平台)
根据国家统计局和民政部数据公布,2022年中国结婚登记数创造了1980年(有数据公布)以来的历史新低,共计683.3万对。相较于2013年巅峰时期的数据,2022年全国结婚登记对数已接近“腰斩”。 2023年“520”期间的结婚登记数…...

web集群学习:基于CentOS 7构建 LVS-DR 群集并配置服务启动脚本
目录 1、环境准备 2、配置lvs服务启动脚本 1、在RS上分别配置服务启动脚本 2、在lvs director上配置服务启动脚本 3、客户端测试 配置LVS-DR模式主要注意的有 1、vip绑定在RS的lo接口; 2、RS做arp抑制; 1、环境准备 VIP192.168.95.10 RS1192.168…...

Flask 高级应用:使用蓝图模块化应用和 JWT 实现安全认证
本文将探讨 Flask 的两个高级特性:蓝图(Blueprints)和 JSON Web Token(JWT)认证。蓝图让我们可以将应用模块化,以便更好地组织代码;而 JWT 认证是现代 Web 应用中常见的一种安全机制。 一、使用…...

【Grafana】中文界面配置 v10.0.3
比如通过 docker run -d -p 3000:3000 -v /e/code/monitor/grafana/grafana.ini.txt:/etc/grafana/grafana.ini grafana/grafana运行一个容器(最新是v10.0.3)。 在 /admin/settings 可以看到 users 部分有一个 default_language 配置。 所以在挂载到 …...

web前端html
文章目录 快捷方式一、html5的声明二、html5基本骨架 2.1 html标签 2.2 head标签 2.3 body和head同级 2.4 body标签 2.5 title标签 2.6 meta标签 三、标题标签介绍与应用 3.1 标题的介绍 3.2 标题标签位置摆放 3.3 标签之段落、换行、水平线 3.3 标签之图片 3.3.1 图…...

Unity 编辑器选择器工具类Selection 常用函数和用法
Unity 编辑器选择器工具类Selection 常用函数和用法 点击封面跳转下载页面 简介 在Unity中,Selection类是一个非常有用的工具类,它提供了许多函数和属性,用于操作和管理编辑器中的选择对象。本文将介绍Selection类的常用函数和用法ÿ…...

ArcGIS在洪水灾害普查、风险评估及淹没制图中应用教程
详情点击链接:ArcGIS在洪水灾害普查、风险评估及淹没制图中应用教程 一:洪水普查技术规范 1.1 全国水旱灾害风险普查实施方案 1.2 洪水风险区划及防治区划编制技术要求 1.3 山丘区中小河流洪水淹没图编制技术要求 二:ArcGIS及数据管理 …...

Oracle日志相关操作
1.归档日志设置 # 切换账号 $ su - oracle# 登录oracle的sys账户 $ sqlplus / as sysdbasql> archive log list; #查看是不是归档方式 SQL> archive log list; Database log mode Archive Mode Automatic archival Enabled Archive destin…...

IMV8.0
一、背景内容 经历了多个版本,基础内容在前面,可以使用之前的基础环境: v1: https://blog.csdn.net/wtt234/article/details/132139454 v2: https://blog.csdn.net/wtt234/article/details/132144907 v3: h…...

【Linux 网络】 数据链路层协议
数据链路层协议 数据链路层解决的问题以太网协议认识以太网以太网帧格式 认识MAC地址对比理解MAC地址和IP地址认识MTUMTU对IP协议的影响MTU对UDP协议的影响MTU对于TCP协议的影响ARP协议ARP协议的作用ARP协议的工作流程ARP数据报的格式 总结 数据链路层解决的问题 IP拥有将数据跨…...

GWJDN-400型2MHZ自动平衡高温介电温谱仪
GWJDN-400型2MHZ自动平衡高温介电温谱仪 GWJDN-400型2MHZ自动平衡高温介电温谱仪 关键词:介电常数,高温介电,自动平衡 主要功能: 材料介电常数测试仪 半导体材料的介电常数、导电率和C-V特性液晶材料:液晶单元的介电常数、弹性…...