stm32之定時器運用———呼吸燈
呼吸燈原理
1.在類比電路中,呼吸燈的實現可以通過一個呈現正弦的電壓控制,這個電壓是連續變化的,所以肉眼看上去就是逐漸變暗,逐漸變亮。
2.而在數位電路中如何實現這種效果呢?就需要通過pwm,也就是脈衝寬度調製,將模擬量轉換為數字量。只要能夠用連續電壓控制的東西都是可以通過pwm方式來驅動,效果是一樣的。
3.
上面一塊區域的面積等於對應下來的矩形的面積,當然,取得塊的間隔越小(即pwm的週期越小),效果越好。這時,如果週期定了,就可以通過改變佔空比來實現面積的改變,從而模擬出上面那張圖的電壓的連續變化。
注意:pwm波的高度是一定的,所以只能通過改變寬度(佔空比)來實現面積的改變
4.說明:觀察這張圖,會發現下面的pwm波是中心與上面的對齊(即pwm中心為高電平),然後左右擴充套件,每個波的週期還是一樣。當然這時可以的。但更多的是運用左對齊(起始為高電平),然後向右擴充套件直到面積到達要求。
5.stm32實現pwm輸出的原理:設點一個值為a,然後在設定一個重灌值b,b>a.開始計數,當計數值小於a時,輸出高電平,當計數值大於a時,輸出低電平,直到計數到b,到b後又重複來一遍。所以改變這個a就可以改變佔空比、
6.PWM 的輸出其實就是對外輸出脈寬可調(即佔空比調節)的方波訊號,訊號頻率是由自動重灌暫存器 ARR 的值決定,佔空比由比較暫存器 CCR 的值決定。其示意圖如圖 19.1.2 所示:
從圖 19.1.2 中可以看到,PWM 輸出頻率是不變的,改變的是 CCR 暫存器內的值,此值的改變將導致 PWM 輸出訊號佔空比的改變。佔空比其實就是一個週期內高電平時間與週期的比值。PWM 輸出比較模式總共有 8 種,具體由暫存器 CCMRx 的位 OCxM[2:0]配置。我們這裡只講解最常用的兩種 PWM 輸出模式:PWM1 和 PWM2,PWM1 和 PWM2 這兩種模式用法差不多,區別之處就是輸出電平的極性不同。如圖 19.1.3 所示:
pwm輸出配置步驟
其實 PWM 輸出和上一章一樣也是通用定時器的一個功能,因此還是要用到定時器的相關配置函式
1.因為pwm是由定時器輸出的,既然用到定時器,就先要使能定時器的時鐘:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//我們用的為tim14定時器
2.因為用到io作為輸出,所以要開啟io口的時鐘:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//注意:io口的外設均是掛在AHB1總線上的
3.通過看手冊,TIM14 的 CH1 通道對應的管腳是 PF9,而pf9有很多複用功能,所以要選擇pf9的輸出模式:通過函式:
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource,
uint8_t GPIO_AF);//前兩個引數不說了。第三個引數為複用為哪種功能,這裡我們使用的是 TIM14 功能,所以引數為 GPIO_AF_TIM14
所以函式為:GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);//AF就是複用的意思
4.配置io口,同之前led時一樣,只不過引數有些變化:
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//PF9 管腳模式配置為複用輸出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度不變
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推完輸出不變
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上啦輸出不變
GPIO_Init(GPIOF,&GPIO_InitStructure);
5.初始化定時器引數,包含自動重灌值,分頻係數,計數方式等.同前面使用定時器中斷
TIM_TimeBaseInitStructure.TIM_Period = pre;//預裝值,這裡依然通過引數傳遞進來
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//預分頻係數
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//固定不變
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數
TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStructure);
6.定時器基本的引數配置完了,但是還沒設定它為pwm輸出模式:
用到的函式為:
void TIM_OCxInit(TIM_TypeDef* TIMx,TIM_OCInitTypeDef* TIM_OCInitStruct);//
注意:我們知道每個通用定時器有多達 4 路 PWM 輸出通道(對於 TIM9-TIM14 最多有 2 路),所以TIM_OCxInit 函式名中的 x 值可以為 1/2/3/4。函式的第一個引數相信大家一看就清楚,是用來選擇定時器的。第二個引數是一個結構體指標變數:
typedef struct
{
uint16_t TIM_OCMode; //比較輸出模式
uint16_t TIM_OutputState; //比較輸出使能
uint16_t TIM_OutputNState; //比較互補輸出使能
uint32_t TIM_Pulse; //脈衝寬度
uint16_t TIM_OCPolarity; //輸出極性
uint16_t TIM_OCNPolarity; //互補比較輸出極性
uint16_t TIM_OCIdleState; //空閒狀態下比較輸出狀態
uint16_t TIM_OCNIdleState; //空閒狀態下比較輸出狀態
}
這裡我們比較常用的 PWM 模式所需的成員變數:
TIM_OCMode:比較輸出模式選擇,總共有 8 種,最常用的是 PWM1 和 PWM2。
TIM_OutputState:比較輸出使能,用來使能 PWM 輸出到 IO 口。
TIM_OCPolarity:輸出極性,用來設定輸出通道電平的極性,是高電平還是低電平。
結 構 體 內 其 他 的 成 員 變 量 TIM_OutputNState , TIM_OCNPolarity ,
TIM_OCIdleState 和 TIM_OCNIdleState 是高階定時器才用到的。
所以配置完為:
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC1Init(TIM14,&TIM_OCInitStructure);
7.開啟定時器
TIM_Cmd(TIM14,ENABLE);
8.修改 TIMx_CCRx 的值控制佔空比(這一步寫在主函式中,因為要實時去改變佔空比).
其實經過前面幾個步驟的配置,PWM 已經開始輸出了,只是佔空比和頻率是固定的,例如本章要實現呼吸燈效果,那麼就需要調節 TIM14 通道 1 的佔空比,通過修改 TIM14_CCR1 值控制。調節佔空比函式是:
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);//對 於 其 他 通 道 , 分 別 有 對 應 的 函 數 名 , 函 數 格 式 是 TIM_SetComparex(x=1/2/3/4)。
分析:第一個引數不說了,第二個引數是計數值。。注意:這個計數值一定要小於前面設定定時器時總的預裝載值(TIM_TimeBaseInitStructure.TIM_Period = pre);
程式碼:
pwm.c
#include "pwm.h"
void TIM14_PWM_Init(u16 pre,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//´ٍ؟ھ¶¨ت±ئ÷µؤت±ضس
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//زٍخھسأµ½¶ث؟ع£¬ثùزشزھت¹ؤـ¶ث؟عت¼ت±ضس£¬ءيحâioµؤحâة趼تا¹ز½سشعAHB1×ـدكةدµؤ
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//ثظ¶ب
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//حئحئحىتن³ِ
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//ةدہ
GPIO_Init(GPIOF,&GPIO_InitStructure);//شع³ُت¼»¯ز»دآ
TIM_TimeBaseInitStructure.TIM_Period = pre;//ةèضأ¶¨ت±ئ÷µؤضـئع£¬ز²¾حت£×¢زâ£؛صâہïخھ´«µؤ²خت
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//¶¨ت±ئ÷ش¤·ضئµدµت
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//ح¨³£²»ذق¸ؤثû£¬¹ج¶¨µؤ£¬ز»°مآج²¨µؤت±؛ٍسأ
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//دٍةد¼ئت£¬´سءم؟ھت¼¼ئت£¬¼ئتµ½ضط×°ضµ
TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStructure);//³ُت¼»¯ز»دآ
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC1Init(TIM14,&TIM_OCInitStructure);
TIM_Cmd(TIM14,ENABLE);
}
mian.c
int main()
{
u8 fx = 0;
u32 i = 0;//ำรภดภผำ
RCC_HSE_Config(8,336,2,7);
Beep_Init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SysTick_Init(168);
key_init();
LED_Init();
TIM14_PWM_Init(500-1,84-1);//2000hz,ึฦฺถจมห,0.5MS
//while(1)
//{
// if(fx==0)
//{
// i++;
// if(i==300)
// {
// fx=1;
// }
//}
//else
//{
// i--;
//if(i==0)
// {
// fx=0;
//}
//}
// TIM_SetCompare1(TIM14,i);
//delay_ms(10);
//}
/********the second code*****/
while(1)
{
while(i<=300)
{
TIM_SetCompare1(TIM14,i);
delay_ms(10);
i++;
}
while(i!=0)
{
TIM_SetCompare1(TIM14,i);
delay_ms(10);
i--;
}
}
}
補充:
1.主函式中註釋程式碼是官方的程式碼,下面是我自己原創的程式碼。官方程式碼是引用了一個變數來判斷方向。
2.觀察主函式的程式碼,我們設定的定時器為0.5ms,意思就是pwm波的週期為0.5ms,而每次執行完TIM_SetCompare1(TIM14,i);
波形(佔空比)就會改變,而後面寫的delay_ms(10);是為了維持這一個波形一段時間,反映在模擬訊號上就是電壓變化的很平緩,很慢,自然亮度的變化也就很緩慢自然。自然,這個延遲時間知道要大於你定時時間好幾倍吧-.-
擴充套件
試試用pwm輸出來控制板子上的蜂鳴器來實現控制他的聲音大小
提示:看電路圖發現beep連在pf9上,而pf9本來就是tim13的複用口。所以只需在這個程式碼基礎上修改定時器的標號為tim13即可
相關推薦
stm32之定時器運用———呼吸燈
呼吸燈原理 1.在類比電路中,呼吸燈的實現可以通過一個呈現正弦的電壓控制,這個電壓是連續變化的,所以肉眼看上去就是逐漸變暗,逐漸變亮。 2.而在數位電路中如何實現這種效果呢?就需要通過pwm,也就是脈衝寬度調製,將模擬量轉換為數字量。只要能夠用連續電壓控制的
STM32之定時器中斷控制LED閃爍
上篇部落格我們是用延時函式實現了LED的閃爍,今天我們使用STM32的定時器來使LED閃爍。 關於32的定時器的種類,今天我在這先不做過多的說明,有時間我會再另寫一篇部落格來專門介紹32的定時器。今天我們使用32的定時器3來產生中斷,以實現LED的閃爍。 今
STM32-自學筆記(9.SysTick定時器控制LED燈閃爍,程式用到的庫函式介紹)
1.SysTick_CLKSourceConfig 函式原型:viod SysTick_CLKSourceConfig (u32 SysTick_CLKSource) 功能:選擇SysTick的時鐘源 引數:SysTick_CLKSource:SysTick時鐘源 引數:S
STM32-自學筆記(8.使用STM32的SysTick定時器控制LED燈閃爍)
SysTick定時器,被稱為“系統節拍時鐘”。SysTick屬於ARM Cortex-M3核心的一個內設,STM32也帶有SysTick定時器。 SysTick定時器的基本結構 SysTick工作原理: SysTick從時鐘源介面獲得時鐘驅動 從重灌暫存器將
STM32通用定時器的基本定時器功能實現燈閃爍
/*MAIN.C*/ /* Includes ------------------------------------------------------------------*/#inclu
STM32實戰3.定時器控制LED燈閃爍(定時器1)
#include "sys.h" #include "led.h" #include "delay.h" #include "TIM1.h" int main(void) { NVIC_Configuration(); LED_Init(); delay_init
定時器/計數器0之定時器
.com 函數調用 wid 延時 mod main images .cn cnblogs /* 效果說明: 定時器中斷:通過單片機計數使程序執行 一秒中斷一次,中斷發生時高四位亮一秒,中斷發生後又回到主程序 */ #include <
STM32--TIM定時器時鐘分割(疑難)
疑難 計數器 謝謝 term 比例 是什麽 tab 超過 定時 不太明白 (1) TIM_Perscaler來設置預分頻系數; (2) TIM_ClockDivision來設置時鐘分割(時鐘分頻因子); (3) TIM_Counte
11.按鍵驅動之定時器防抖(詳解)
pri pos long 超時時間 device queue pen fun cti 本節目標: 通過定時器來防止按鍵抖動,測試程序是使用上節的:阻塞操作的測試程序 1.如下圖所示,在沒有定時器防抖情況下,按鍵沒有穩定之前會多次進入中斷,使得輸出多個相同信息出來
(筆記)Linux內核學習(八)之定時器和時間管理
全局變量 define 結構 load 統計 object 一個 完成 溢出 一 內核中的時間觀念 內核在硬件的幫助下計算和管理時間。硬件為內核提供一個系統定時器用以計算流逝的時間。系 統定時器以某種頻率自行觸發,產生時鐘中斷,進入內核時鐘中斷處理程序中進行
java學習筆記之定時器
blog div this rgs date row demo sdf 時間 定時器 1 package pack01_timer; 2 3 import java.io.File; 4 import java.text.ParseException; 5 i
STM32-通用定時器基本定時功能
數字 vision 實現 定義 還要 可能 輸出 給定 禁止 1. STM32的Timer簡介 STM32中一共有11個定時器,其中2個高級控制定時器,4個普通定時器和2個基本定時器,以及2個看門狗定時器和1個系統嘀嗒定時器。其中系統嘀嗒定時器是前文中所描述的Sys
Linux驅動之定時器在按鍵去抖中的應用
arc div 測試 完整 esc arm 是否 reg blog 機械按鍵在按下的過程中會出現抖動的情況,如下圖,這樣就會導致本來按下一次按鍵的過程會出現多次中斷,導致判斷出錯。在按鍵驅動程序中我們可以這麽做: 在按鍵驅動程序中我們可以這麽做來取消按鍵抖動的影響:當出現
[轉]解決STM32開啟定時器時立即進入一次中斷程序問題
結果 程序 相關 fig 請求 啟動 其中 邏輯性 ear 整理:MilerShao 在用到STM32定時器的更新中斷時,發現有些情形下只要開啟定時器就立即進入一次中斷。準確說,只要使能更新中斷允許位就立即響應一次更新中斷【當然前提是相關NVIC也已經配置好】。
js之定時器操作
abs 第一個字符 tin type itl ntb 跑馬燈 get function <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">
STM32-(SysTick定時器,EXTI外部中斷/事件控制器)
Systick系統定時器 介紹:systick定時器上屬於CM3核心中的一個外設,內嵌在NVIC中。系統定時器是一個24位向下計數的計數器,計數器每一次計數的時間是1/SYSTICK,一般我們設定SYSTICK為72M。當過載數值暫存器的值遞減到0時,系統定時器產生一次中斷,以此迴圈。
遊戲伺服器之定時器
遊戲伺服器之定時器 1.1 簡單介紹 在遊戲中的關於定時任務的應用很多,在此就不舉例了。所謂定時任務,簡單來說就是t毫秒後執行相應的任務。因為這裡用的例子都是博主工作時用到的遊戲伺服器中的,所以相關程式碼會比較詳盡,如若只是瞭解定時器的大概實現,按照博主所標註的順序,只看重點
STM32cubeMX 基於stm32的定時器實現定時1秒LED閃爍。
軟體: STM32CubeMX V4.25.0 keil_u5 韌體庫版本: STM32Cube FW_F1 V1.6.1 硬體: OneNet 麒麟座V1.4 在STM32CubeMX中新建專案,選擇正確的MCU型號
Java多執行緒學習筆記20之定時器Timer
詳細程式碼見:github程式碼地址 本節內容: 定時器Timer的使用及分析 1) 如何實現指定時間執行任務 2) 如何實現按指定週期執行任務 第五章 定時器Timer 定時/計劃
PHP 程式碼自動執行之定時器
<?php ignore_user_abort();//關閉瀏覽器仍然執行 set_time_limit(0);//讓程式一直執行下去 $interval=3;//每隔一定時間執行 do{ $msg = date("Y-m-d H:i:s"); file_put_content