【星閃】Hi2821 | PWM脈寬調制模塊 + 呼吸燈例程

1. 簡介

????????PWM(Pulse Width Modulation),全稱脈寬調制,通過對一系列脈沖的寬度進行調制,等效出所需波形。即對模擬信號電平進行數字編碼,通過調節頻率、占空比的變化來調節信號的變化。

? ? ? ? 一個 PWM 周期內由一段高電平和一段低電平區間組成,通過調整高低電平的時間,即占空比,可以等效輸出不同的電壓。

????????比如,周期為 100ms,高電平時間為 50ms,低電平時間為 50ms,即占空比為 50%,VCC 假設為 5V,那么等效輸出的電壓為 1.15V。

2. 硬件特性

? ? ? ? Hi2821 一共有 12 路 PWM 輸出通道;支持PWM分組,一個組可以分配多個通道,同一個通道不能同時位于不同的組里。

3. 例程

3.1 Kconfig

? ? ? ? SDK 是默認打開 PWM 的編譯的,配置項不多,基本上也不需要配置。唯一可能要配置的是最后一個“Using PWM PRELOAD”,它的作用是可以預配置一系列占空比,這樣 PWM 輸出完一個周期后,驅動會自動加載下一個周期的配置。

3.2 代碼

#include "soc_osal.h"
#include "app_init.h"
#include "pwm.h"
#include "hal_pwm.h"
#include "pinctrl.h"#include <string.h>
#include <stdint.h>#define PWM_GROUP_ID 0static uint8_t pwm_chn = 0;
static pwm_config_t pwm_cfg = {1000,0,0,100,false
};static errcode_t pwm_callback(uint8_t channel)
{static uint8_t dir = 0;if (dir) {pwm_cfg.low_time++;pwm_cfg.high_time--;} else {pwm_cfg.low_time--;pwm_cfg.high_time++;}/* 更新占空比 */hal_pwm_funcs_t *func = hal_pwm_get_funcs();func->set_time(PWM_SET_LOW_TIME, (pwm_channel_t)channel, pwm_cfg.low_time);func->set_time(PWM_SET_HIGH_TIME, (pwm_channel_t)channel, pwm_cfg.high_time);func->set_action(PWM_GROUP_ID, PWM_ACTION_START);osal_printk("duty cycle, high: %u, low: %u\r\n", pwm_cfg.high_time, pwm_cfg.low_time);if (pwm_cfg.low_time == 0) {dir = 1;} else if (pwm_cfg.low_time == 1000) {dir = 0;}return 0;
}void app_main(void *unused)
{(void)(unused);int ret = 0;/* 初始化管腳 */uapi_pin_set_mode(31, HAL_PIO_PWM0);/* 初始化PWM */uapi_pwm_deinit();uapi_pwm_init();ret = uapi_pwm_open(pwm_chn, &pwm_cfg);if (ret) {osal_printk("PWM init failed, err: %X");return;}uapi_pwm_register_interrupt(pwm_chn, pwm_callback);osal_printk("\r\nPWM freq: %d Hz\r\n", uapi_pwm_get_frequency(pwm_chn));uapi_pwm_set_group(PWM_GROUP_ID, &pwm_chn, 1);uapi_pwm_start_group(PWM_GROUP_ID);
}

1. 初始化管腳

? ? ? ? 我使用的是開發板上自帶的 LED 燈,對應 31 號管腳,只需要調用?uapi_pin_set_mode 函數配置復用到對應的 PWM 通道即可。

2. 初始化 PWM

? ? ? ? 先調用?uapi_pwm_init 初始化驅動;接著調用?uapi_pwm_open 配置通道運行參數,參數一為通道號,參數二為運行參數,定義如下:

typedef struct pwm_config {uint32_t low_time;               /*!< @if Eng PWM working clock cycle count low level part,PWM work frequency @ref uapi_pwm_get_frequency().If the PWM operating cycle is Tus,the actual low-level time = low_time * Tus.@else   PWM工作時鐘周期計數個數低電平部分,頻率參考 @ref uapi_pwm_get_frequency()。如果PWM工作周期為Tus, 實際低電平時間 = low_time * Tus @endif */uint32_t high_time;              /*!< @if Eng PWM working clock cycle count high level part,PWM work frequency @ref uapi_pwm_get_frequency().If the PWM operating cycle is Tus,the actual high-level time = high_time * Tus.@else   PWM工作時鐘周期計數個數高電平部分,頻率參考 @ref uapi_pwm_get_frequency()。如果PWM工作周期為Tus, 實際高電平時間 = high_time * Tus @endif */uint32_t offset_time;            /*!< @if Eng PWM offset time.@else   PWM相位。  @endif */uint16_t cycles;                 /*!< @if Eng PWM cycles, range:0~32767 (15bit).@else   PWM重復周期,范圍:0~32767 (15bit)。  @endif */bool repeat;                     /*!< @if Eng Flag to indicate PWM should output continuously.@else   指示PWM應連續輸出的標志。  @endif */
} pwm_config_t;
  • low_time:低電平時間;
  • high_time:高電平時間;
  • offset_time:相位偏移;
  • cycles:重復周期;
  • repeat:是否連續周期。

? ? ? ? PWM 的時鐘默認是 32MHz,也可以調?uapi_pwm_get_frequency 去獲取。low_time 和 high_time 的值是 PWM 時鐘的周期數,那么可以得出一個 PWM 周期的時間為:(low\_time+high\_time)\times \frac{1}{32000000}

? ? ? ? cycles 和 repeat 是互斥的,如果設置了 repeat,那么驅動會忽略 cycles 的值。

? ? ? ? 然后調用?uapi_pwm_register_interrupt?注冊中斷回調,當 PWM 完成了一個輸出任務時,這個回調就會調用。

如果設置了 repeat 這個中斷就永遠不會調用,因為輸出的任務永遠不會結束。

另外,中斷回調注冊一定要放在?uapi_pwm_open 之前,因為后者會使用驅動默認的中斷回調去覆蓋回調函數。

? ? ? ? 調用?uapi_pwm_set_group 設置 PWM 組,最多可設置?6 個組;參數一為組號,參數二為通道號列表,參數三為通道數。最后調用?uapi_pwm_start_group 去使能對應組的輸出任務。

3. 中斷回調函數

? ? ? ? 在中斷回調函數里面去調整占空比,目前的 SDK 比較 low,還沒有移植調整占空比的函數,所以只能調用 HAL 層的函數接口去調整。

? ? ? ? 調用?hal_pwm_get_funcs 函數可以獲取 PWM 底層的操作函數,調用 set_time 函數可以調整 low_time 和 high_time 的值,調整完成后需要調用 set_action 去使能 PWM 輸出任務,參數一為組號,參數二填?PWM_ACTION_START。

3.3 測試

? ? ? ? 編譯并燒錄固件,此時就能看到呼吸燈的效果了,下面為部分系統 log。

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

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

相關文章

51單片機---硬件學習(電子琴、主從應答模式、modbus模型、DS18B20傳感器顯示溫度)

一、串行通信與并行通信1、串行通信定義&#xff1a;數據一位一位地按順序通過單條傳輸線進行傳輸的通信方式。優點&#xff1a;傳輸線少&#xff0c;成本低&#xff0c;適合長距離傳輸缺點&#xff1a;傳輸速度相對較慢2、并行通信定義&#xff1a;數據的各位同時通過多條并行…

SpringBoot后端開發常用工具詳細介紹——SpringSecurity認證用戶保證安全

簡單的開始 創建SpringBoot項目 首先創建一個簡單的springboot項目&#xff0c;假設端口為8888&#xff0c;添加controller控制層&#xff0c;并在其中添加TestController控制類&#xff0c;那么啟動springboot項目之后&#xff0c;訪localhost:8888/api/message頁面會顯示my…

別再手工縫合API了!開源LLMOps神器LMForge,讓你像搭積木一樣玩轉AI智能體!

你是否受夠了這些&#xff1f; 剛調通OpenAI的API&#xff0c;老板說“咱們試試國產模型降本增效”&#xff0c;你看著滿屏的if-else只想說“我暈”。想給AI加上“查天氣”、“執行代碼”的能力&#xff0c;卻發現Function Calling的代碼復雜得讓人頭皮發麻。本地的Agentdemo驚…

window使用ffmep工具,加自定義腳本執行視頻轉碼成h264(運營人員使用)

技術文章大綱&#xff1a;ffmep配合腳本使用1. 需要提供腳本給視頻轉碼的給運營,給運營上傳視頻使用安裝ffmep windows版本(目前我使用的就是windows)將腳本里面的執行路徑修改成自己的電腦安裝ffmep/bin/ffmep.exe路徑處理好之后就點擊執行2.環境準備ffmep windows版解壓到一個…

Leetcode 240. 搜索二維矩陣 II 矩陣 / 二分

原題鏈接&#xff1a; Leetcode 240. 搜索二維矩陣 II 解法一&#xff1a;排除法 參考 【圖解】排除法&#xff0c;一圖秒懂&#xff01;&#xff08;Python/Java/C/C/Go/JS/Rust&#xff09; 從右上角&#xff1a; class Solution { public:bool searchMatrix(vector<vec…

OCR 證件識別:驅動澳門酒店自助入住智能化

澳門酒店作為國際旅游窗口&#xff0c;每日接待持多元證件的旅客&#xff0c;OCR 證件識別技術的應用&#xff0c;讓自助入住終端實現 “一證通辦”&#xff0c;大幅提升服務效率。?旅客在自助終端辦理入住時&#xff0c;只需將護照、港澳通行證、回鄉證、電子身份證等證件貼近…

深入解析匯編語言的奧秘

匯編語言簡介匯編語言&#xff08;Assembly Language&#xff09;是一種低級編程語言&#xff0c;直接對應計算機的機器指令集。它通過助記符&#xff08;如 MOV、ADD&#xff09;代替二進制操作碼&#xff0c;更接近硬件架構&#xff0c;常用于性能優化、嵌入式開發或逆向工程…

Nextcloud 實戰:打造屬于你的私有云與在線協作平臺

隨著數據安全與隱私保護意識的提升&#xff0c;越來越多的個人和組織選擇自建云平臺來替代公有云。Nextcloud 作為一款開源的文件同步與協作套件&#xff0c;不僅能實現類似網盤的文件存儲與分享&#xff0c;還提供日歷、聯系人、即時通訊、在線文檔編輯等協作功能&#xff0c;…

實踐指南:利用衡石AI Data Agent實現自然語言驅動的指標開發與歸因

在數字化轉型的深水區&#xff0c;企業數據團隊常面臨兩難困境&#xff1a;業務部門需要敏捷響應的指標分析&#xff0c;但傳統BI工具依賴技術團隊編寫SQL&#xff0c;導致需求交付周期長達數周&#xff1b;而直接暴露底層數據又存在安全與合規風險。衡石科技推出的AI Data Age…

知微集:Python中的線程(三)

歡迎來到"一起學點什么吧"的合集「NLP知微集」。在這里&#xff0c;我們不愿宏大敘事&#xff0c;只聚焦于自然語言處理領域中那些細微卻關鍵的“齒輪”與“螺絲釘”。我相信&#xff0c;真正深刻的理解&#xff0c;源于對細節的洞察。本期&#xff0c;我將為您拆解的…

動態規劃入門:從記憶化搜索到動態規劃

在開始對動態規劃的講解之前&#xff0c;我們需要先對記憶化搜索進行回顧&#xff1a; 什么是記憶化搜索&#xff1f; 在搜索過程中&#xff0c;當搜索樹中存在大量重復的節點時&#xff0c;我們可以通過引入一個"備忘錄"&#xff08;通常是一個數組或哈希表&#…

Boost搜索引擎 網絡庫與前端(4)

文章目錄前言一、引入網絡庫模塊引入cpp-httplibcpp-httplib測試正式編寫http_server二、前端模塊三、項目的可能拓展總結前言 終于到了最后一篇嘍&#xff0c;嘻嘻&#xff01; 一、引入網絡庫模塊 引入cpp-httplib 下載地址如下&#xff0c;我個人不喜歡新版本 ??cpp-http…

Flink反壓問題

背景在使用flink的過程中&#xff0c;多次遇到過反壓&#xff08;backpressure&#xff09;的問題&#xff0c;這通常是因為數據處理的速率超過了數據源或下游系統的處理能力導致。反壓的底層剖析網絡流控一個重要的概念是網絡流控&#xff0c;如上圖&#xff0c;不同的Consume…

Day5-中間件與請求處理

昨天搞定了異步優化&#xff0c;今天來解決一些實際問題。Day4的API雖然性能不錯&#xff0c;但還缺少一些企業級應用必備的功能。 現在的問題 前端無法訪問API&#xff08;跨域問題&#xff09;沒有請求日志&#xff0c;出問題難以排查錯誤信息格式不統一缺少統一的請求處理機…

【LeetCode熱題100道筆記】反轉鏈表

題目描述 給你單鏈表的頭節點 head &#xff0c;請你反轉鏈表&#xff0c;并返回反轉后的鏈表。 示例 1&#xff1a;輸入&#xff1a;head [1,2,3,4,5] 輸出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a;輸入&#xff1a;head [1,2] 輸出&#xff1a;[2,1] 示例 3&#xff1a;…

Oracle:select top 5

在Oracle數據庫中實現SELECT TOP 5功能需采用特定語法&#xff0c;因其原生不支持TOP關鍵字。以下是兩種主流實現方式&#xff1a;?ROWNUM結合子查詢?先通過子查詢排序數據&#xff0c;再在外層用ROWNUM限制行數&#xff1a;SELECT * FROM ( SELECT * FROM 表名 ORDER BY 排序…

Kubernetes(k8s) 增量更新 po

文章目錄前言k8s 增量更新 po1. 導出要新建po 的控制器配置2. 配置詳解3. 重新生效前言 如果您覺得有用的話&#xff0c;記得給博主點個贊&#xff0c;評論&#xff0c;收藏一鍵三連啊&#xff0c;寫作不易啊^ _ ^。 ??而且聽說點贊的人每天的運氣都不會太差&#xff0c;實在…

基于stm32的車輛安全駕駛預警系統

若該文為原創文章&#xff0c;轉載請注明原文出處。一、 項目背景與引言(一) 研究背景及意義道路交通安全是全球性的重大公共安全問題。據統計&#xff0c;絕大多數交通事故源于駕駛員的危險狀態&#xff08;疲勞、分心、健康突發狀況&#xff09;和危險駕駛行為&#xff08;超…

React學習教程,從入門到精通, React 新創建組件語法知識點及案例代碼(11)

React 新創建組件語法知識點及案例代碼 React 是由 Facebook 開發的一個用于構建用戶界面的 JavaScript 庫。隨著 React 的不斷發展&#xff0c;創建組件的方式也在不斷演進。本文將詳細介紹 React 中創建組件的最新語法&#xff0c;包括函數組件&#xff08;Functional Compo…

SQL Server全鏈路安全防護

SQL Server 的安全性是一個多層次、綜合性的體系&#xff0c;旨在保護數據免受未授權訪問、篡改和泄露。其核心安全機制可概括為以下幾個方面&#xff1a;1. 身份驗證&#xff08;Authentication&#xff09; Windows 身份驗證&#xff1a; 使用 Windows 賬戶&#xff08;域/本…