1、前情提要
网上关于RT_Thread输出pwm波的教程很多,但是绝大多数都是使用rt_thread borad.h中开启pwm的注释教程步骤来的,我会遇到pwmX_config的报错,x是你pwm所在的timer,比如1,2,3,4,5.......,而且就算我手动补全最后也不能输出pwm波形。
最后我只好想着用HAL去强行开启,真别说还找到一个哥们出的教程,但是很遗憾,我还是不能出波形。在这里附上这个老哥链接,如果我这个教程不行,你还可以参考他的:基于RT-Thread(RTT)的HAL库PWM波输出(解决PWM周期跳变问题)_rtt pwm使用-CSDN博客
2、具体步骤
我先说明一下我stm32包的版本,感觉很多人不提一下自己包的版本,我跟着教程到后面,给我蹦出来几百个报错,直接心态蹦了。我stm32包是0.2.2版本的
1.新建工程
比较重要的地方:第一个是,RT_thread版本选择4.0.3,然后其他的根据你自己板子去选
2.打开cubemx
这个需要你提前下载cubemx,然后点击工程的CubeMX Settings
然后会弹出来一个框框,点击Browse
因为我经常用,他会直接到我上次选择cubemx的文件夹,如果是你就去找你下载的cubemx的exe文件所在的文件夹,我是直接放桌面了
点击这个cubemx图标,然后点击右下角打开。然后cubemx软件就会自动打开了。
3.cubemx设置
因为我后面打算直接把cubemx的文件夹删掉,所以uart1通信串口就不设置了。
1.设置时钟
因为我的板子是只有高速晶振的,所以我只设置了高速晶振。
然后去设置时钟树
因为我晶振是8MHZ的,所以就设置了8,这个按照你自己板子来。然后我画圈的地方是大家一样的操作,其他数值按照你自己的想法来
2.设置TIM
因为我板子哪个PIN脚对应的是TIM14的CH1,所以我直接设置TIM14
TIM设置如下图所示,我改了分频系数,Counter Period,Pulse,具体什么意思请看其他教程,我这个教程只负责出波形,如果是要你想要的波形,就改这些参数。
3.生成代码
点击Project Manager,修改的地方我会标出
最后点击GENERATE CODE。然后重要的事情说三遍,一定要关掉cubemx,关掉cubemx,关掉cube
RT_thread操作
关掉CUBEMX,RT_Thread会弹出一个框
这个不用管,现在把cubemx文件夹里面的,tim.h和tim.c放在applications文件夹下,
当然你在目录文件找不到tim.c
但是其实是存在这个文件的,就在src里面,我们首先打开tim.h找到MX_TIM14_Init,当然你不一定是14,看你是哪个tim。
右键点击打开声明,然后就会出现tim.c了。
然后鼠标右键点击tim.c,把这个文件复制粘贴在applications的工程目录下。我再次强调一下,不要在非目录结构下进行文件粘贴,直接用我的文件夹界面进行粘贴是不可以的,可能会有bug,比如直接在这个工程的文件夹下进行复制粘贴。一定要在rt——studio的项目资源管理器下粘贴。
然后修改tim.h的头文件,把main.h注释掉,加上#include <drv_common.h>
然后修改stm32f4xx_hal_conf_bak.h
把我标的地方取消注释。
然后把cubemx中的main.c中的SystemClock_Config函数,复制粘贴到drv_clk.c,把原来的system_clock_config删掉再把SystemClock_Config名字换成system_clock_config,再把clk_init函数改掉,如下图所示
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-10-26 ChenYong first version
* 2020-01-08 xiangxistu add HSI configuration
*/
#include <board.h>
#include <rtthread.h>
#include <stm32f4xx.h>
#include "drv_common.h"
#define DBG_TAG "board"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
void system_clock_config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
int clock_information(void)
{
LOG_D("System Clock information");
LOG_D("SYSCLK_Frequency = %d", HAL_RCC_GetSysClockFreq());
LOG_D("HCLK_Frequency = %d", HAL_RCC_GetHCLKFreq());
LOG_D("PCLK1_Frequency = %d", HAL_RCC_GetPCLK1Freq());
LOG_D("PCLK2_Frequency = %d", HAL_RCC_GetPCLK2Freq());
return RT_EOK;
}
INIT_BOARD_EXPORT(clock_information);
void clk_init(char *clk_source, int source_freq, int target_freq)
{
/*
* Use SystemClock_Config generated from STM32CubeMX for clock init
* system_clock_config(target_freq);
*/
system_clock_config();
}
然后,现在把工程下的cubemx文件夹删掉,再然后把driver文件夹下的stm32f4xx_hal_conf.h文件重命名成stm32f4xx_hal.h
3.修改main函数,进行波形输出
头文件加上tim.h和drv_common.h
首先进行tim初始化,然后使用HAL_TIM_PWM_Start函数开启pwm波形输出
#include <rtthread.h>
#include <drv_common.h>
#include "tim.h"
#include <rtdbg.h>
#include <board.h>
#include <rtdevice.h>
int main(void)
{
MX_TIM14_Init();
HAL_TIM_PWM_Start(&htim14,TIM_CHANNEL_1);
while(1){
rt_thread_mdelay(100);
}
return RT_EOK;
}
现在进行编译
ok,现在下到板子里面
完结撒花