NUCLEO-F411RE RT-Thread 體驗(yàn) (9) - GCC環(huán)境 PWM的驅(qū)動(dòng)移植以及簡單使用
驅(qū)動(dòng)移植
驅(qū)動(dòng)位于drv_pwm.c文件中,components層代碼位于rt_drv_pwm.c中。
修改Makefile文件
修改配置文件rtconfig.h
LED2鏈接PA5,而TIM2_CHANNEL1可從PA5輸出PWM,所以我們需要配置TIM2,并使能TIM2_CH1.
修改RT-Thread-basic/Core/Src/stm32f4xx_hal_msp.c
HAL_TIM_MspPostInit 函數(shù)在stm32_hw_pwm_init函數(shù)中被調(diào)用。主要配置PA5。
HAL_TIM_PWM_MspInit函數(shù)在HAL_TIM_PWM_Init中被調(diào)用。而HAL_TIM_PWM_Init在stm32_hw_pwm_init中被調(diào)用。
RT-Thread-basic/libraries/HAL_Drivers/config/f4/pwm_config.h
此處channel并不與實(shí)際channel1對(duì)應(yīng),后面會(huì)重新賦值。
編譯后,list_device后會(huì)出現(xiàn)pwm2設(shè)備
使用pwm命令測試
rt_drv_pwm.c中封裝了pwm_set pwm_get pwm_enable pwm_disable
假設(shè)設(shè)置1KHZ 占空比50%的波形,命令如下:
pwm_set pwm2 1 1000000 500000
pwm_enable pwm2 1
period單位為ns,1s = 1000 * 1000 * 1000 ns
1Khz,每個(gè)周期占1/1000 = 1ms,1ms = 1000 * 1000ns,duty cycle 占一半,為500*1000ns。
驅(qū)動(dòng)中如何設(shè)置的呢?
主要是做了個(gè)轉(zhuǎn)換,
1s = 1000 * 1000 * 1000,那么1ms = 1000 * 1000,換成100M的工作頻率即為1ms = 100 * 1000,所以period = (傳過來的periond * timeclock)/ (1000 * 1000 * 1000)。
這個(gè)period可以理解為一個(gè)周期里的計(jì)數(shù)次數(shù),
TIM的AutoReload的最大值也是這個(gè)period,但是在0-65535之間,如果大與65535,則要經(jīng)過perscaler設(shè)置一下分頻。所以這里psc = (period/MaxPperiod) + 1。意思是看看period大于幾倍的65535,就設(shè)置幾倍的分頻。文章來源:http://www.zghlxwxcb.cn/news/detail-496793.html
簡單測試程序
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-25 misonyo first implementation.
*/
/*
* 程序清單:這是一個(gè) PWM 設(shè)備使用例程
* 例程導(dǎo)出了 pwm_led_sample 命令到控制終端
* 命令調(diào)用格式:pwm_led_sample
* 程序功能:通過 PWM 設(shè)備控制 LED 燈的亮度,可以看到LED不停的由暗變到亮,然后又從亮變到暗。
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#define LED_PIN_NUM GET_PIN(A, 5) /* LED PIN腳編號(hào),查看驅(qū)動(dòng)文件drv_gpio.c確定 */
#define PWM_DEV_NAME "pwm2" /* PWM設(shè)備名稱 */
#define PWM_DEV_CHANNEL 1 /* PWM通道 */
struct rt_device_pwm *pwm_dev; /* PWM設(shè)備句柄 */
static int pwm_led_sample(int argc, char *argv[])
{
rt_uint32_t period, pulse, dir;
period = 500000; /* 周期為0.5ms,單位為納秒ns */
dir = 1; /* PWM脈沖寬度值的增減方向 */
pulse = 0; /* PWM脈沖寬度值,單位為納秒ns */
// /* 設(shè)置LED引腳腳模式為輸出 */
// rt_pin_mode(LED_PIN_NUM, PIN_MODE_OUTPUT);
// /* 拉高LED引腳 */
// rt_pin_write(LED_PIN_NUM, PIN_HIGH);
/* 查找設(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;
}
/* 設(shè)置PWM周期和脈沖寬度默認(rèn)值 */
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
/* 使能設(shè)備 */
rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
while (1)
{
rt_thread_mdelay(1000);
if (dir)
{
pulse += 5000; /* 從0值開始每次增加5000ns */
}
else
{
pulse -= 5000; /* 從最大值開始每次減少5000ns */
}
if (pulse >= period)
{
dir = 0;
}
if (0 == pulse)
{
dir = 1;
}
/* 設(shè)置PWM周期和脈沖寬度 */
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
}
}
/* 導(dǎo)出到 msh 命令列表中 */
MSH_CMD_EXPORT(pwm_led_sample, pwm sample);
代碼
代碼下載文章來源地址http://www.zghlxwxcb.cn/news/detail-496793.html
到了這里,關(guān)于NUCLEO-F411RE RT-Thread 體驗(yàn) (9) - GCC環(huán)境 PWM的驅(qū)動(dòng)移植以及簡單使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!