[程序源码] 串口通讯环形缓冲区应用代码分享

[复制链接]
 楼主| blust5 发表于 2020-3-14 12:13 | 显示全部楼层 |阅读模式
以下代码是我自己写的自己用过的,串口通讯的话加上环形缓冲区之后,很方便处理协议和帧结构相关的逻辑。

uart.c

  1. /*
  2. * uart.c
  3. *
  4. *  Created on: 2018年1月24日
  5. *      Author: blust
  6. */

  7. #include"uart.h"

  8. unsigned char UartTxBuffer[UART_TX_RX_SIZE];    // 发送数组
  9. unsigned char UartRxBuffer[UART_TX_RX_SIZE];    // 接收数组

  10. unsigned char UartRxCircleBuffer[UART_RX_BUFF_SIZE];    // 接收环形缓冲区
  11. volatile unsigned char uart_rx_head = 0;    // 环形缓冲区头,缓冲区头尾重合有两种情况,一种是接收溢出,头覆盖了尾;一种是缓冲区空,所有数据都被读取处理了
  12. volatile unsigned char uart_rx_tail = 0;    // 环形缓冲区尾
  13. volatile unsigned char uart_tx_num = 0;     // 需发送数据长度
  14. volatile unsigned char uart_tx_cnt = 0;     // 发送数据计数

  15. // 初始化函数
  16. void UART_Init(void) //ACLK=32.678K
  17. {
  18.     //Select the IO's function to uart.
  19.     P1DIR  |=  BIT2;             //P1.2  UART_TX
  20.     P1DIR  &= ~BIT1;             //P1.1  UART_RX
  21.     P1SEL  |=  BIT1 + BIT2;        //select P1.1 as UART port
  22.     P1SEL2 |=  BIT1 + BIT2;
  23.     //Set the bus as uart.
  24.     UCA0CTL1 |= UCSWRST;         //reset UART module,as well as enable UART module
  25.     UCA0CTL1 |= UCSSEL1; // CLK = SMCLK  8MHz
  26.     UCA0BR0   = 0x41; // 8MHz/9600 = 833.33   833 = 0x0341
  27.     UCA0BR1   = 0x03;
  28.     UCA0MCTL  = UCBRS1; // UCBRSx = 0.33×8=2.64取整
  29.     UCA0CTL1 &= ~UCSWRST;        //UART reset end
  30.     IE2 |= UCA0RXIE ;  //Open the UART receive interrupt
  31. }

  32. // 读取函数
  33. // 环形缓冲区为空则返回-1
  34. // 读取长度超出数组上限返回-1
  35. // 正常读取则返回数据长度
  36. signed char UART_Read(void)
  37. {
  38.     unsigned char i = 0;

  39.     if(uart_rx_tail == uart_rx_head)
  40.     {
  41.         return -1;
  42.     }

  43.     do{
  44.         if(i >= UART_TX_RX_SIZE)
  45.         {
  46.             return -1;
  47.         }
  48.         UartRxBuffer[i++] = UartRxCircleBuffer[uart_rx_tail++];
  49.         if (uart_rx_tail >= UART_RX_BUFF_SIZE)
  50.         {
  51.             uart_rx_tail = 0;
  52.         }
  53.     }
  54.     while(uart_rx_tail != uart_rx_head);

  55.     return i;
  56. }

  57. #pragma vector=USCIAB0RX_VECTOR
  58. __interrupt void USCI0RX_ISR(void)   //接收中断
  59. {
  60. //    IFG2 &=~UCA0RXIFG;         //clear RX interrupt flag
  61.     timer_comm_stick = 0;                // 用来超时判断帧接收完成的计数变量,定时器里累加和判断超时

  62.     UartRxCircleBuffer[uart_rx_head ++] = UCA0RXBUF;
  63.     if (uart_rx_head >= UART_RX_BUFF_SIZE)
  64.     {
  65.         uart_rx_head = 0;
  66.     }
  67. }

  68. // 发送函数
  69. // 传递参数为要发送的数据长度
  70. // 发送数组采用全局变量UartTxBuffer[],下标从0开始
  71. // 待发送长度为0或超出数组长度,返回-1,正常发送则返回0
  72. signed char UART_Transmit(unsigned char length)
  73. {
  74.     if((length == 0)||(length > UART_TX_RX_SIZE))
  75.     {
  76.         return -1;
  77.     }

  78.     IE2 &= ~UCA0RXIE;   // 关闭接收中断
  79.     IFG2 &= ~UCA0TXIFG; // 清发送中断标志
  80.     IE2 |= UCA0TXIE;    // 打开发送中断
  81.     delay_ms(1);
  82.     uart_tx_cnt = 0;
  83.     uart_tx_num = length;
  84.     UCA0TXBUF = UartTxBuffer[uart_tx_cnt ++];
  85.    
  86.     return 0;
  87. }

  88. // 发送中断
  89. void uart_transmit_isr(void)
  90. {
  91.     if(uart_tx_cnt < uart_tx_num)
  92.     {
  93.         UCA0TXBUF = UartTxBuffer[uart_tx_cnt ++];
  94.     }
  95.     else
  96.     {
  97.         memset(UartTxBuffer, 0, sizeof(UartTxBuffer));
  98.         IFG2 &= ~UCA0TXIFG;  // 清发送中断标志
  99.         IE2  &= ~UCA0TXIE;   // 关闭发送中断
  100.         IFG2 &= ~UCA0RXIFG;  // 清接收中断标志
  101.         IE2  |= UCA0RXIE;    // 开接收中断
  102.     }
  103. }

  104. #pragma vector=USCIAB0TX_VECTOR
  105. __interrupt void USCI0TX_ISR(void)
  106. {
  107.     if(UART_TXIF)
  108.     {
  109.         uart_transmit_isr();
  110.     }
  111. }



 楼主| blust5 发表于 2020-3-14 12:13 | 显示全部楼层
uart.h

  1. /*
  2. * uart.h
  3. *
  4. *  Created on: 2018年1月24日
  5. *      Author: blust
  6. *
  7. * 对外接口:
  8. * 初始化函数                UART_Init();
  9. * 发送函数                        UART_Transmit(length);
  10. * 读取函数                        UART_Read();
  11. * 发送数组                        UartTxBuffer[]
  12. * 接收数组                        UartRxBuffer[]
  13. */

  14. #ifndef UART_H_
  15. #define UART_H_

  16. #include <msp430.h>
  17. #include "stdint.h"
  18. #include <stdio.h>
  19. #include <string.h>


  20. #define UART_RX_BUFF_SIZE   64  // 接收环形缓冲区长度

  21. #define UART_TX_RX_SIZE   64  // 发送接收数组长度
  22. extern unsigned char UartTxBuffer[UART_TX_RX_SIZE];     // 发送数组
  23. extern unsigned char UartRxBuffer[UART_TX_RX_SIZE];     // 接收数组

  24. extern volatile unsigned char uart_rx_head;    // 环形缓冲区头
  25. extern volatile unsigned char uart_rx_tail;    // 环形缓冲区尾


  26. #define UART_TXIF  (IFG2&UCA0TXIFG)
  27. #define UART_RXIF  (IFG2&UCA0RXIFG)

  28. extern void UART_Init(void);
  29. extern signed char UART_Read(void);
  30. extern signed char UART_Transmit(unsigned char length);


  31. #endif /* UART_H_ */
Prry 发表于 2020-3-16 09:17 | 显示全部楼层
参考抽象成模块的:
https://blog.csdn.net/qq_20553613/article/details/78902689
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:业精于勤荒于嬉,行成于思毁于随。

72

主题

2955

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部