USART_RTx_TypeDef USART1_RTx;
void uart1_initial(void)
{
UART1_DeInit(); /* 将寄存器的值复位 */
/*
* 将UART1配置为:
* 波特率 = 9600
* 数据位 = 8
* 1位停止位
* 无校验位
* 使能接收和发送
* 使能接收中断
*/
UART1_Init((u32)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO , UART1_SYNCMODE_CLOCK_DISABLE , UART1_MODE_TXRX_ENABLE);
UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
//UART1_ITConfig(UART1_IT_TXE, DISABLE);//关串口开始发送中断
//UART1_ITConfig(UART1_IT_TC, DISABLE);//关串口发送结束中断
UART1_Cmd(ENABLE);
}
//--重新加载定时器初值
INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
// In order to detect unexpected events during development,
// it is recommended to set a breakpoint on the following instruction.
/* 如果定时器打开 */
if( USART1_RTx.Timeout_Flag == ON )
{
if(USART1_RTx.Timeout>0)
USART1_RTx.Timeout--;
if(USART1_RTx.Timeout == 0)
{
USART1_RTx.Rec_Flag=1;/* 接收完成标志 */
//TIM4_ITConfig(TIM4_IT_UPDATE, DISABLE);
USART1_RTx.Timeout_Flag = OFF;
USART1_RTx.Process=0;
}
}
//GPIO_WriteReverse(GPIOC, GPIO_PIN_4);
TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
}
INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17)
{
}
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
u8 res;
//读取接收到的数据,当读完数据后自动取消RXNE的中断标志位
res = UART1_ReceiveData8();
if(USART1_RTx.Rx_Length >= 64) USART1_RTx.Rx_Length = 0;
USART1_RTx.Rx_Buf[USART1_RTx.Rx_Length++] = res;
switch(USART1_RTx.Process)
{
case 0:
USART1_RTx.Timeout=3;
USART1_RTx.Process=1;
//TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
USART1_RTx.Timeout_Flag = ON;
break;
case 1:
USART1_RTx.Timeout=3;
break;
default:
USART1_RTx.Timeout=0;
USART1_RTx.Process=0;
//TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
USART1_RTx.Timeout_Flag = ON;
break;
}
//清中断。
UART1_ClearITPendingBit(UART1_IT_RXNE);
}
头文件设置下
#ifndef __UART_H__
#define __UART_H__
#include "main.h"
typedef struct
{
uint8_t Rec_Flag;
uint8_t Process;
uint8_t Timeout_Flag;
uint8_t Timeout;/* 单位ms */
uint8_t Rx_Length;
uint8_t Tx_Buf[64];
uint8_t Rx_Buf[64];
}USART_RTx_TypeDef;
extern USART_RTx_TypeDef USART1_RTx;
void uart1_initial(void);
void uart_Sendbyte (u8 byte);
void uart_SendString(u8 *string);
void uart_SendDatas(u8 *Datas,u16 Num);
#endif /* __UART_H__ */
主函数测试
while(1)
{
if(USART1_RTx.Rec_Flag)
{
USART1_RTx.Rec_Flag = 0;
uart_SendDatas(USART1_RTx.Rx_Buf,USART1_RTx.Rx_Length);
memset(USART1_RTx.Rx_Buf,0,64);
USART1_RTx.Rx_Length = 0;
}
//led_task();
//uart1_send_string(test_str);
//uart1_send_buffer(test_str,sizeof(test_str));
//GPIO_WriteReverse(GPIOB, GPIO_PIN_5);
}
实现方法也是网上分享的方式,我这里只是把方式修改了下。串口发送 间隔最好 大于等于70ms 当然 要不然会出现黏包
另外我仔细看了下,stm8s也有串口空闲中断,也可以用空闲中断的方法实现,下次有空验证下。
/**
* @brief UART1 Interrupt definition
* UART1_IT possible values
* Elements values convention: 0xZYX
* X: Position of the corresponding Interrupt
* - For the following values, X means the interrupt position in the CR2 register.
* UART1_IT_TXE
* UART1_IT_TC
* UART1_IT_RXNE
* UART1_IT_IDLE
* UART1_IT_OR
* - For the UART1_IT_PE value, X means the flag position in the CR1 register.
* - For the UART1_IT_LBDF value, X means the flag position in the CR4 register.
* Y: Flag position
* - For the following values, Y means the flag (pending bit) position in the SR register.
* UART1_IT_TXE
* UART1_IT_TC
* UART1_IT_RXNE
* UART1_IT_IDLE
* UART1_IT_OR
* UART1_IT_PE
* - For the UART1_IT_LBDF value, Y means the flag position in the CR4 register.
* Z: Register index: indicate in which register the dedicated interrupt source is:
* - 1==> CR1 register
* - 2==> CR2 register
* - 3==> CR4 register
*/
typedef enum { UART1_IT_TXE = (uint16_t)0x0277, /*!< Transmit interrupt */
UART1_IT_TC = (uint16_t)0x0266, /*!< Transmission Complete interrupt */
UART1_IT_RXNE = (uint16_t)0x0255, /*!< Receive interrupt */
UART1_IT_IDLE = (uint16_t)0x0244, /*!< IDLE line interrupt */
UART1_IT_OR = (uint16_t)0x0235, /*!< Overrun Error interrupt */
UART1_IT_PE = (uint16_t)0x0100, /*!< Parity Error interrupt */
UART1_IT_LBDF = (uint16_t)0x0346, /**< LIN break detection interrupt */
UART1_IT_RXNE_OR = (uint16_t)0x0205 /*!< Receive/Overrun interrupt */
} UART1_IT_TypeDef;