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);

人狠,话不多。看完不用叫我雷锋,但一定要点赞、关注,当然如果有土豪驾到,来个打赏我也不会怪你。

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