前言
之前一直在Linux下面嘗試進行部署了RT-Thread的stm32的開發(fā),這種方式確實是可行的,但是也會帶來種種不便之處。使用VSCode + Scons + openocd 進行編輯、編譯鏈接、燒錄確實是可以進行開發(fā),但是若要進行調試則沒有這種環(huán)境的解決方案,只得在eclipse中進行調試。而將RT-Thread改成eclipse的方案雖然可行,但是這樣還不如直接在windows下面采用keil 5 來進行開發(fā)。
由于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接受到的字符串。