用CCS分析解讀CC3200 SDK工具包的PWM示例程式
CC3200一共有4組定時器TimerA0-A3,每個定時器有2個子定時器,如TimerA0A、TimerA0B、TimerA1A、TimerA1B等。根據不同的功能需要,可以在引腳配置檔案中選擇不同的模式,如下圖,模式3代表輸出PWM,模式12代表捕獲外部脈衝。
圖源自:CC3200-PWM
PWM示例程式在“example\pwm”目錄中。C3200 GPTA2B、GPTA3B、GPTA3A分別通過PWM05(PIN_64)、PWM06(PIN_01)、PWM07(PIN_02)輸出PWM訊號(佔空比由0到1)控制3個LED的亮度(由滅逐漸到亮)。PWM專案包含主函式檔案、引腳配置程式檔案和CCS啟動程式檔案。
- PWM操作
PWM操作主要是初始化PWM模組InitPWMModules(),主要內容是設定PWM模式SetupTimerPWMMode()。
void InitPWMModules()
{
//
// Initialization of timers to generate PWM output
//
MAP_PRCMPeripheralClkEnable(PRCM_TIMERA2, PRCM_RUN_MODE_CLK);
MAP_PRCMPeripheralClkEnable(PRCM_TIMERA3, PRCM_RUN_MODE_CLK);
//
// TIMERA2 (TIMER B) as RED of RGB light. GPIO 9 --> PWM_5
//
SetupTimerPWMMode(TIMERA2_BASE, TIMER_B,
(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM), 1);
//
// TIMERA3 (TIMER B) as YELLOW of RGB light. GPIO 10 --> PWM_6
//
SetupTimerPWMMode(TIMERA3_BASE, TIMER_A,
(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM), 1);
//
// TIMERA3 (TIMER A) as GREEN of RGB light. GPIO 11 --> PWM_7
//
SetupTimerPWMMode(TIMERA3_BASE, TIMER_B,
(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM), 1);
MAP_TimerEnable(TIMERA2_BASE,TIMER_B);
MAP_TimerEnable(TIMERA3_BASE,TIMER_A);
MAP_TimerEnable(TIMERA3_BASE,TIMER_B);
}
void SetupTimerPWMMode(unsigned long ulBase, unsigned long ulTimer,
unsigned long ulConfig, unsigned char ucInvert)
{
//
// Set GPT - Configured Timer in PWM mode.
//
MAP_TimerConfigure(ulBase,ulConfig);
MAP_TimerPrescaleSet(ulBase,ulTimer,0);
//
// Inverting the timer output if required
//
MAP_TimerControlLevel(ulBase,ulTimer,ucInvert);
//
// Load value set to ~0.5 ms time period
//
MAP_TimerLoadSet(ulBase,ulTimer,TIMER_INTERVAL_RELOAD);
//
// Match value set so as to output level 0
//
MAP_TimerMatchSet(ulBase,ulTimer,TIMER_INTERVAL_RELOAD);
}
SetupTimerPWMMode()主要包括下列內容。
- 配置定時器:TimerConfigure()
- 設定預分頻:TimerPrescaleSet()
- 控制輸出電平:TimerControlLevel()
- 設定定時器初值:TimerLoadSet()
- 設定定時器匹配:TimerMatchSet()
(1)配置定時器
void TimerConfigure(unsigned long ulBase, unsigned long ulConfig);
引數說明:
-
ulBase:定時器基地址,TimerA2和TimerA3的基地址分別是0x4003 2000和0x4003 3000,在hw_memmap.h中定義。
-
ulConfig:定時器配置,主要包括下列值。
1.TIMER_CFG_SPLIT_PAIR:雙16位定時器
2.TIMER_CFG_A_PWM:子定時器A PWM輸出
3.TIMER_CFG_B_PWM:子定時器B PWM輸出
TimerA2的設定值是1和3,因為此程式涉及到了TimerA2B。
TimerA3的設定值是1、2和3,因為此程式涉及到了TimerA3A、TimerA3B。
當需要同時配置一個定時器組中的兩個pwm輸出的時候,模式設定函式中要2和3進行或運算,如下所示。不能單獨配置,否則前一個配置模式會被後面的配置給覆蓋掉。注意:Timer專案和PWM專案中TimerConfigure()的主要區別是配置值的不同,Timer專案中配置值是TIMER_CFG_PERIODIC(32位週期定期器)。
(2)設定預分頻
void TimerPrescaleSet(unsigned long ulBase, unsigned long ulTimer,unsigned long ulValue)
引數說明:
- ulBase:定時器基地址。
- ulTimer:子定時器選擇,TimerA2的設定值是TIMER_B,TimerA3的設定值是TIMER_A和TIMER_B。
- ulValue:預分頻值,設定值都是0,即不分頻。
(3)控制輸出電平
void TimerControlLevel(unsigned long ulBase, unsigned long ulTimer,tBoolean bInvert)
引數說明:
- ulBase:定時器基地址。
- ulTimer:子定時器選擇。
- bInvert:定時器輸出電平,true表示低電平,false表示高電平。此示例程式都設定為1,也就是PWM模式下輸出的有效電平為低電平,對應的LED的熄滅狀態。
(4)設定定時器初值
void TimerLoadSet(unsigned long ulBase, unsigned long ulTimer,unsigned long ulValue)
引數說明:
- ulBase:定時器基地址。
- ulTimer:子定時器選擇。
- ulValue:定時器初值。此示例程式設定的是40035.
MAP_TimerLoadSet(ulBase,ulTimer,TIMER_INTERVAL_RELOAD);
.....
#define TIMER_INTERVAL_RELOAD 40035 /* =(255*157) */
(5)設定定時器匹配值
void TimerMatchSet(unsigned long ulBase, unsigned long ulTimer,unsigned long ulValue)
引數說明:
- ulBase:定時器基地址。
- ulTimer:子定時器選擇。
- ulValue:定時器初值。
(6)允許定時器
void TimerEnable(unsigned long ulBase, unsigned long ulTimer)
(7)更新PWM佔空比
void UpdateDutyCycle(unsigned long ulBase, unsigned long ulTimer,
unsigned char ucLevel)
{
//
// Match value is updated to reflect the new dutycycle settings
//
MAP_TimerMatchSet(ulBase,ulTimer,(ucLevel*DUTYCYCLE_GRANULARITY));
}
...
#define DUTYCYCLE_GRANULARITY 157
- 佔空比的計算
系統的時鐘是80MHz的,首先確定PWM的週期,比如說0.5ms,據此確定定時器裝載的初始值。(0.5*10的-3次方)/(1/80M) = 40000,也就是說定時器從40000向下計數就是0.5ms。
從上圖看出,定時器的初值為0xC350,然後比較值為0x411A,PWM輸出的原理是定時器向下計數,當定時器的值大於比較值時輸出有效電平,小於比較值時輸出另一電平。而有效電平的設定是在控制輸出電平TimerControlLevel()中的bInvert引數設定的,此示例程式都設定為1,也就是PWM模式下輸出的有效電平為低電平,對應的LED的熄滅狀態。
然後我們要考慮佔空比可調,我們需要考慮LED亮度一共有多少等級可以調節。示例中設定的是0-254一共255個等級,那每個等級之間的步長就是40000/255約等於157,不能除盡。所以我們調節定時器的初值為255*157=40035(週期0.5004735ms),這樣就可以達到255等級,每個等級步長均為157。
下圖是主函式迴圈函式,主要是改變iLoopCnt以此來改變LED燈亮度等級,從0開始往上遞增。
while(1)
{
//
// RYB - Update the duty cycle of the corresponding timers.
// This changes the brightness of the LEDs appropriately.
// The timers used are as per LP schematics.
//
for(iLoopCnt = 0; iLoopCnt < 255; iLoopCnt++)
{
UpdateDutyCycle(TIMERA2_BASE, TIMER_B, iLoopCnt);
UpdateDutyCycle(TIMERA3_BASE, TIMER_B, iLoopCnt);
UpdateDutyCycle(TIMERA3_BASE, TIMER_A, iLoopCnt);
MAP_UtilsDelay(800000);
}
}
以下為具體的佔空比更新函式,引用了TimerMatchSet函式改變匹配值,也就是匹配值。我們可以看到匹配值從等級0,慢慢增加,對應的就是比較值0、157、314…所以我們可以推出在前面一段時間,整個週期低電平是佔了一大半時間的,對應的就是LED處於熄滅狀態。當比較值慢慢增加,有效電平即低電平所佔的時間慢慢減少,高電平所佔的時間慢慢增加,也就是LED點亮的時間慢慢增加,從視覺上來說,就是LED變亮了。
void UpdateDutyCycle(unsigned long ulBase, unsigned long ulTimer,
unsigned char ucLevel)
{
//
// Match value is updated to reflect the new dutycycle settings
//
MAP_TimerMatchSet(ulBase,ulTimer,(ucLevel*DUTYCYCLE_GRANULARITY));
}
- 函式引用關係整理
綠色框圖代表的是SDK工具包提供的庫函式,這是已經封裝好的函式,只要匯入標頭檔案和相關驅動檔案就可以直接引用。藍色函式是新定義的函式。
參考文獻:《ARM Cortex-M4+Wi-Fi MCU應用指南-CC3200 CCS基礎篇》郭書軍編著 電子工業出版社
相關文章
- 用CCS分析解讀CC3200 SDK工具包的UART示例程式
- 史上最詳細ConvLstm的pytorch程式碼解讀分析PyTorch
- Halcon斑點分析官方示例講解
- CCS 2022 | 以太坊改進提案1559實證分析
- PWM
- PHP8 新特性解讀和示例PHP
- Android HAL 層框架分析以及程式碼示例Android框架
- PWM同步
- Lift, Splat, Shoot, LSS程式碼詳盡分析與解讀
- NPOI讀取示例
- 詳解javascript拖拽(二)拖拽的應用及示例JavaScript
- SpringBoot @ConditionalOnBean、@ConditionalOnMissingBean註解原始碼分析與示例Spring BootBean原始碼
- 示例解讀 Python 2 和 Python 3 之間的主要差異Python
- 解讀Linux程式Linux
- Java讀取properties配置檔案工具包Java
- 採用libpq連結lightdb示例程式
- 【Azure Developer】使用 Python SDK連線Azure Storage Account, 計算Blob大小程式碼示例DeveloperPython
- Sentry-JS-SDK-Browser 官方示例最佳實踐JS
- werkzeug原始碼分析——從官網的示例程式碼開始原始碼
- Python中檔案讀取與儲存程式碼示例Python
- MySQL資料分析儲存引擎示例講解HKEAMySql儲存引擎
- 收藏篇:低功耗模組軟體的PWM應用例項
- kafka程式碼解讀Kafka
- ASP.NET 微軟Web應用示例程式走廊-專案解決方案ASP.NET微軟Web
- 影片聊天原始碼,同步、非同步示例程式碼分析原始碼非同步
- 淺談JavaScript程式碼預解析 + 示例詳解JavaScript
- Spring 註解學習 詳細程式碼示例Spring
- 併發程式設計ConcurrentLinkedQueue使用示例詳解程式設計
- GBase XDM 資料庫ldapdelete命令講解和示例分析資料庫LDAdelete
- 遺傳演算法庫DEAP的示例程式碼的學習和分析演算法
- 報告解讀分享會報名開啟:2022愛分析·人工智慧應用實踐報告解讀人工智慧
- bootstrap-select 的多選+模糊查詢下拉框詳解(官方示例文件解讀)boot
- 美顏SDK詳解,您瞭解美顏SDK嗎?
- 零程式碼的多方面解讀
- 接入 SDK 結果翻車了?瞭解 SDK 的那些事
- Laravel核心解讀–Cookie原始碼分析LaravelCookie原始碼
- 從解讀 BDC 自動生成的程式碼談起,講解 SAPGUI 的程式組成部分試讀版GUI
- 資料分析之杜邦分析法的公式及示例公式