cubemx STM32空閒中斷,非DMA收發

從前面文章知道,我用過DMA收發,但有時候需要用非DMA方式,我發現如果使用DMA方式發送的話,代碼一下子多起來好的。我就是這個原因才用非DMA方式的。人狠話不多,直接上圖,上代碼:
cubemx,配置如下,全局中斷打開,其他波特率什麼的可自行配置,略過:
在這裏插入圖片描述

直接生成後初始化添加的代碼,開啓中斷:

void usart1_Init(){
	HAL_UART_Receive_IT(&huart1, rx_EPOS_Buff, EPOS_RX_FRAME_LEN);  
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
	}

然後很關鍵的接收中斷函數,添加到it.c的中斷函數裏

void usart_Receive_IDLE(UART_HandleTypeDef *huart)
{
	uint32_t temp;
	uint8_t rx_Len;
	unsigned char  res_ack='O';
	loopData_Typedef buffer_loop;
	
	if(huart->Instance==USART1) //USART1
	{
		if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
		{
			__HAL_UART_CLEAR_IDLEFLAG(huart);
//			temp = huart1.Instance->SR; //Clear USART_IT_RXNE Flag
//			temp = huart1.Instance->DR; //Clear USART_IT_IDLE Flag
//			temp = temp;

			if (huart->RxState == HAL_UART_STATE_BUSY_RX)
        {
            /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
            CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
            CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
            /* At end of Rx process, restore huart->RxState to Ready */
            huart->RxState = HAL_UART_STATE_READY;
        }


			rx_Len=EPOS_RX_FRAME_LEN-huart->RxXferCount;
			#if 1 //調試  收發的全部發送出來
			HAL_UART_Transmit(&huart1,rx_EPOS_Buff,rx_Len,200);
//			EPOS_SendCmd(rx_EPOS_Buff,rx_Len);	
			#endif
			HAL_UART_Receive_IT(huart, rx_EPOS_Buff, EPOS_RX_FRAME_LEN);  
		}
	}
}

下面這個函數必須添加,如果不添加,下一幀的的數據會跟接着上一次緩存位置往下存;添加此函數後,下一幀的數據會從頭開始存。
原理上式當接收長度達到EPOS_RX_FRAME_LEN的長度,RxState纔會變成ready,否則爲busy

 huart->RxState = HAL_UART_STATE_READY;

接着是發送函數,以及它的回調函數了,我用的式要給二值信號量等待發送完成,特別注意的是,有的RTOS 二值信號量是不可以用在中斷裏面的,切記,我跳過坑。當然不用系統,你們用while等待發送完成也是可以的。

void EPOS_SendCmd(unsigned char *cmd,unsigned char len){
//	HAL_UART_Transmit(&huart1,cmd,len,200);
	HAL_UART_Transmit_IT(&huart1,cmd,len);
	#ifdef IRQ_Back_Flag
	osSemaphoreAcquire(sid_Semaphore_usart1_tx, osWaitForever); /*等待發送完成*/
	#endif
}

#ifdef IRQ_Back_Flag
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){
	if(huart->Instance == USART1){
		osSemaphoreRelease(sid_Semaphore_usart1_tx);		//count incremented;	
	}
}
#endif 

下面兩個函數的區別是,第一個爲阻塞式(死等 hal_delay),第二個爲非阻塞式(可切換線程繼續跑)
HAL_UART_Transmit(&huart1,cmd,len,200);
HAL_UART_Transmit_IT(&huart1,cmd,len);

人狠,話不多。看完不用叫我雷鋒,但一定要點贊、關注,當然如果有土豪駕到,來個打賞我也不會怪你。

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