一、概述
? ? ? ?本文主要介紹如何配置USART接收中斷,使用乒乓緩存的設(shè)計接收數(shù)據(jù)并將其回顯在PC 串口工具上。以stm32f10為例,配置USART1 9600波特率。具體配置參考上一章節(jié)STM32 寄存器配置筆記——USART配置 打印。
? ? ? ? 乒乓緩存的設(shè)計應(yīng)用場景:當(dāng)后面的處理單元在工作期間,前面的 buffer 的內(nèi)容不能被釋放。或者,在處理單元工作期間, buffer 的特定地址的內(nèi)容不止被訪問一次。優(yōu)點是相比全部寫完再讀的方式,可以節(jié)約讀寫時序。
二、中斷優(yōu)先級
? ? ? ?STM32 的中斷向量具有兩個屬性,一個為搶占屬性,另一個為響應(yīng)屬性,其屬性編號越小,表明它的優(yōu)先級別越高。即搶占優(yōu)先級和響應(yīng)優(yōu)先級。
搶占
搶占,是指打斷其他中斷的屬性,即因為具有這個屬性會出現(xiàn)嵌套中斷(在執(zhí)行中斷服務(wù)函數(shù)A 的過程中被中斷B 打斷,執(zhí)行完中斷服務(wù)函數(shù)B 再繼續(xù)執(zhí)行中斷服務(wù)函數(shù)A),搶占屬性由NVIC_IRQChannelPreemptionPriority 的參數(shù)配置。
響應(yīng)
響應(yīng)屬性則應(yīng)用在搶占屬性相同的情況下,當(dāng)兩個中斷向量的搶占優(yōu)先級相同時,如果兩個中斷同時到達, 則先處理響應(yīng)優(yōu)先級高的中斷, 響應(yīng)屬性由NVIC_IRQChannelSubPriority 參數(shù)配置。
?
三、配置流程
? ? ? ? 1)使能RXNE中斷
? ? ? ? 接收緩沖區(qū)非空中斷使能,通過MY_NVIC_init函數(shù)配置中斷的搶占優(yōu)先級和響應(yīng)優(yōu)先級為3(這里可以隨意配置本章重點不在這)。最后一個參數(shù)表示分組為2。即有2位用來表示搶占優(yōu)先級,2位用來表示響應(yīng)優(yōu)先級。
USART1->CR1 |= 1 << 5; // enable RXNE interrupt
MY_NVIC_Init(3,3,USART1_IRQn,2); // 2bit PreemptionPriority 3 2bit SubPriority 3
? ? ? ? 2)編寫串口中斷函數(shù)
? ? ? ? USART1_IRQHandler是在啟動文件里定義的只要有串口中斷便會跑進來。查詢狀態(tài)寄存器USART_SR的RXNE位為1則表示收到數(shù)據(jù)可以讀出。此時從USART_DR寄存器讀取數(shù)據(jù)。
? ? ? 三、乒乓緩存設(shè)計
? ? ? ? ?1)數(shù)據(jù)結(jié)構(gòu)定義
typedef struct
{
u8 USART_RX_BUF[USART_REC_LEN];
u16 len;
} USART_DATA;
typedef struct
{
USART_DATA stUartFifo[2];
u8 curRecFifo;
} USART_HANDLE;
static USART_DATA *p_cur_Usart1_Handle = NULL;
static USART_DATA *p_cur_Data_ProcessingHandle = NULL;
static USART_HANDLE g_Usart1Handle;
uin16 needPro = 0;
? ? ? ? 2)乒乓緩存初始化?
void init_usart_handle(void)
{
memset((u8*)&g_Usart1Handle, 0, sizeof(USART_HANDLE));
p_cur_Usart1_Handle = &g_Usart1Handle.stUartFifo[0];
}
? ? ? ? 3)乒乓緩存接收
void USART1_IRQHandler(void)
{
if(USART1->SR&(1<<5))
{
p_cur_Usart1_Handle->USART_RX_BUF[p_cur_Usart1_Handle->len++] = USART1->DR;
}
}
? ? ? ? ?4)乒乓緩存切換
? ? ? ? 這里是以每收到一幀完整幀的數(shù)據(jù)都是以0x0d 0x0a結(jié)尾的數(shù)據(jù)為例。收到一幀完整幀將當(dāng)前乒乓緩存A切換為處理,乒乓緩存B切換為接收。
void change_curFifo(void)
{
u16 len = p_cur_Usart1_Handle->len;
if (len >= 2)
{
if (p_cur_Usart1_Handle->USART_RX_BUF[len - 2] == 0x0d
&& p_cur_Usart1_Handle->USART_RX_BUF[len - 1] == 0x0a)
{
printf("curFifo:%d len:%d\r\n", g_Usart1Handle.curRecFifo, len);
p_cur_Data_ProcessingHandle = p_cur_Usart1_Handle;
g_Usart1Handle.curRecFifo++;
p_cur_Usart1_Handle = &g_Usart1Handle.stUartFifo[g_Usart1Handle.curRecFifo % 2];
p_cur_Usart1_Handle->len = 0;
needPro = 1;
}
}
}
? ? ? ? 5)乒乓緩存處理
? ? ? ? 打印接收內(nèi)容。
void data_processing(void)
{
if (needPro)
{
needPro = 0;
p_cur_Data_ProcessingHandle->USART_RX_BUF[p_cur_Data_ProcessingHandle->len] = 0;
printf("func:%s dat:%s\r\n", __func__, p_cur_Data_ProcessingHandle->USART_RX_BUF);
}
}
? ? ? 6)調(diào)用如下
? ? ? 主循環(huán)一直輪詢是否需要切換乒乓緩存以及是否存在數(shù)據(jù)待處理。文章來源:http://www.zghlxwxcb.cn/news/detail-828841.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-828841.html
到了這里,關(guān)于STM32 寄存器配置筆記——USART配置中斷接收乒乓緩存處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!