STM32-TIM定時器中斷

目錄

一、TIM(Timer)定時器簡介

二、定時器類型

2.1基本定時器結構

2.2通用定時器結構

2.3高級定時器結構

三、定時中斷基本結構

四、時序圖分析

4.1 預分頻器時序

4.2 計數器時序

4.3 計數器無預裝時序(無影子寄存器)

4.4?計數器有預裝時序(有影子寄存器)

五、RCC時鐘樹?

六、開發步驟

七、定時器函數

八、實驗

8.1定時器定時中斷

8.2定時器外部時鐘


一、TIM(Timer)定時器簡介

①定時器可以對輸入的時鐘進行計數,并在計數值達到設定值時觸發中斷
②16位計數器、預分頻器、自動重裝寄存器的時基單元,在72MHz計數時鐘下可以實現最大59.65s的定時

計數器:執行計數定時的一個寄存器,每來一個時鐘,計數器加1

預分頻器:對計數器的時鐘進行分頻,讓這個計數更加靈活

自動重裝寄存器:計數的目標值,計多少個時鐘來申請一次中斷
③不僅具備基本的定時中斷功能,而且還包含內外時鐘源選擇、輸入捕獲、輸出比較、編碼器接口、主從觸發模式等多種功能
④根據復雜度和應用場景分為了高級定時器、通用定時器、基本定時器三種類型

二、定時器類型

2.1基本定時器結構

主模式觸發DAC功能:把定時器的更新事件映射到觸發輸出TRGO(Trigger Out)的位置,TRGO直接接到DAC的觸發轉換引腳上,這樣就不需要通過中斷來觸發DAC轉換了。實現了硬件的自動化。??

?通用定時器和高級定時器除了向上計數模式,還有向下計數模式和中央對齊模式

2.2通用定時器結構

2.3高級定時器結構

三、定時中斷基本結構

四、時序圖分析

4.1 預分頻器時序

計數器計數頻率:CK_CNT = CK_PSC / (PSC + 1)

4.2 計數器時序

計數器溢出頻率:CK_CNT_OV = CK_CNT / (ARR + 1)= CK_PSC / (PSC + 1) / (ARR + 1)

計數器時間:(PSC + 1)(ARR + 1)/CK_PSC

4.3 計數器無預裝時序(無影子寄存器)

4.4?計數器有預裝時序(有影子寄存器)

五、RCC時鐘樹?

作用:產生和配置時鐘,將配置好的時鐘發送到各個外設系統

開發技巧:

在SystemInit函數中,首先啟動內部8MHz時鐘為系統時鐘運行,然后再啟動外部時鐘,進入PLL鎖相環進行倍頻,8MHz倍頻9倍,得到72MHz,鎖相環輸出穩定之后,選擇鎖相環輸出為系統時鐘,這樣就把系統時鐘由8MHz變成了72MHz。

實際問題:

如果外部晶振出現問題,程序時鐘慢了大概10倍,定時器定時1s,結果過了大概10s才進中斷。是因為現在是以內部時鐘8MHz運行的

六、開發步驟

①RCC打開時鐘

②選擇時基單元的時鐘源

③結構體配置時基單元(預分頻器,自動重裝器,計數模式)

④配置輸出中斷控制,允許更新中斷輸出到NVIC

⑤配置NVIC,在NVIC中打開定時器中斷的通道,并分配一個優先級

⑥運行控制,使能計數器

⑦寫定時器中斷函數

七、定時器函數

=====================================================================

=================================基本函數=============================

void TIM_DeInit(TIM_TypeDef* TIMx);

//定時器恢復缺省配置


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

//時基單元初始化

//第一個參數:某個定時器,第二個參數:結構體

void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

//把結構體變量賦默認值

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

//使能計數器

//第一個參數:TIMx選擇定時器,第二個參數:使能或失能

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

//使能中斷輸出信號(中斷輸出控制)

//第一個參數:TIMx選擇定時器,第二個參數:哪個中斷輸出,第三個參數:使能或失能

=====================================================================

=========================配置時鐘輸入的函數=============================

void TIM_InternalClockConfig(TIM_TypeDef* TIMx);

//選擇內部時鐘


void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

//選擇ITRx其他定時器時鐘

//第一個參數:選擇配置哪個定時器,第二個參數:選擇要接入哪個定時器


void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);

//選擇TIx捕獲通道的時鐘

//第一個參數:TIMx,第二個參數:TIMx具體哪個引腳,第三、四個參數:輸入極性和濾波器


void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);

//ETR通過外部時鐘模式1輸入時鐘

//第一個參數:TIMx,第二個參數:外部觸發預分頻器,第三、四個參數:輸入極性和濾波器


void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,?
uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);

//ETR通過外部時鐘模式2輸入時鐘

//第一個參數:TIMx,第二個參數:外部觸發預分頻器,第三、四個參數:輸入極性和濾波器


void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);

//單獨配置ETR引腳的預分頻器、極性、濾波器

//第一個參數:TIMx,第二個參數:外部觸發預分頻器,第三、四個參數:輸入極性和濾波器

=====================================================================

===================更改關鍵參數函數(預分頻值,自動重裝載值)==============

void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);

//修改預分頻值

//第一個參數:TIMx,第二個參數:預分頻值,第三個參數:寫入模式


void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);

//修改計數器的計數模式

//第一個參數:TIMx,第二個參數:新的計數器模式


void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

//自動重裝器預裝功能配置

//第一個參數:TIMx,第二個參數:預裝功能使能或失能

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);

//給計數器值

//第一個參數:TIMx,第二個參數:計數器值


void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);

//給自動重裝器寫入值

//第一個參數:TIMx,第二個參數:自動重裝值

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

//獲取計數器值


uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);

//獲取預分頻值

=====================================================================

============================獲取和清除標志位函數========================

//主函數

FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);

//中斷函數

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

八、實驗

8.1定時器定時中斷

實驗現象:1s計數加一

代碼實現

Timer.c

#include "stm32f10x.h"                  // Device headervoid Timer_Init(void)
{/*一、RCC開啟時鐘*/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 = 10000 - 1;//ARR自動重裝器值TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//PSC預分頻器值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重復計數器值(高級定時器才有)TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);/*避免剛初始化就進入中斷(復位就是1,而不是0)*/TIM_ClearFlag(TIM2,TIM_FLAG_Update);/*四、配置輸出中斷控制,允許更新中斷輸出到NVIC*/TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//開啟更新中斷到NVIC的通路/*五、配置NVIC,在NVIC打開定時器中斷的通道,分配優先級*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//中斷通道NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;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){TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}
*/

Timer.h

#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,1,"Num:");OLED_ShowString(2,1,"CNT:");while (1){OLED_ShowNum(1,5,Num,5);OLED_ShowNum(2,5,TIM_GetCounter(TIM2),5);//觀察CNT計數器值的變化情況}
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){Num ++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}

8.2定時器外部時鐘

方法:定時器指定的外部引腳輸入一個方波信號,來提供定時器計數的時鐘?

實驗現象:利用對射式紅外傳感器來手動模擬一個外部時鐘,用擋光片,依次遮擋、移開來模擬一個方波,定時器計數值(CNT)逐次加一,當CNT到9后,產生一次中斷,Num加一,CNT清零重新計數

代碼實現

Timer.c

#include "stm32f10x.h"                  // Device headervoid Timer_Init(void)
{/*一、RCC開啟時鐘 + GPIOA的初始化*/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);/*二、選擇時基單元的時鐘源*/TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);//通過ETR的外部時鐘模式2,不分頻,不反向(高電平/上升沿有效),外部觸發濾波器/*三、配置時基單元(預分頻器,自動重裝器,計數模式)*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;//ARR自動重裝器值TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;//PSC預分頻器值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重復計數器值TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);/*避免剛初始化就進入中斷(復位就是1,而不是0)*/TIM_ClearFlag(TIM2,TIM_FLAG_Update);/*四、配置輸出中斷控制,允許更新中斷輸出到NVIC*/TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);/*五、配置NVIC,在NVIC打開定時器中斷的通道,分配優先級*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);/*六、運行控制,使能計數器*/TIM_Cmd(TIM2,ENABLE);
}/*查看CNT的值*/
uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);
}/*中斷函數模板
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}
*/

Timer.h

#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);
uint16_t Timer_GetCounter(void);#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,1,"Num:");OLED_ShowString(2,1,"CNT:");while (1){OLED_ShowNum(1,5,Num,5);OLED_ShowNum(2,5,Timer_GetCounter(),5);//觀察CNT計數器值的變化情況}
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){Num ++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210687.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210687.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210687.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C#的線程技術及操作

每個正在操作系統上運行的應用程序都是一個進程,一個進程可以包括一個或多個線程。線程是操作系統分配處理器時間的基本單元,在進程中可以有多個線程同時執行代碼。每個線程都維護異常處理程序、調度優先級和一組系統用于在調度該線程前保存線程上下文的…

PyQt6 水平布局Horizontal Layout (QHBoxLayout)

鋒哥原創的PyQt6視頻教程: 2024版 PyQt6 Python桌面開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili2024版 PyQt6 Python桌面開發 視頻教程(無廢話版) 玩命更新中~共計41條視頻,包括:2024版 PyQt6 Python桌面開發 視頻教程(無廢話版…

[足式機器人]Part2 Dr. CAN學習筆記-自動控制原理Ch1-1開環系統與閉環系統Open/Closed Loop System

本文僅供學習使用 本文參考: B站:DR_CAN Dr. CAN學習筆記-自動控制原理Ch1-1開環系統與閉環系統Open/Closed Loop System EG1: 燒水與控溫水壺EG2: 蓄水與最終水位閉環控制系統 EG1: 燒水與控溫水壺 EG2: 蓄水與最終水位 h ˙ q i n A ? g h A R \dot{…

阿里云SLS采集jvm日志

一、背景 java應用部署在阿里云的k8s容器里,采集其日志的需求則是一個不可缺少的。而不同公司的jvm日志會存在很大的差異,所以本文僅以我的實際情況作一個示例,僅供有需要采集jvm日志的同學們一個參考。 我們打印的Jvm日志格式見下&#xf…

【干貨分享】KingIOServer與三菱PLC的通訊的應用案例

哈嘍,大家好,我是雷工! 最近一個項目涉及用KingIOServer采集三菱PLC數據,特記錄通訊過程方便備忘。 一、版本說明: 1、KingIOServer版本:3.7SP2 2、PLC型號:Q03UDV 和Q03UDE自帶以太網網口。…

Vue筆記(五)路由進階

導航守衛 vue-router提供導航守衛主要通過跳轉或**取消*的方式守衛導航。有很多方式植入路由導航中:全局的、單個路由獨享的,或者組件級的。 全局前置守衛:beforeEach。 每個守衛接收兩個參數: to:將要進入的目標fr…

VUE寶典之el-dialog使用

文章目錄 🍁前言🍁el-dialog簡介🍁el-dialog屬性🍁el-dialog示例🍁父子組件值傳遞示例 🍁前言 el-dialog是Element UI庫中的一個重要組件,用于在Vue應用程序中創建彈出框。它提供了一組實用的屬…

【Dubbo3云原生微服務開發實戰】「Dubbo前奏導學」 RPC服務的底層原理和實現

RPC服務 RPC服務介紹RPC通信模式RPC架構組成RPC技術要點RPC通信技術選項分析RPC實戰開發6大基礎組件基礎組件之Guava基礎組件之Hutools基礎組件之ReflectionASM基礎組件之FastJSON/FastJSON2基礎組件之FST相比FastJSON的優勢 基礎組件之Commons-Codec RPC框架層面選項分析RPC組…

持續集成交付CICD:Jenkins配置Nexus制品上傳流水線

目錄 一、實驗 1.Jenkins配置制品上傳流水線 二、問題 1.上傳制品顯示名稱有誤 一、實驗 1.Jenkins配置制品上傳流水線 (1) 新建流水線項目 (2)描述 (3)添加參數 (4)查看構建首頁 (5&…

實現簡易的一對一用戶聊天

服務端 package 一對一用戶;import java.awt.BorderLayout; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Vector…

Vue.js - 界面設計工具和UI組件庫

ViewDesign ViewDesign是一款開源的在線設計工具,它主要提供了一種可視化的界面設計方法,可以幫助設計師和開發人員更高效地完成界面設計和開發工作。 ViewDesign的特點是支持在線協作,可以多人同時進行設計,提高了設計效率&…

Redis課程:黑馬點評

文章目錄 基于Redis實現短信登錄商戶查詢緩存優惠券秒殺一人一單 分布式鎖Redis分布式鎖誤刪情況說明解決Redis分布式鎖誤刪問題使用lua腳本解決分布式鎖的原子性問題 基于阻塞隊列實現秒殺優化Redis消息隊列優化秒殺業務達人探店參考 本文是根據黑馬程序員的視頻課程 黑馬程序…

vscode 開發c環境

前置條件: 1.vscode安裝C/C Extension Pack擴展 2.安裝gcc或者clang開發環境 在工程.vscode目錄下創建task任務文件 tasks.json {"tasks": [{"type": "cppbuild","label": "build","command": &q…

Kubernetes架構及核心部件

文章目錄 1、Kubernetes集群概述1.1、概述1.2、通過聲明式API即可 2、Kubernetes 集群架構2.1、Master 組件2.1.1、API Server2.1.2、集群狀態存儲2.1.3、控制器管理器2.1.4、調度器 2.2、Worker Node 組件2.2.1、kubelet2.2.2、容器運行時環境2.2.3、kube-proxy 2.3、圖解架構…

深入解析Node.js:V8引擎、事件驅動和非阻塞式I/O

文章目錄 1. 引言2. 什么是Node.js?3. V8引擎3.1 V8引擎簡介3.2 V8引擎的特點 4. 事件驅動4.1 事件循環4.2 事件觸發與監聽4.2.1 代碼示例 4.3 異步回調4.3.1 代碼示例 5. 非阻塞式I/O5.1 非阻塞式I/O的優勢5.2 異步與同步的對比5.2.1 同步I/O的代碼示例5.2.2 異步I…

前端知識筆記(三)———CSS核心功能手冊:從熟悉到精通

參考HTML代碼 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wi…

指針 注意事項

指針變量的本質是用來放地址&#xff0c;而一般的變量是放數值的。 1、指針的定義&#xff08;兩種形式&#xff09; ①int x3; int *p&x ②int x; int *p&#xff1b; x3&#xff1b;p&x int*p中 *p和p的差別&#xff1a;簡單說*p是數值&#xff0c;p是地址&a…

Linux 系統上配置 SSH 密鑰

1. 生成 SSH 密鑰 打開終端&#xff0c;運行以下命令來生成 SSH 密鑰&#xff1a; ssh-keygen -t rsa -b 4096 -C "wqzbxhexample.com" 替換 "wqzbxhexample.com" 為你在 GitHub 注冊時使用的郵箱地址。 2. 添加 SSH 密鑰到 SSH 代理 運行以下命令來啟…

ROS gazebo 機器人仿真,環境與robot建模,添加相機 lidar,控制robot運動

b站上有一個非常好的ros教程234仿真之URDF_link標簽簡介-機器人系統仿真_嗶哩嗶哩_bilibili&#xff0c;推薦去看原視頻。 視頻教程的相關文檔見&#xff1a;6.7.1 機器人運動控制以及里程計信息顯示 Autolabor-ROS機器人入門課程《ROS理論與實踐》零基礎教程 本文對視頻教程…

java物聯網協議解析插件,java iot對接解析框架.java物聯網架構的設計思路

一般來說&#xff0c;物聯網開發則hi對硬件設備進行信息采集&#xff0c;所以建議技術棧如下&#xff1a; 物聯網開發技術棧一般如下&#xff1a; nettyspringbootrocketmqredismagic-byte 其中netty用于tcp和數據接入 rockemqt用于消息臨時儲存中轉&#xff0c; springboot就…