創(chuàng)建工程
這次因?yàn)闆]有新增功能所以新建功能部分我就先略過了,大家可以參考一下上篇文章,其中我修改Kconfig,開啟PWM5 CH1/2/3的部分已經(jīng)提交PR了,各位之后導(dǎo)入工程時(shí)可以先看一下RT-Thread Setting中是否已經(jīng)顯示。
aRGB三原色
aRGB 為一種色彩模式,aRGB 分別代表了 alpha(透明度)、Red(紅色)、Green(綠色)和Blue(藍(lán)色)四個(gè)要素,一般我們給每個(gè)要素設(shè)置十進(jìn)制下 0-255 的取值范圍,通過 16 進(jìn)制表示就是 0x00-0xFF,因此一個(gè) aRGB 值可以通過八位十六進(jìn)制數(shù)來描述,從前到后每?jī)晌灰来螌?duì)應(yīng) a,R,G,B。
在 aRGB 中,alpha 值越大色彩越不透明,RGB 中哪個(gè)值越大,對(duì)應(yīng)的色彩就越強(qiáng)。比如純紅色可以用 8 位 16 進(jìn)制表示為 0xFFFF0000,純綠色可以表示為 0xFF00FF00,純藍(lán)色可以表示為 0xFF0000FF,黃色由藍(lán)色和綠色合成,所以可以表示為 0xFF00FFFF。
程序設(shè)計(jì)
根據(jù)上面的描述我們就可以創(chuàng)建一個(gè)rt_uint32_t類型變量作為我們的aRGB值。之后每八位分別作為我們的alpha(透明度)、Red(紅色)、Green(綠色)和Blue(藍(lán)色)四個(gè)要素。
我這里為了代碼變量的清晰,我定義了一個(gè)aRGB結(jié)構(gòu)體,用于裝載計(jì)算后的aRGB值。大家可以自行嘗試一下。這里三原色的類型為rt_uint16_t的原因之后我們計(jì)算過程中需要給它們乘以alpha因此使用rt_uint8_t會(huì)溢出。
typedef struct
{
rt_uint8_t alpha; /* 透明度 最大值為FF */
rt_uint16_t red;
rt_uint16_t green;
rt_uint16_t blue;
} aRGB;
下面就是計(jì)算函數(shù),這里我們需要把傳進(jìn)來的rt_uint32_t整型進(jìn)行位運(yùn)算,將每八位的值移入給我們的結(jié)構(gòu)體成員內(nèi)。然后用透明度alpha與R、G、B三者依次相乘。后面我們就可以將R、G、B各值作為脈沖寬度。這里R、G、B三個(gè)值計(jì)算出來范圍是0-65536,我們所以我們后面將PWM周期設(shè)置為65536。
static void aRGB_count(aRGB* LED_aRGB, rt_uint32_t set_aRGB)
{
LED_aRGB->alpha = (set_aRGB & 0xFF000000) >> 24;
LED_aRGB->red = ((set_aRGB & 0x00FF0000) >> 16) * LED_aRGB->alpha;
LED_aRGB->green = ((set_aRGB & 0x0000FF00) >> 8) * LED_aRGB->alpha;
LED_aRGB->blue = ((set_aRGB & 0x000000FF) >> 0) * LED_aRGB->alpha;
}
下面就放出完整代碼,這里我是自定義了一個(gè)MSH命令,輸入aRGB_led_sample 0xFF00FF00之類的命令即可設(shè)置aRGB值。
用于MSH命令輸入的參數(shù)都是字符串,所以這里我使用了stroul()函數(shù),這個(gè)函數(shù)可以將字符串轉(zhuǎn)化為無符號(hào)長(zhǎng)整型。
/*
Copyright (c) 2006-2021, RT-Thread Development Team
SPDX-License-Identifier: Apache-2.0
Change Logs:
Date Author Notes
2022-12-31 Goldengrandpa the first version
/
#include
#include
#include "stdlib.h" / 使用其中的函數(shù):strtoul(); /
#define PWM_DEV_NAME "pwm5" / PWM設(shè)備名稱 /
#define PWM_DEV_LEDB_CHANNEL 1 / 藍(lán)燈PWM通道 /
#define PWM_DEV_LEDG_CHANNEL 2 / 綠燈PWM通道 /
#define PWM_DEV_LEDR_CHANNEL 3 / 紅燈PWM通道 */
struct rt_device_pwm pwm_dev; / PWM設(shè)備句柄 /
/ aRGB結(jié)構(gòu)體 /
typedef struct
{
rt_uint8_t alpha; / 透明度 最大值為FF /
rt_uint16_t red;
rt_uint16_t green;
rt_uint16_t blue;
} aRGB;
aRGB LED_aRGB={0,0,0,0};
static void aRGB_count(aRGB LED_aRGB, rt_uint32_t set_aRGB)
{
LED_aRGB->alpha = (set_aRGB & 0xFF000000) >> 24;
LED_aRGB->red = ((set_aRGB & 0x00FF0000) >> 16) * LED_aRGB->alpha;
LED_aRGB->green = ((set_aRGB & 0x0000FF00) >> 8) * LED_aRGB->alpha;
LED_aRGB->blue = ((set_aRGB & 0x000000FF) >> 0) * LED_aRGB->alpha;
}
static int aRGB_led_sample(int argc, char argv[])
{
/ 查找設(shè)備 */
pwm_dev = (struct rt_device_pwm ) rt_device_find(PWM_DEV_NAME);
if (pwm_dev == RT_NULL)
{
rt_kprintf("pwm sample run failed! can't find %s device!n", PWM_DEV_NAME);
return RT_ERROR;
}
rt_uint32_t ui32_aRGB = 0;
/ 用于字符串?dāng)?shù)據(jù)的檢測(cè)與轉(zhuǎn)換 */
rt_kprintf("input para is: %s %sn",argv[0],argv[1]);
if(2!=argc)
{
rt_kprintf("error cmd! please input as: (0x7FFFFFFF) n");
return RT_ERROR;
}
ui32_aRGB=(rt_uint32_t)strtoul(argv[1],NULL,16);/* 將字符串轉(zhuǎn)換為16進(jìn)制數(shù) */
aRGB_count(&LED_aRGB, ui32_aRGB);
rt_uint32_t period=65536;
rt_pwm_set(pwm_dev, PWM_DEV_LEDB_CHANNEL, period, LED_aRGB.blue);
rt_pwm_set(pwm_dev, PWM_DEV_LEDG_CHANNEL, period, LED_aRGB.green);
rt_pwm_set(pwm_dev, PWM_DEV_LEDR_CHANNEL, period, LED_aRGB.red);
rt_pwm_enable(pwm_dev, PWM_DEV_LEDB_CHANNEL);
rt_pwm_enable(pwm_dev, PWM_DEV_LEDG_CHANNEL);
rt_pwm_enable(pwm_dev, PWM_DEV_LEDR_CHANNEL);
}
MSH_CMD_EXPORT(aRGB_led_sample, pwm aRGB sample)
實(shí)驗(yàn)效果如下我們?cè)贛SH控制臺(tái)輸入0xFF00FF00,就會(huì)亮綠燈。如果輸入0x88888888,就會(huì)顯示如下顏色。
PWM教程之蜂鳴器唱歌
蜂鳴器部分主要參考了RT-Thread文檔中心的蜂鳴器播放器,大家有需要的話可以直接去看官方教程,我這里因?yàn)槠驎?huì)有縮減。
蜂鳴器基礎(chǔ)知識(shí)
蜂鳴器是一種能夠通過電子信號(hào)控制的發(fā)聲器件。在生活中,幾乎所有能夠發(fā)出嗶嗶響聲的電子器件中都裝有蜂鳴器。蜂鳴器能夠?yàn)槭褂谜咛峁┲庇^的聲音信息,是一種常見的人機(jī)交互模式。
根據(jù)是否內(nèi)置震蕩電路可分為有源蜂鳴器和無源蜂鳴器。有源蜂鳴器只需要提供直流電壓就可以通過內(nèi)部的震蕩電路產(chǎn)生震蕩電流進(jìn)而發(fā)出聲音,而無源蜂鳴器需要輸入特定頻率的方波才能發(fā)出聲音。兩者比較起來,有源蜂鳴器的控制更加簡(jiǎn)單,但是只能發(fā)出單一頻率的聲音,而無源蜂鳴器雖然控制起來比較麻煩,但是可以通過改變輸入方波的頻率發(fā)出不同音調(diào)的聲音,甚至可以用來演奏樂曲。
這里我們板載的是無源貼片蜂鳴器,這也是我們這個(gè)篇章的先決條件。
程序設(shè)計(jì)
本次我們需要的外設(shè)蜂鳴器,查看原理圖后發(fā)現(xiàn)我們需要的PWM4 CH3已經(jīng)開好了,我們直接去RT-Thread Setting中開啟即可
之后創(chuàng)建beep.c文件,編寫蜂鳴器相關(guān)代碼
/*
Copyright (c) 2006-2021, RT-Thread Development Team
SPDX-License-Identifier: Apache-2.0
Change Logs:
Date Author Notes
2023-01-01 Goldengrandpa the first version
*/
#include "beep.h"
#include //使用 RT-Thread 的設(shè)備需要包含此頭文件
struct rt_device_pwm pwm_device = RT_NULL; //定義 pwm 設(shè)備指針
int beep_init(void)
{
/ 查找PWM設(shè)備 /
pwm_device = (struct rt_device_pwm )rt_device_find(BEEP_PWM_DEVICE);
if (pwm_device == RT_NULL)
{
rt_kprintf("pwm device %s not found!n", BEEP_PWM_DEVICE);
return -RT_ERROR;
}
return 0;
}
int beep_on(void)
{
rt_pwm_enable(pwm_device, BEEP_PWM_CH); //使能蜂鳴器對(duì)應(yīng)的 PWM 通道
return 0;
}
int beep_off(void)
{
rt_pwm_disable(pwm_device, BEEP_PWM_CH); //失能蜂鳴器對(duì)應(yīng)的 PWM 通道
return 0;
}
int beep_set(uint16_t freq, uint8_t volume)
{
rt_uint32_t period, pulse;
/ 將頻率轉(zhuǎn)化為周期 周期單位:ns 頻率單位:HZ /
period = 1000000000 / freq; //unit:ns 1/HZ10^9 = ns
/ 根據(jù)聲音大小計(jì)算占空比 蜂鳴器低電平觸發(fā) /
pulse = period - period / 100 * volume;
/ 利用 PWM API 設(shè)定 周期和占空比 */
rt_pwm_set(pwm_device, BEEP_PWM_CH, period, pulse);//channel,period,pulse
return 0;
}
之后我們后面音符頻率對(duì)周期進(jìn)行設(shè)置,下面程序就實(shí)現(xiàn)了播放音符CDEFGAB的功能。
#include
#include "beep.h"
uint16_t freq_tab[12] = {262, 277, 294, 311, 330, 349, 369, 392, 415, 440, 466, 494}; //原始頻率表 CDEFGAB
uint8_t beep_volume = 3;
int main(void)
{
/* user app entry */
int i;
beep_init();
for (i = 0; i < 12; i++)
{
beep_set(freq_tab[i], beep_volume);
beep_on();
rt_thread_mdelay(500);
beep_off();
rt_thread_mdelay(500);
}
return 0;
}
后面關(guān)于音樂數(shù)據(jù)編碼解碼方面的知識(shí),我自己也是完全是跟著教程的復(fù)刻,所以這里就不進(jìn)行教程的搬運(yùn)了,大家自行跟著官方教程吧。
-
led燈
+關(guān)注
關(guān)注
22文章
1592瀏覽量
107751 -
RGB
+關(guān)注
關(guān)注
4文章
797瀏覽量
58338 -
蜂鳴器
+關(guān)注
關(guān)注
12文章
888瀏覽量
45838 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1261瀏覽量
39840 -
PWM輸出
+關(guān)注
關(guān)注
1文章
66瀏覽量
5113
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論