当前位置: 首页 > news >正文

网站建设实训心得 总结/关键词优化案例

网站建设实训心得 总结,关键词优化案例,html5 jq做电脑网站,杭州比较有名的设计公司STM32定时器使用 STM32定时器计数模式定时器工作原理基本定时器:TIM6、TIM7示例代码代码讲解 通用定时器:TIM2、TIM3、TIM4、TIM5高级定时器:TIM1、TIM8定时器PWM输出原理通用定时器3控制通道1输出PWM脉冲代码 总结参考资料 STM32定时器 STM…

STM32定时器使用

  • STM32定时器
    • 计数模式
    • 定时器工作原理
    • 基本定时器:TIM6、TIM7
      • 示例代码
      • 代码讲解
    • 通用定时器:TIM2、TIM3、TIM4、TIM5
    • 高级定时器:TIM1、TIM8
    • 定时器PWM输出原理
      • 通用定时器3控制通道1输出PWM脉冲
      • 代码
    • 总结
    • 参考资料

STM32定时器

STM32F103系列芯片拥有多种定时器,包括基本定时器、通用定时器和高级定时器,每种定时器都具有一些特定的功能。
在这里插入图片描述

计数模式

向上计数:计数器从0计数到自动重装载值(ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
向下计数:计数器从自动重装载值(ARR)开始向下计数到0,然后重新从自动重装载值(ARR)开始向下计数,并且产生一个计数器溢出事件。
向上向下双向计数(中央对齐模式):计数器从0开始计数到自动重装载值-1,产生一个计数器溢出事件,然后计数器从ARR开始向下计数,计数到1再次产生一个计数器溢出事件,以此往复。

定时器工作原理

STM32F103系统构架知:TIM1、8在APB2上,TIM2、3、4、5、6、7在APB1上,APB1操作速度限于36MHz,APB2操作于全速72MHz。
在这里插入图片描述

基本定时器:TIM6、TIM7

TIM6、TIM7定时器主要功能:16位自动重装载累加计算器,16位可编程预分频器(1~65536),触发DAC的同步电路、产生DMA中断请求。

基本定时器框图在这里插入图片描述
时钟源: STM32F103基本定时器的时钟源,可以使用内部时钟源或外部时钟源。当使用内部时钟源(CN_INT)时,计时器的时钟频率由STM32内部时钟提供。当使用外部时钟源时,计时器的时钟频率由外部时钟信号提供,可以使用外部晶体振荡器、RC振荡器等外部时钟源。

预分频器:PSC预分频寄存器,用于设定定时器时钟的分频系数。

CNT计数器:用于记录定时器的当前值,从0开始计数,当CNT到达ARR时计数器重新从0开始计数(向上计数模式)。

自动重装载寄存器:ARR用于设定计时器的计时时长,当CNT到达该值时自动重新计数。
在这里插入图片描述
如何定时呢?
首先确定TIM6\TIM7时钟源(内部时钟CK_INT)经APB1预分频后分频提供,如果APB1预分频系数是1则频率不变,在库函数中APB1预分频的系数是2,即PCLK1=36MHz,所以定时器的时钟频率TIMxCLK为72Mhz(36*2)

计数器计数的计算方式:

CK_CNT = TIMxCLK/(PSC+1)     //CK_CNT最大65536

PSC是预分频器值

定时时间计算(计数器的中断周期*中断的次数):

Tout = ((ARR+1)*(PSC+1))/TIMxCLK

假设需要计时1s产生一次中断(已知TIMxCLk为72MHz):
先设ARR值为9999(ARR+1就是10000)
1 = (10000(PSC+1))/72000000*
因此PSC=7199

所以CK_CNT计算有什么用?

假设PSC是7199 所以CN_CNK=1000(hz)的时钟  计数一次花费时间1/1000 = 0.0001s = 0.1ms
所以Tout = (ARR+1)*(0.0001) 已知定时1s = Tout  所以ARR = 9999

示例代码

使用定时器TIM6中断方法控制LED灯闪烁,设置定时器1s中断一次,中断服务函数中控制LED实现LED闪烁功能。

定时器头文件定义

#ifndef __TIME_H
#define __TIME_H#include "stm32f10x.h"#define TIM         TIM4    
#define TIM_CLK     RCC_APB1Periph_TIM4     //RCC时钟
#define TIM_ARR     10000-1                 //定义ARR值
#define TIM_PSC     7200-1                  //定义PSC值
#define TIM_IRQ     TIM4_IRQn               //定义中断编号
#define TIM_IRQHandler TIM4_IRQHandler      //重定义中断函数void TIM_Init_Config(void);     #endif /* __TIME_H */

定时器源文件

#include "bsp_time.h"//中断优先级配置
void TIM_NVIC_Config(void){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);             //设置优先级分组NVIC_InitStructure.NVIC_IRQChannel = TIM_IRQ;               //指定需要配置的中断信号NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //先占优先级 1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          //从优先级   1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //使能NVICNVIC_Init(&NVIC_InitStructure);                             //初始化NVIC寄存器
}//定时器配置
void TIM_Init_Config(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;RCC_APB1PeriphClockCmd(TIM_CLK, ENABLE);                    //开启TIM4定时器所对应的APB1总线时钟TIM_TimeBaseInitStruct.TIM_Prescaler = TIM_PSC;             //设置TIM4的预分频系数TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数模式设置为递增模式TIM_TimeBaseInitStruct.TIM_Period = TIM_ARR;                //设置TIM4自动重载寄存器的值,用于设定定时器的定时时长TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;    //设置TIM4的时钟分割比,即分割细度
//    TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM, &TIM_TimeBaseInitStruct);TIM_ITConfig(TIM, TIM_IT_Update, ENABLE);//使能TIM4的溢出中断,将TIM_IT_Update设置为ENABLE即可。这一步非常重要,否则定时器无法产生中断信号,不会触发相应的中断服务程序。TIM_NVIC_Config();TIM_Cmd(TIM, ENABLE);   //使能定时器 -- 开启定时器
}

中断函数

//"stm32f10x_it.c"源文件
void TIM_IRQHandler(void){if(TIM_GetITStatus(TIM, TIM_IT_Update)!= RESET){LED_TOGGLE;TIM_ClearITPendingBit(TIM, TIM_IT_Update);}
}

代码讲解

定时器结构体成员

/*** @brief  TIM Time Base Init structure definition* @note   This structure is used with all TIMx except for TIM6 and TIM7.    */typedef struct
{uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.This parameter can be a number between 0x0000 and 0xFFFF */uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.This parameter can be a value of @ref TIM_Counter_Mode */uint16_t TIM_Period;            /*!< Specifies the period value to be loaded into the activeAuto-Reload Register at the next update event.This parameter must be a number between 0x0000 and 0xFFFF.  */uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.This parameter can be a value of @ref TIM_Clock_Division_CKD */uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounterreaches zero, an update event is generated and counting restartsfrom the RCR value (N).This means in PWM mode that (N+1) corresponds to:- the number of PWM periods in edge-aligned mode- the number of half PWM period in center-aligned modeThis parameter must be a number between 0x00 and 0xFF.@note This parameter is valid only for TIM1 and TIM8. */
} TIM_TimeBaseInitTypeDef;

TIM_Prescaler:指分配器的预分频值,一般为一定的预定值,大小范围为0到65536
TIM_CounterMode:指定时器的计数模式,一般有递增和递减模式

#define TIM_CounterMode_Up                 ((uint16_t)0x0000)
#define TIM_CounterMode_Down               ((uint16_t)0x0010)
#define TIM_CounterMode_CenterAligned1     ((uint16_t)0x0020)
#define TIM_CounterMode_CenterAligned2     ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3     ((uint16_t)0x0060)

TIM_Period:定时器的自动重装载值,大小范围为0到65536
TIM_ClockDivision:TIM的时钟分割比,即分割细度
TIM_RepetitionCounter: 指定TIM1和TIM8定时器的重复计数器值。当重复计数器的值减少到0时,将会产生一个溢出事件,并将TIMx的计数器重新从重复计数器的值开始计数。

定时器初始化函数

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)    //x从1到17

TIMx:定时器选择,可从1到17

使能/失能中断溢出函数

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)    //x从1到17

开启/关闭定时器函数

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)    //x从1到17

定时器中断标志位获取和清除

FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);        //获取定时器中断标志状态,检查x定时器是否发生中断事件//TIM_FLAG是需要检测的中断标志
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);                  //清除定时器中断标志,将x定时器指定的中断标志清零ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);              //获取定时器中断状态,检查x定时器是否产生中断信号//TIM_IT用于检测需要的中断源void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);            //清除定时器的中断状态

定时器中断标志状态函数一般先于定时器中断状态函数使用,并且在启用中断之前使用它们以确保不会丢失年中断信号;定时器中断状态函数则用于在ISR(中断服务程序)中检查中断状态。

通用定时器:TIM2、TIM3、TIM4、TIM5

定时器时钟来源:

  • 内部定时器(CK_INT)
  • 外部时钟模式1:外部输入脚(TIx)
  • 外部时钟模式2:外部触发输入(ETR)
  • 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器作为另一个定时器的预分频器。

编程步骤:

  • 配置系统时钟
  • 配置NVIC
  • 配置定时器
  • 配置定时器中断服务函数

高级定时器:TIM1、TIM8

待补写

定时器PWM输出原理

PWM输出就是对外输出脉宽(占空比)可调的方波信号,信号频率由自动重装载寄存器ARR的值决定,占空比由比较寄存器CCR的值决定。

通用定时器3控制通道1输出PWM脉冲

在这里插入图片描述
从上图通用定时器框图可以看出一个定时器只有一个计数器,所以同一个定时器输出的PWM频率是一样的,可以改变的是占空比大小(可以通过改变比较寄存器改变占空比大小)。

查看定时器TIM3复用的引脚图,如下所示
在这里插入图片描述

代码

PWM头文件定义

#ifndef __PWM_H
#define __PWM_H
#include "stm32f10x.h"#define PWM_TIM     TIM3
#define PWM_TIM_CLK RCC_APB1Periph_TIM3#define PWM_TIM_GPIP_PORT   GPIOA
#define PWM_TIM_GPIO_CLK    RCC_APB2Periph_GPIOA
#define PWM_TIM_GPIO_Pin    GPIO_Pin_6void PWM_TIM_Mode_Init(uint16_t freq, uint16_t duty);#endif /* __PWM_H */

PWM源文件

#include "bsp_pwm.h"/**
* @brief 初始化PWM的GPIO为复用模式
*
* @retval None
*/
void PWM_TIM_GPIO_Init(void){GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(PWM_TIM_GPIO_CLK, ENABLE);   //开启GPIOA时钟GPIO_InitStruct.GPIO_Pin = PWM_TIM_GPIO_Pin;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;        //设置引脚为复用推挽输出模式GPIO_Init(PWM_TIM_GPIP_PORT, &GPIO_InitStruct);     //初始化函数
}/**
* @brief 初始化TIM为PWM输出模式
*
* @param freq PWM的频率(kHz)
* @param duty PWM的占空比(0~100)
* @retval None
*/
void PWM_TIM_Mode_Init(uint16_t freq, uint16_t duty){uint16_t arr = 36000/freq;      //freq是频率,单位是khz   //将频率PWM_TIM_GPIO_Init();//配置定时器TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_OCInitTypeDef TIM_OCInitStruct;//开启定时器时钟RCC_APB1PeriphClockCmd(PWM_TIM_CLK, ENABLE);TIM_TimeBaseInitStruct.TIM_Period = arr-1;TIM_TimeBaseInitStruct.TIM_Prescaler =1; //时钟预分频数  设置频率f = 36mhz  因为 t = TIMx_CLK/(PSC+1) --> t = 1/(36Mhz) --> f = 1/t  --> f = 1/t = 36mhzTIM_TimeBaseInitStruct.TIM_ClockDivision = 0;   //采样分频TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;    //计数模式TIM_TimeBaseInit(PWM_TIM, &TIM_TimeBaseInitStruct);TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;      //设置为PWM1模式TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;  //输出使能TIM_OCInitStruct.TIM_Pulse = (arr+1)*duty/100-1;    //设置占空比TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;      //输出极性//初始化PWM_TIM输出比较通道1TIM_OC1Init(PWM_TIM, &TIM_OCInitStruct);//使能OC1输出比较多预装载以及TIMx的配置寄存器TIM_OC1PreloadConfig(PWM_TIM, TIM_OCPreload_Enable);//开启定时器TIM_Cmd(PWM_TIM,ENABLE);
}

主程序

PWM_TIM_Mode_Init(20, 80);    //初始化时调用一次即可

TIM_OCInitTypeDef结构体讲解

typedef struct
{uint16_t TIM_OCMode;        /*!< 指定TIM输出比较的模式 */uint16_t TIM_OutputState;   /*!< 指定TIM输出比较通道的输出状态(开启或关闭) */uint16_t TIM_OutputNState;  /*!< 指定TIM互补输出比较通道的输出状态(开启或者关闭),只对定时器TIM1、TIM8有效 */uint16_t TIM_Pulse;         /*!< 指定TIM输出比较通道的占空比 */uint16_t TIM_OCPolarity;    /*!< 指定TIM输出比较通道的极性 */uint16_t TIM_OCNPolarity;   /*!< 指定TIM互补输出比较通道的极性 */uint16_t TIM_OCIdleState;   /*!< 指定TIM输出比较通道在闲置或者空档时的输出电平状态 */uint16_t TIM_OCNIdleState;  /*!< 指定TIM互补输出比较通道在空档状态下输出的电平状态 */
} TIM_OCInitTypeDef;

ARR决定PWM周期
CCRx决定PWM占空比大小
ARR计算:

由Tout = ((ARR+1)*(PSC+1))/TIMxCLK           --   已知TIMxCLK = 72Mhz且PSC设置为1
因此T=(arr+1)/36            -- 已知 t = 1/f
所以1/f = (arr+1)/36  
得 arr = 36000/f

总结

要多用,要多用!

参考资料

https://www.bilibili.com/video/BV1b54y1m71K/?spm_id_from=333.337.search-card.all.click&vd_source=101ae2594bcc6dbee11cc6670869bc2ehttps://blog.csdn.net/qq_44016222/article/details/123507270?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-20-123507270-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-20-123507270-null-null.nonecasehttps://www.guyuehome.com/39703#%E4%B8%89%E3%80%81%E5%AE%9A%E6%97%B6%E5%99%A8%E8%BE%93%E5%87%BAPWMhttps://blog.csdn.net/qq_38410730/article/details/79996222

在这里插入图片描述

http://www.jmfq.cn/news/5167549.html

相关文章:

  • 正规的食品行业网站开发/合肥全网推广
  • 网站建设业务员主要工作/百度排名优化专家
  • 网站关键词排名下降/口碑营销的定义
  • 淄博网站建设服务/最有效的宣传方式
  • 免费网站模板html/实事新闻热点
  • asp网站开发教程pdf/游戏推广员一个月能赚多少
  • logo设计在线生成免费版/seo技术分享博客
  • 简述网站建设过程步骤/美国seo薪酬
  • 电子商务网站建设的意义/新站整站快速排名
  • 0基础多久学会网站架构/青岛网络优化代理
  • 上海 网站建设 案例/怎样做竞价推广
  • 网站更新/app推广拉新接单平台
  • 上海建桥学院门户网站/百度推广外推联系方式
  • 做网赌需要在哪些网站投广告/抖音推广引流平台
  • 临沂外贸网站建设/今天的新闻最新消息
  • 青岛企业网站制作哪家好/淘宝seo是什么
  • 在国内做博彩网站代理/代写
  • 大众点评如何做团购网站/企业网站营销实现方式
  • 景县做网站/百度怎么打广告
  • 公司想为一个产品做多个网站/西安网站seo推广
  • 上海未成年人思想道德建设网站/谷歌官网登录入口
  • 做外贸的阿里巴巴网站是哪个更好/推广app赚佣金平台
  • wordpress网站统计插件/广州seo关键词优化费用
  • 麻章网站建设公司/广告网络
  • 58网站一起做网店/高端定制网站建设
  • 网页设计意图怎么写/百度seo软件曝光行者seo
  • 网站设计怎么算间距/什么是淘宝搜索关键词
  • 网站购买云空间/百度一下你就知道百度官网
  • 阿里云 建设网站怎么样/2024年将爆发新瘟疫
  • 如何替换网站ico图标/百度认证营销推广师