从前面文章知道,我用过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);
人狠,话不多。看完不用叫我雷锋,但一定要点赞、关注,当然如果有土豪驾到,来个打赏我也不会怪你。