STM32串口中断收发的应用接口设计

数据环形缓冲区:

#define FIFO_BUF_SIZE        512 //必须是2的幂次方
#define FIFO_BUF_SIZE_MASK   (FIFO_BUF_SIZE - 1)

typedef struct
{
    uint32 head;                                 //头指针
    uint32 tail;                                    //尾指针
    uint8 buf[FIFO_BUF_SIZE];         //缓冲区
} fifo_buf_t;

缓冲区接口:

status_t fifo_empty(fifo_buf_t* fifo)     //判断缓冲区是否为空
{
    if (fifo->tail == fifo->head) // empty
    {
        return OK;
    }

    return ER;
}

status_t fifo_full(fifo_buf_t* fifo)     //判断缓冲区是否为满
{
    if (((fifo->tail + 1) & FIFO_BUF_SIZE_MASK) == 
        fifo->head) // full
    {
        return OK;
    }

    return ER;
}

status_t fifo_put(fifo_buf_t* fifo, uint8 c)   //往缓冲区放一个字节
{
    if (fifo_full(fifo) == OK) // full
    {
        return ER;
    }

    fifo->buf[fifo->tail] = c;
    fifo->tail ++;
    fifo->tail &= FIFO_BUF_SIZE_MASK;
    
    return OK;
}

status_t fifo_get(fifo_buf_t* fifo, uint8* c)   //往缓冲区取一个字节
{
    if (fifo_empty(fifo) == OK) // empty
    {
        return ER;
    }

    *c = fifo->buf[fifo->head];
    fifo->head ++;
    fifo->head &= FIFO_BUF_SIZE_MASK;

    return OK;
}

串口应用设计原理是:
数据收,接收中断会把数据丢到缓冲区,应用调用读接口,从接收缓冲区里读数据。 数据发,应用调用写接口,写数据到到发送缓冲区里,然后启动发送完成中断,在中断里会判断发送缓冲区是否有数据,有就发送,没有就关闭发送完成中断。

typedef struct   //串口结构体
{
	USART_TypeDef* USARTx;
	fifo_buf_t tx_fifo;                          //发送缓冲区
	fifo_buf_t rx_fifo;                         //接口缓冲区
} uart_driver_t;

static uart_driver_t uart_driver_list[UART_MAX];
   
 void UART_TxIntCallback(int fd)
 {
     if ((fd < 0) || (fd >= UART_MAX))
     {
         return;
     }
     
     uart_driver_t* puart = &uart_driver_list[fd];
     
     if (USART_GetITStatus(puart->USARTx, USART_IT_TC) != RESET)
     { 	
         uint8 c;
         
         if (fifo_get(&puart->tx_fifo, &c) == OK)
         {
             USART_SendData(puart->USARTx, c);
         }
         else
         {
             USART_ITConfig(puart->USARTx, USART_IT_TC, DISABLE);
         }
     }
 }
 
 void UART_RxIntCallback(int fd)
 { 
     if ((fd < 0) || (fd >= UART_MAX))
     {
         return;
     }
     
     uart_driver_t* puart = &uart_driver_list[fd];
     
     if (USART_GetITStatus(puart->USARTx, USART_IT_RXNE) != RESET)
     { 	
         uint8 c;
         c = USART_ReceiveData(puart->USARTx);
         fifo_put(&puart->rx_fifo, c);
     }
 
     //溢出
     if (USART_GetFlagStatus(puart->USARTx, USART_FLAG_ORE) == SET)
     {
         uint8 c;
         c = USART_ReceiveData(puart->USARTx);
         (void)c;
         USART_ClearFlag(puart->USARTx, USART_FLAG_ORE);
     }
 }
 
 static void UART_TxStartup(int fd)
 {
     if ((fd < 0) || (fd >= UART_MAX))
     {
         return;
     }
     
     uart_driver_t* puart = &uart_driver_list[fd];
     USART_ITConfig(puart->USARTx, USART_IT_TC, ENABLE);
 }
 
 int UART_Write(int fd, uint8 *buf, int len)
 {
     if ((fd < 0) || (fd >= UART_MAX))
     {
         return ER;
     }
     
     int i;
     uart_driver_t* puart = &uart_driver_list[fd];
 
     if ((buf == NULL) || (len == 0))
     {
         return ER;
     }
 
     if (fifo_full(&puart->tx_fifo) == OK)
     {
         return 0;
     }
 
     SYS_ENTER_CRITICAL();
 
     for (i = 0;i < len;i ++)
     {
         if (fifo_put(&puart->tx_fifo, buf[i]) == ER)
         {
             break;
         }
     }
 
     SYS_EXIT_CRITICAL();
     
     UART_TxStartup(fd);
     return i;
 }
 
 int UART_Read(int fd, uint8 *buf, int len)
 {
     if ((fd < 0) || (fd >= UART_MAX))
     {
         return ER;
     }
     
     int i;
     uart_driver_t* puart = &uart_driver_list[fd];
 
     if ((buf == NULL) || (len == 0))
     {
         return ER;
     }
 
     if (fifo_empty(&puart->rx_fifo) == OK)
     {
         return 0;
     }
 
     SYS_ENTER_CRITICAL();
 
     for (i = 0;i < len;i ++)
     {
         if (fifo_get(&puart->rx_fifo, &buf[i]) == ER)
         {
             break;
         }
     }
 
     SYS_EXIT_CRITICAL();
 
     return i;
 }
 
 static void UART_MspDeInit(int fd)
 {
     //硬件释放
 }
 
 static void UART_MspInit(int fd)
 {
     //硬件初始化
 }
 
 void UART_DeInit(int fd)
 {
     UART_MspDeInit(fd);
 }
 
 void UART_Init(int fd, uint32 BaudRate, uint16 StopBits, 
     uint16 Parity)
 {
     if ((fd < 0) || (fd >= UART_MAX))
     {
         return;
     }
     
     USART_InitTypeDef USART_InitStructure;
     uart_driver_t* puart = &uart_driver_list[fd];
 
     /* uart fifo */
     memset(&puart->tx_fifo, 0, sizeof(fifo_buf_t)); 
     memset(&puart->rx_fifo, 0, sizeof(fifo_buf_t)); 
 
     UART_MspInit(fd);
 
     /* USART mode config */
     USART_InitStructure.USART_BaudRate = BaudRate; //115200;
     USART_InitStructure.USART_WordLength = ((Parity == USART_Parity_No) 
         ? USART_WordLength_8b : USART_WordLength_9b);
     USART_InitStructure.USART_StopBits = StopBits; //USART_StopBits_1;
     USART_InitStructure.USART_Parity = Parity; //USART_Parity_No;
     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	
     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
     USART_Init(puart->USARTx, &USART_InitStructure);
     USART_ITConfig(puart->USARTx, USART_IT_RXNE, ENABLE);
     USART_ClearFlag(puart->USARTx, USART_FLAG_TC); //清除发送完成标志
 
     USART_Cmd(puart->USARTx, ENABLE);
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值