STM32高級定時器TIM1產生兩路互補的PWM波(帶死區)

来源:https://www.cnblogs.com/NickQ/archive/2018/03/12/8550901.html
-Advertisement-
Play Games

測試環境:Keil 5.20.0.0 STM32F103RBT6 固件庫版本:STM32F10x_StdPeriph_Lib_V3.5.0(2011) 本文使用TIM1的通道1,通道2,產生兩路1khz,死區時間1us的互補PWM波。 所使用的IO口:由下圖知,我們使用引腳為PA9,PA10,互補輸 ...


測試環境:Keil 5.20.0.0 STM32F103RBT6 固件庫版本:STM32F10x_StdPeriph_Lib_V3.5.0(2011)

本文使用TIM1的通道1,通道2,產生兩路1khz,死區時間1us的互補PWM波。

所使用的IO口:由下圖知,我們使用引腳為PA9,PA10,互補輸出使用PB14,PB15

部分代碼如下:

 1 /* 配置TIM1復用輸出PWM時用到的I/O  */
 2 static void TIM1_GPIO_Config(void) 
 3 {
 4   GPIO_InitTypeDef GPIO_InitStructure;
 5 
 6   /* TIM1 clock enable */
 7   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
 8 
 9   /* GPIOA and GPIOB clock enable */
10   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
11     
12   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10;
13   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
14   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
15 
16   GPIO_Init(GPIOA, &GPIO_InitStructure);
17 
18   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14 | GPIO_Pin_15;
19   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
20   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
21 
22   GPIO_Init(GPIOB, &GPIO_InitStructure);
23 
24 }
初始化IO

 初始化定時器功能配置

 1 u16 CCR2_Val = 500;
 2 u16 CCR3_Val = 500;//占空比,周期為1000
 3 
 4 /*配置TIM1輸出的PWM信號的模式,如周期、極性、占空比 */
 5 void TIM1_Mode_Config(void)
 6 {
 7     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 8     TIM_BDTRInitTypeDef      TIM1_BDTRInitStruct;
 9     TIM_OCInitTypeDef        TIM_OCInitStructure;
10 
11     /* Time base configuration */
12     TIM_TimeBaseStructure.TIM_Period = 1000-1; //計數周期,向上記到此數,計數值清零
13     TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//定時器分頻繫數,Ftimer = 72M/(TIM_Prescaler+1) = 1ms
14     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//與死區時間分頻有關
15     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數模式
16     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
17     
18     /****** 配置BDTR寄存器,配置死區時間****************/
19     /*
20        定時器時鐘 72M   TIM_ClockDivision = TIM_CKD_DIV1時,  Tdts = 13.89ns
21        0 - 1.764us  用演算法一
22        1.778us - 3.505us  用演算法二
23        3.556us - 7.000us  用演算法三 
24        7.1117us - 14us    用演算法四
25        需要更長時間,使用TIM_ClockDivision分頻
26     */
27     TIM1_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Disable;
28     TIM1_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Disable;
29     TIM1_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
30     TIM1_BDTRInitStruct.TIM_DeadTime = 205; //死區時間  72:1us 172:3us 205:5us
31     TIM_BDTRConfig(TIM1,&TIM1_BDTRInitStruct);
32  
33 //    TIM1->BDTR |= 72;   //設置死區  註:上面那種方法也可以,這種快且簡單
34     
35      /* PWM1 Mode configuration: Channel2 */
36      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//PWM2模式
37      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
38      TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//比較互補輸出使能
39      TIM_OCInitStructure.TIM_Pulse = CCR2_Val;   //比較值,即占空比
40      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //輸出極性
41      TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//互補輸出極性
42      TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//指定空閑狀態下的TIM輸出比較的引腳狀態。
43      TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//指定空閑狀態下的TIM互補輸出比較的引腳狀態。
44      TIM_OC2Init(TIM1, &TIM_OCInitStructure);   //初始化通道二比較輸出
45      TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);      //配置通道二,自動重裝載使能
46 
47 
48     /* PWM1 Mode configuration: Channel3 */
49     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
50     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
51     TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
52     TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
53     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
54     TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
55     TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
56     TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;      
57     TIM_OC3Init(TIM1, &TIM_OCInitStructure);
58     TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);    
59 
60     TIM_ARRPreloadConfig(TIM1, ENABLE);//重載裝載值 ENABLE 立即生效,DISABLE 下一個比較周期生效
61 
62     /* TIM1 enable counter */
63     TIM_Cmd(TIM1, ENABLE);//使能定時器1
64     
65     TIM_CtrlPWMOutputs(TIM1, ENABLE);//使能PWM外圍輸出    
66 }

 

 1 int main(void)
 2 {
 3     TIM1_GPIO_Config();
 4     TIM1_Mode_Config();    
 5     while(1)
 6     {
 7          TIM1->CCR2 = CCR2_Val;
 8          TIM1->CCR3 = CCR3_Val;
 9          CCR2_Val+=5;
10          CCR3_Val+=10;
11          if(CCR2_Val>900)  CCR2_Val = 100;
12          if(CCR3_Val>900)  CCR3_Val = 100;   
13          Delay_mS(200);
14     }
15 }
main函數

 

關於死區時間計算:

 先貼幾張關於TIM時鐘的圖:

第一張圖:關於死區時間分頻因數。(代碼見,初始化定時器功能配置代碼部分第14行所示)

第二張圖:死區時間計算

 

       定時器1時鐘掛在APB2匯流排上,時鐘為72M   當TIM_ClockDivision = TIM_CKD_DIV1時,  Tdts = 1/72M = 13.89ns
       0 - 1.764us  用演算法一
       1.778us - 3.505us  用演算法二
       3.556us - 7.000us  用演算法三
       7.1117us - 14us    用演算法四
       需要更長時間,使用TIM_ClockDivision分頻後(可2分,4分頻),設置死區時間。

 

測試數據:

實驗現象:產生了兩路死區時間為1us的互補PWM信號,其頻率都是1kHz,占空比在10% - 90%不斷變化,通道三比通道二變化要快。

死區時間(以通道二為例):(黃:PA10  綠:PB15)

  

通道二抓拍波形  (黃:PA10  綠:PB15)

通道三抓拍波形  (黃:PA9 綠:PB14)

通道二和通道三  (黃:PA9  綠:PA10)

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在寫一個項目的時候需要用到MonogoDB,存儲經緯度坐標的(貌似MongoBD乾這個比較專業),由於沒有玩過MongoBD,就跟著教程來整合這個東西,用的是SpringBoot來整合SpringData和MongoDB,大概是由於版本等原因 教程里是這樣寫的,完全沒毛病。 但是自己寫的時候就出 ...
  • 字典(dictionary) 字典是另一種可變容器模型,且可存儲任意類型對象。 字典的每個鍵值 key= value 對用冒號:分割,每個鍵值對之間用逗號,分割,整個字典包括在花括弧 {} 中 ,格式如下所示: 訪問字典里的值 字典遍歷 第一種方法:key遍歷 第二種方法:元素遍歷 判斷key是否存 ...
  • 序列 序列:數學上,序列是被排成一列的對象(或事件);這樣,每個元素不是在器他元素之前,就是在其他元素之後。這裡元素之間的順序非常重要。《維基百科》 序列是Python中最基本的數據結構。序列中的每個元素都分配一個數字 - 它的位置,或索引,第一個索引是0,第二個索引是1,依此類推。 Python有 ...
  • Description 已知va和vb分別為非遞減有序線性表,將va和vb進行合併為新的線性表vc,並保持vc仍然非遞減有序。 本題中,線性表元素為整數。線性表的最大長度為1000。 Input 輸入數據有多組,第一行為測試數據的組數t,接下來為2t行,每一組測試數據有兩行: 第一行的第一個數為va ...
  • 編寫第一個Java程式 完成工作:1.在文本編輯器中輸入一個Java程式。 2.使用括弧組織程式。 3.保存、編譯和運行程式。 1 package com.Jsample;//將程式的包名稱命名為com.Jsample 2 3 public class Helloworld {//將程式(類)命名為 ...
  • 列表函數 追加和擴展 list.append() 在列表末尾追加新的對象 extend()在列表末尾一次性追加另一個序列中的多個值(用新列表擴展原來的列表) 其他函數 count() 統計某個元素在列表中出現的次數 index() 從列表中找出某個值第一個匹配項的索引位置 insert() 將對象插 ...
  • 1 Celery簡介 Celery是非同步任務隊列,可以獨立於主進程運行,在主進程退出後,也不影響隊列中的任務執行。 任務執行異常退出,重新啟動後,會繼續執行隊列中的其他任務,同時可以緩存停止期間接收的工作任務,這個功能依賴於消息隊列(MQ、Redis)。 1.1 Celery原理 Celery的架構 ...
  • 1、方法的定義格式及解析 (1)方法概述:方法就是完成特定功能的代碼塊。 (2)定義格式: 修飾符 返回值類型 方法名(參數1,參數2,參數3...){ 函數體; return 返回值; } (3)修飾符:公共類public、私有類private、抽象類abstract、最終類final。 (4)返 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...