前言
之前一直在Linux下面尝试进行部署了RT-Thread的stm32的开发,这种方式确实是可行的,但是也会带来种种不便之处。使用VSCode + Scons + openocd 进行编辑、编译链接、烧录确实是可以进行开发,但是若要进行调试则没有这种环境的解决方案,只得在eclipse中进行调试。而将RT-Thread改成eclipse的方案虽然可行,但是这样还不如直接在windows下面采用keil 5 来进行开发。
由于stm32f103板载flash过小,栈也十分的小,于是换成stm32f411。板子来自于微雪科技的XNUCLEO,和STM官方NUCLEO板子是兼容的。
安装Keil 5.23
由于我首先安装了Keil 5.11,然后附带的破解器破解了,之后卸载再安装了Keil 5.23,直接显示已经破解成功。破解器仍然是多年前就流行的注册码生成器。之所以使用Keil 5.23版本,是因为RT-Thread工程只能使用这个版本进行打开。
使用pack installer安装库
只有安装了Keil::STM32F4xx_DFP才能打开RT-Thread的bps分支下的nucleo工程。
安装STM32CubeMX
通过STM32CubeMX,我们可以方便的通过鼠标点击生成初始化代码。但是调用函数还是得我们自己写,不如NPX的PE方便。
安装ST-Link驱动
微雪科技售卖100块钱的板子还附带了ST-Link调试器,那我们就是用ST-Link来进行调试吧。
下载nucleo工程
打开rt-thread-master\bsp\stm32f411-nucleo
下的Keil 5工程,尝试编译,通过后,简单设置工程的debug,使用ST-Link来进行调试,然后将程序下载到板子里面。虽然程序下进去了,但是没有任何效果,因为主函数是空的。
我们在main函数中加入如下代码:
int main(void)
{
/* user app entry */
MX_GPIO_Init();
while(1){
rt_thread_delay(5);
HAL_GPIO_WritePin (GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
rt_thread_delay(5);
HAL_GPIO_WritePin (GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
}
}
并加上LED的初始化函数
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
/*Configure GPIO pin : PC5 */
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
这样我们就可以看到板载的LED4灯亮起来了,并且在闪烁。
这些初始化代码是从哪来的呢?主函数中的代码,是从网上找的,很简单的操作GPIO的函数,而MX_GPIO_Init这段代码,则来自于STM32CubeMX自动生成的代码。下面会讲如何通过STM32CubeMX生成初始化UART代码。
使用STM32CubeMX生成UART初始化代码
- 首先我们建立一个工程,并设置好芯片型号,下面是演示
- 然后设置串口引脚。
由于RT-Thread已经初始化了串口1,我以我们不能使用这个。我们可以使用UART6。
- 打开工程,将代码偷走,蓝色部分就是我们要拿走的代码
- 移植代码
在void HAL_UART_MspInit(UART_HandleTypeDef *huart)中,添加USART6的代码:
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
if (huart->Instance == USART2)
{
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
USARTx_TX_GPIO_CLK_ENABLE();
USARTx_RX_GPIO_CLK_ENABLE();
/* Enable USARTx clock */
USARTx_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
/* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Alternate = USARTx_RX_AF;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
HAL_NVIC_SetPriority(USART2_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
if (huart->Instance == USART6)
{
/* USER CODE BEGIN USART6_MspInit 0 */
/* USER CODE END USART6_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART6_CLK_ENABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PC7 ------> USART6_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(USART6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART6_IRQn);
/* USER CODE BEGIN USART6_MspInit 1 */
/* USER CODE END USART6_MspInit 1 */
}
}
在main.c文件中,添加MX_USART6_UART_Init();
函数内容,并在主函数中,调用MX_USART6_UART_Init();
进行初始化。
之后,在main()函数中进行测试:
uint8_t TxData[10]= "01234abcde";
HAL_UART_Transmit(&huart6,TxData,10,0xf);
我们将微雪的板子上的JP4跳帽接在右侧,这样,USB TO UART就能使用PC6、PC7作为串口接口了。然后,接上USB接口到PC机,我们可以在XSHELL之类的串口终端查看PC接受到的字符串。