写在前面
- 使用STM32F767有两种中断方式(超时中断和空闲中断)接不定长的数据,其中超时中断要比空闲中断好用
超时中断
相关寄存器
接收器超时寄存器(USARTx_RTOR)
空闲中断
空闲中断:就是说每接收到一条完整的数据就会置位空闲标志位,我们只需要判断空闲标志位是否置一,就能知道是不是接收到了一条完整的数据。
用空闲中断的好处就是,对于以前我写程序通信都会在数据的后面加上尾(/n什么的),然后另一个接收的单片机通过判断数据的尾来确定是不是一条完整的数据,有了空闲中断就不需要在给数据加上尾了
整体思路
使用STC 的HAL库在其中断服务函数USART1_IRQHandler中编写对于空闲中断触发的处理过程。
其中可以使用RXNE一个字节一个字节的获取数据,在没有数据进来的时候,进入空闲中断,这时候拿出存储的数据处理就可以了。
数据的回显使用HAL_UART_Transmit显示就好了,在有串口1连接的情况下,会直接发送至串口1
附录
程序代码
如下代码,注释部分为空闲中断实现,未注释部分使用超时中断实现
#include "sys.h"
#include "stdio.h"
#include "stm32f7xx_hal_uart.h"
#include "delay.h"
#include "uart_drv.h"
#include "string.h"
#if 1
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
while((USART1->ISR&0X40)==0);
USART1->TDR=(u8)ch;
return ch;
}
#endif
u8 bUsartRxBuf[USART_REC_LEN];
u16 wUsartRxSta=0;
u16 wUartRxCounter=0;
u8 bRxBuffer[RXBUFFERSIZE];
UART_HandleTypeDef UART1_Handler;
void uart_init(u32 bound)
{
UART1_Handler.Instance = USART1;
UART1_Handler.Init.BaudRate = bound;
UART1_Handler.Init.WordLength = UART_WORDLENGTH_8B;
UART1_Handler.Init.StopBits = UART_STOPBITS_1;
UART1_Handler.Init.Parity = UART_PARITY_NONE;
UART1_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UART1_Handler.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&UART1_Handler);
__HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE);
SET_BIT(UART1_Handler.Instance->CR2,USART_CR2_RTOEN);
SET_BIT(UART1_Handler.Instance->CR1,USART_CR1_RTOIE);
WRITE_REG(UART1_Handler.Instance->RTOR,22);
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_Initure = {0};
if (huart->Instance == USART1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
GPIO_Initure.Pin = GPIO_PIN_9;
GPIO_Initure.Mode = GPIO_MODE_AF_PP;
GPIO_Initure.Pull = GPIO_PULLUP;
GPIO_Initure.Speed = GPIO_SPEED_FAST;
GPIO_Initure.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_Initure);
GPIO_Initure.Pin = GPIO_PIN_10;
HAL_GPIO_Init(GPIOA, &GPIO_Initure);
#if EN_USART1_RX
HAL_NVIC_EnableIRQ(USART1_IRQn);
HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);
#endif
}
}
void USART1_IRQHandler(void)
{
uint32_t isrflags = READ_REG(UART1_Handler.Instance->ISR);
uint32_t cr1its = READ_REG(UART1_Handler.Instance->CR1);
uint32_t cr3its = READ_REG(UART1_Handler.Instance->CR3);
if (((isrflags & USART_ISR_ORE) != RESET) &&
(((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))
{
__HAL_UART_CLEAR_IT(&UART1_Handler, UART_CLEAR_OREF);
}
if ((__HAL_UART_GET_FLAG(&UART1_Handler, UART_FLAG_RXNE) != RESET))
{
if (wUsartRxSta == 0x0000)
{
wUsartRxSta = 0x4000;
wUartRxCounter = 0;
memset(bUsartRxBuf,0,sizeof(bUsartRxBuf));
bUsartRxBuf[wUartRxCounter] = (uint8_t)(UART1_Handler.Instance->RDR & (uint8_t)0x00FF);
wUartRxCounter++;
}
else if (wUsartRxSta == 0x4000)
{
bUsartRxBuf[wUartRxCounter] = (uint8_t)(UART1_Handler.Instance->RDR & (uint8_t)0x00FF);
wUartRxCounter++;
}
}
if (READ_BIT(UART1_Handler.Instance->ISR,USART_ISR_RTOF))
{
SET_BIT(UART1_Handler.Instance->ICR,USART_ICR_RTOCF);
if (wUartRxCounter > 0)
{
wUsartRxSta |= 0x8000;
}
}
}
参考
【超时中断参考】
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)