STM32 串口 空閒中斷使用

最近搞串口接收完整的數據幀,雖然很早就接觸串口,但是工作上用還是會遇到不少問題。串口收包過程,首先要解決的問題就是要保證接收到完整的數據包,參考網上的串口收包方法,多數是使用定時器做超時判斷,又或者加DMA之類的,考慮到我的串口只是做小數據量收發(收發指令),要額外使用一個定時器,就太複雜了。查資料過程中發現了串口空閒中斷,故想空閒中斷來接收串口數據幀。以下是空閒中斷的參考demo:

主函數 main.c

/**
  ******************************************************************************
  * @file    main.c
  * @author  Lewis
  * @version V1.0
  * @date    2019-12-18
  * @brief   調試函數PR的Demo
  ******************************************************************************
  * @attention
  * Software Truestudio for STM32
  */

#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_GeneralTim.h"
#include "string.h"

extern unsigned char data_buffer[256];
extern unsigned char rx_done;
extern unsigned char rx_cnt;

/**
  * @brief  主函數
  * @param  無
  * @retval 無
  */

int main(void)
{

	unsigned char i = 0;

    USART_Config(); // USART1 115200 8-N-1

    // GENERAL_TIM_Init();

    PR("IEM init done...\r\n");

    // 開定時器
    // TIM_Cmd(GENERAL_TIM, ENABLE);

    while(1)
    {
        if( rx_done == 1 )
        {
        	rx_done = 0;

        	PR("UART RX done...\r\n");

        	PR("rx_cnt = %d.\r\n",rx_cnt);

        	for( i = 0; i < rx_cnt; i++ )
        	{
        		PR( "data_buffer[%d] = 0x%x\r\n", i, data_buffer[i] );
        	}

        	// 清空數組
        	memset( data_buffer, 0x00, rx_cnt );

        	PR("---------------------------\r\n");

        	for( i = 0; i < rx_cnt; i++ )
        	{
        		PR( "data_buffer[%d] = 0x%x\r\n", i, data_buffer[i] );
        	}

        	USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);

        	PR("UART1 reopen done.\r\n");
        }
    }
}



/*--------------------------------------------------------------------------------*/

串口初始化部分:
略-就是常見的配置端口,波特率,開中斷之類的

/*--------------------------------------------------------------------------------*/

// 串口中斷服務函數
void USART1_IRQHandler(void)
{
	// 接收中斷
	if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET )
	{


		if( state == STATE_READY )
		{
			state = STATE_START;

			// 串口計數清零
			rx_cnt = 0;

			// 開啓串口1空閒中斷
			USART1->CR1 |= (1<<4);
			// USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //開啓串口1空閒中斷

			// 接收首字節
			data_buffer[rx_cnt] = USART_ReceiveData(USART1);

			rx_cnt ++;

		}else if( state == STATE_START )
		{
			data_buffer[rx_cnt] = USART_ReceiveData(USART1);
			rx_cnt ++;
		}

		// 清接收標誌
	}

	// 進入空閒中斷
	if( USART_GetITStatus(USART1,USART_IT_IDLE) != RESET )
	{
		// 關閉空閒中斷
		USART1->CR1 &= ~(1<<4);
		// USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);

		// 關閉串口1接收中斷
		USART1->CR1 &= ~(1<<5);
		// USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);

		// 狀態表明一幀數據接收完成了,需要處理。處理完以後再把接收中斷打開
		rx_done = 1;

		// 清除空閒中斷
		clear = USART1->DR;

		// 復位狀態機
		state = STATE_READY;
	}
}

測試:
hex 發送 11 22 33 44 55 66

[10:27:18.672]發→◇"3DUf□
[10:27:18.675]收←◆UART RX done...
rx_cnt = 6.
data_buffer[0] = 0x11
data_buffer[1] = 0x22
data_buffer[2] = 0x33
data_buffer[3] = 0x44
data_buffer[4] = 0x55
data_buffer[5] = 0x66
---------------------------
data_buffer[0] = 0x0
data_buffer[1] = 0x0
data_buffer[2] = 0x0
data_buffer[3] = 0x0
data_buffer[4] = 0x0
data_buffer[5] = 0x0
UART1 reopen done.

參考:
利用stm32串口空閒中斷接收不定長數據
http://www.eemaker.com/stm32-uart-budingchangshuju.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章