当前位置:   article > 正文

HAL STM32使用环形缓冲区域 读取数据包

HAL STM32使用环形缓冲区域 读取数据包

tjc_usart_hmi.c

  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #include "tjc_usart_hmi.h"
  5. #include <stddef.h>
  6. #include "usart.h"
  7. #include <string.h>
  8. #include <stdlib.h>
  9. typedef struct
  10. {
  11. uint16_t Head; // 头指针 指向可读起始地址 每读一个,数字+1
  12. uint16_t Tail; // 尾指针 指向可写的起始地址 每写一个,数字+1,当尾指针超过数组大小,
  13. // 则尾指针又指向数组首地址。
  14. uint16_t Lenght; // 长度
  15. uint8_t Ring_data[RINGBUFF_LEN]; // 数据缓冲区
  16. }RingBuff_t;
  17. RingBuff_t ringBuff; //创建一个ringBuff的缓冲区
  18. uint8_t RxBuff[1]; // 串口接收地址
  19. #define STR_LENGTH 40 // 定义串口发送的缓冲大小
  20. //字符串发送函数 HMISends("n0.val=2333");
  21. void HMISends(char *fmt, ...)
  22. {
  23. char buffer[STR_LENGTH];
  24. const char endFlag[13]="\xff\xff\xff";
  25. uint8_t len;
  26. va_list arg;
  27. va_start(arg, fmt);
  28. vsnprintf((char *)buffer,STR_LENGTH,fmt,arg);
  29. va_end(arg);
  30. strcat(buffer,endFlag);
  31. len=strlen(&buffer);
  32. HAL_UART_Transmit(&huart1,(uint8_t *)&buffer,len,0xffff);
  33. }
  34. /********************************************************
  35. 函数名: HAL_UART_RxCpltCallback
  36. 功能: 串口接收中断,将接收到的数据写入环形缓冲区
  37. **********************************************************/
  38. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  39. {
  40. if(huart->Instance == USART1)
  41. {
  42. HAL_UART_Receive_IT(&huart1,&RxBuff[0],1);
  43. writeRingBuff(RxBuff[0]);
  44. }
  45. }
  46. /********************************************************
  47. 函数名: initRingBuff
  48. 功能: 初始化环形缓冲区
  49. 输入参数:
  50. 返回值: void
  51. 修改记录:
  52. **********************************************************/
  53. void initRingBuff(void)
  54. {
  55. //初始化相关信息
  56. ringBuff.Head = 0;
  57. ringBuff.Tail = 0;
  58. ringBuff.Lenght = 0;
  59. }
  60. /********************************************************
  61. 函数名: writeRingBuff
  62. 功能: 往环形缓冲区写入数据 每次写入一个数据
  63. **********************************************************/
  64. void writeRingBuff(uint8_t data)
  65. {
  66. if(ringBuff.Lenght >= RINGBUFF_LEN) //判断缓冲区是否已满
  67. {
  68. return ;
  69. }
  70. ringBuff.Ring_data[ringBuff.Tail]=data; //写入到尾数据
  71. ringBuff.Tail = (ringBuff.Tail+1)%RINGBUFF_LEN; //防止越界非法访问 Tail=RINGBUFF_LEN 就为0
  72. //如果Tail指针已经到达缓冲区的末尾,那么Tail+1就会变成0
  73. ringBuff.Lenght++;} // 数据长度+1
  74. /********************************************************
  75. 函数名: deleteRingBuff
  76. 功能: 删除串口缓冲区中相应长度的数据 从头删除指定长度
  77. 输入参数: 要删除的长度
  78. **********************************************************/
  79. void deleteRingBuff(uint16_t size)
  80. {
  81. if(size >= ringBuff.Lenght) // 确保小于以有数据
  82. {
  83. initRingBuff();
  84. return;
  85. }
  86. for(int i = 0; i < size; i++)
  87. {
  88. if(ringBuff.Lenght == 0)//判断非空
  89. {
  90. initRingBuff();
  91. return;
  92. }
  93. ringBuff.Head = (ringBuff.Head+1)%RINGBUFF_LEN;//防止越界非法访问
  94. ringBuff.Lenght--;
  95. }
  96. }
  97. /********************************************************
  98. 函数名: read1BFromRingBuff
  99. 功能: 从串口缓冲区读取1字节数据
  100. 输入参数: position:读取的位置
  101. 返回值: 所在位置的数据(1字节)
  102. **********************************************************/
  103. uint8_t read1BFromRingBuff(uint16_t position)
  104. {
  105. uint16_t realPosition = (ringBuff.Head + position) % RINGBUFF_LEN;
  106. return ringBuff.Ring_data[realPosition];
  107. }
  108. /********************************************************
  109. 函数名: getRingBuffLenght
  110. 功能: 获取串口缓冲区的数据数量
  111. 返回值: 串口缓冲区的数据数量
  112. **********************************************************/
  113. uint16_t getRingBuffLenght()
  114. {
  115. return ringBuff.Lenght;
  116. }
  117. /********************************************************
  118. 函数名: isRingBuffOverflow
  119. 功能: 判断环形缓冲区是否已满
  120. 返回值: 1:环形缓冲区已满 , 2:环形缓冲区未满
  121. **********************************************************/
  122. uint8_t isRingBuffOverflow()
  123. {
  124. return ringBuff.Lenght == RINGBUFF_LEN;
  125. }
  126. void tjcUsartHmi_Init(){
  127. HAL_UART_Receive_IT(&huart1,&RxBuff[0],1); // 打开串口中断
  128. initRingBuff(); // 初始化串口缓冲区
  129. }
  130. //串口数据帧长度:6字节
  131. //帧头 led编号 LED状态 帧尾
  132. //0x55 1字节 1字节 0xffffff
  133. //例子1:上位机代码 printh 55 01 00 ff ff ff 含义:1号led关闭
  134. //例子2:上位机代码 printh 55 04 01 ff ff ff 含义:4号led打开
  135. //例子3:上位机代码 printh 55 00 01 ff ff ff 含义:0号led打开
  136. //例子4:上位机代码 printh 55 04 00 ff ff ff 含义:4号led关闭
  137. #define FRAMELENGTH 6 // 数据包的长度
  138. // 数据包解析函数
  139. void UsartDataAnalysis()
  140. {
  141. while(usize >= FRAMELENGTH) // 如果以及接收的数据长于数据包的长度
  142. {
  143. //校验帧头帧尾是否匹配
  144. if(u(0) != 0x55 || u(3) != 0xff || u(4) != 0xff || u(5) != 0xff)
  145. {
  146. //不匹配删除1字节
  147. udelete(1);
  148. }else
  149. {
  150. //匹配,跳出循环
  151. break;
  152. }
  153. }
  154. //进行解析
  155. if(usize >= FRAMELENGTH && u(0) == 0x55 && u(3) == 0xff && u(4) == 0xff && u(5) == 0xff)
  156. {
  157. // 读取对应字节 //
  158. udelete(FRAMELENGTH); // 删除对应数据包的
  159. }
  160. }

tjc_usart_hmi.h

  1. #ifndef __TJCUSARTHMI_H_
  2. #define __TJCUSARTHMI_H_
  3. #include "main.h"
  4. #define RINGBUFF_LEN (500) //定义最大接收字节数 500
  5. extern uint8_t RxBuff[1];
  6. #define usize getRingBuffLenght()
  7. #define code_c() initRingBuff()
  8. #define udelete(x) deleteRingBuff(x)
  9. #define u(x) read1BFromRingBuff(x)
  10. void tjcUsartHmi_Init();
  11. void HMISends(char *fmt, ...);
  12. void initRingBuff(void);
  13. void writeRingBuff(uint8_t data);
  14. void deleteRingBuff(uint16_t size);
  15. uint16_t getRingBuffLenght(void);
  16. uint8_t read1BFromRingBuff(uint16_t position);
  17. #endif

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/635429
推荐阅读
相关标签
  

闽ICP备14008679号