概述
本文利用中斷實(shí)現(xiàn)串口不定長(zhǎng)接收(非DMA),使用HAL庫(kù),將接收的數(shù)據(jù)打印出去。
DMA接收請(qǐng)查看:https://blog.csdn.net/qq_24312945/article/details/106557538
硬件準(zhǔn)備
首先需要準(zhǔn)備一個(gè)開(kāi)發(fā)板,這里我準(zhǔn)備的是NUCLEO-F030R8的開(kāi)發(fā)板:
選擇芯片型號(hào)
使用STM32CUBEMX選擇芯片stm32f030r8,如下所示:
配置時(shí)鐘源
HSE與LSE分別為外部高速時(shí)鐘和低速時(shí)鐘,在本文中使用內(nèi)置的時(shí)鐘源,故都選擇Disable選項(xiàng),如下所示:
配置時(shí)鐘樹(shù)
STM32F0的最高主頻到48M,所以配置48即可:
串口配置
本次實(shí)驗(yàn)使用的串口1進(jìn)行串口通信,波特率配置為115200。
中斷
GPIO配置
板子上led為PA5端口,故設(shè)置PA5閃爍來(lái)驗(yàn)證是否正確。
定時(shí)器配置
本次實(shí)驗(yàn)使用的是TIM3來(lái)進(jìn)行計(jì)數(shù)。
PWM頻率計(jì)算如下所示
在上面配置TIM3參數(shù),預(yù)分頻系數(shù)設(shè)置為480-1, 自動(dòng)重載值設(shè)置為10000-1,那么PWM頻率為48,000,000/((480-1+1)*(10000-1+1))=10Hz,即 100ms一個(gè)周期。
生成工程設(shè)置
注意在生成工程設(shè)置中不能出現(xiàn)中文,不然會(huì)報(bào)錯(cuò)。
代碼生成設(shè)置
最后設(shè)置生成獨(dú)立的初始化文件:
生成代碼
配置keil
代碼
在main.c中,先加入頭文件。
/* USER CODE BEGIN Includes */
#include "stdio.h"//printf頭文件
#include "string.h"//memset頭文件
/* USER CODE END Includes */
定義變量存儲(chǔ)。
/* USER CODE BEGIN PV */
uint8_t RxBuff[1]; //進(jìn)入中斷接收數(shù)據(jù)的數(shù)組
uint8_t DataBuff[5000]; //保存接收到的數(shù)據(jù)的數(shù)組
int RxLine=0; //接收到的數(shù)據(jù)長(zhǎng)度
int Rx_flag=0; //接受到數(shù)據(jù)標(biāo)志
/* USER CODE END PV */
定義printf的重定向函數(shù)fputc。
/* USER CODE BEGIN 0 */
void printf_usart(void);//輸出內(nèi)容
int fputc(int ch, FILE* file)//定義printf的重定向函數(shù)fputc,滿足串口調(diào)試打印
{
return HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
}
/* USER CODE END 0 */
打開(kāi)串口和定時(shí)器。
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //打開(kāi)串口中斷接收
HAL_TIM_Base_Start_IT(&htim3);//開(kāi)啟定時(shí)器
/* USER CODE END 2 */
串口接受代碼,當(dāng)接受到最后數(shù)據(jù)為FF時(shí)候,直接打印,否則等待100ms打印。
/* USER CODE BEGIN 4 */
void printf_usart(void)
{
printf("數(shù)據(jù)長(zhǎng)度=%d
",RxLine);
for(int i=0;iprintf("數(shù)據(jù):[%d] = 0x%x
",i,DataBuff[i]);
memset(DataBuff,0,sizeof(DataBuff)); //清空緩存數(shù)組
//memset()作用:可以方便的清空一個(gè)結(jié)構(gòu)類(lèi)型的變量或數(shù)組。
//例句:memset(aTxbuffer,0,sizeof(aTxbuffer)) 用memset清空aTxbuffer。
RxLine=0; //清空接收長(zhǎng)度
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == htim3.Instance)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
/* Toggle LED */
if(Rx_flag==1)
{
printf_usart();
Rx_flag=0;
}
}
}
// 捕獲中斷回調(diào)函數(shù),每次捕獲到信號(hào)就會(huì)進(jìn)入這個(gè)回調(diào)函數(shù)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
{
RxLine++; //每接收到一個(gè)數(shù)據(jù),進(jìn)入回調(diào)數(shù)據(jù)長(zhǎng)度加1
DataBuff[RxLine-1]=RxBuff[0]; //把每次接收到的數(shù)據(jù)保存到緩存數(shù)組
Rx_flag=1;
if(RxBuff[0]==0xff) //接收結(jié)束標(biāo)志位,這個(gè)數(shù)據(jù)可以自定義,根據(jù)實(shí)際需求,這里只做示例使用,不一定是0xff
{
printf_usart();
}
RxBuff[0]=0;
HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //每接收一個(gè)數(shù)據(jù),就打開(kāi)一次串口中斷接收,否則只會(huì)接收一個(gè)數(shù)據(jù)就停止接收
__HAL_TIM_SET_COUNTER(&htim3, 1); // 計(jì)數(shù)清零,從頭開(kāi)始計(jì)
}
/* USER CODE END 4 */
演示效果
可以看到 發(fā)送11 12 13需要等待100ms左右才能發(fā)送,如果最后加上ff直接發(fā)送。
審核編輯:湯梓紅
-
定時(shí)器
+關(guān)注
關(guān)注
23文章
3248瀏覽量
114800 -
USART
+關(guān)注
關(guān)注
1文章
195瀏覽量
30857 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
283瀏覽量
14809
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論