dlt645_port.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*************************************************
  2. Copyright (c) 2019
  3. All rights reserved.
  4. File name: dlt645_port.c
  5. Description: DLT645 移植&使用例程文件
  6. History:
  7. 1. Version:
  8. Date: 2019-09-19
  9. Author: wangjunjie
  10. Modify:
  11. *************************************************/
  12. #include "dlt645.h"
  13. #include "gd32f10x_gpio.h"
  14. #include "systick.h"
  15. #define DLT_RXSIZE 200
  16. // DLT645采集使用的串口名
  17. #define DLT645_USART USART1
  18. #define DLT645_CTRL_GPIO GPIOA
  19. #define DLT645_CTRL_PIN GPIO_PIN_8
  20. // DL/T 645硬件拓展结构体
  21. typedef struct
  22. {
  23. uint8_t dlt645_Tx; // 用于串口接收的状态
  24. uint32_t timeout; //
  25. uint8_t rxBuf[DLT_RXSIZE];
  26. uint8_t done;
  27. uint8_t index;
  28. } dlt645_port_t;
  29. static dlt645_port_t dlt645_port;
  30. // dlt645 环境结构体
  31. dlt645_t dlt645;
  32. #if 1
  33. void dlt_callback()
  34. {
  35. if (RESET != usart_interrupt_flag_get(DLT645_USART, USART_INT_FLAG_RBNE))
  36. {
  37. if (dlt645_port.index < DLT_RXSIZE - 1)
  38. {
  39. dlt645_port.rxBuf[dlt645_port.index] = usart_data_receive(DLT645_USART);
  40. dlt645_port.index++;
  41. }
  42. else
  43. {
  44. usart_data_receive(DLT645_USART);
  45. }
  46. usart_interrupt_flag_clear(DLT645_USART, USART_INT_FLAG_RBNE);
  47. }
  48. if ((dlt645_port.index > 0) && RESET != usart_interrupt_flag_get(DLT645_USART, USART_INT_FLAG_IDLE))
  49. {
  50. usart_interrupt_flag_clear(DLT645_USART, USART_INT_FLAG_IDLE);
  51. usart_data_receive(DLT645_USART);
  52. if(dlt645_port.rxBuf[dlt645_port.index-1]!=0x16)//增加一步结束符判断解决部分电表数据不连贯问题
  53. {
  54. dlt645_port.done=0;
  55. }
  56. else
  57. {
  58. dlt645_port.done = 1;
  59. }
  60. return;
  61. }
  62. else
  63. {
  64. usart_interrupt_flag_clear(DLT645_USART, USART_INT_FLAG_RBNE);
  65. }
  66. }
  67. #else
  68. //针对部分老电表发数据包中间出现卡断数据包做的特殊处理
  69. static uint32_t data_time;
  70. static uint32_t data_time_sum[10];
  71. void dlt_callback()
  72. {
  73. if (RESET != usart_interrupt_flag_get(DLT645_USART, USART_INT_FLAG_RBNE))
  74. {
  75. data_time=gettick();//获取最后一次得到数据的时间
  76. data_time_sum[dlt645_port.index]=data_time;
  77. if (dlt645_port.index < DLT_RXSIZE - 1)
  78. {
  79. dlt645_port.rxBuf[dlt645_port.index] = usart_data_receive(DLT645_USART);
  80. dlt645_port.index++;
  81. }
  82. usart_interrupt_flag_clear(DLT645_USART, USART_INT_FLAG_RBNE);
  83. }
  84. if(gettick()-data_time>2000 && data_time!=0)
  85. {
  86. uint32_t nowtime=gettick();
  87. data_time=0;
  88. usart_interrupt_flag_clear(DLT645_USART, USART_INT_FLAG_IDLE);
  89. usart_data_receive(DLT645_USART);
  90. dlt645_port.done = 1;
  91. return;
  92. }
  93. else
  94. {
  95. usart_interrupt_flag_clear(DLT645_USART, USART_INT_FLAG_RBNE);
  96. }
  97. }
  98. #endif
  99. /**
  100. * Name: dlt645_hw_read
  101. * Brief: dlt645 硬件层接收数据
  102. * Input:
  103. * @ctx: 645运行环境
  104. * @msg: 接收数据存放地址
  105. * @len: 数据最大接收长度
  106. * Output: 读取数据的长度
  107. */
  108. static int dlt645_hw_read(dlt645_t *ctx, uint8_t *msg, uint16_t len)
  109. {
  110. int dataLength = 0;
  111. int startTime = gettick();
  112. while (1)
  113. {
  114. if (gettick() - startTime > dlt645_port.timeout * 1000)
  115. return 0;
  116. if (dlt645_port.done == 1)
  117. {
  118. dataLength = dlt645_port.index;
  119. memcpy(msg, &(dlt645_port.rxBuf[4]), len-4);
  120. dataLength = dlt645_port.index-4;
  121. return dataLength;
  122. }
  123. }
  124. }
  125. /**
  126. * Name: dlt645_hw_write
  127. * Brief: dlt645 硬件层发送数据
  128. * Input:
  129. * @ctx: 645运行环境
  130. * @buf: 待发送数据
  131. * @len: 发送长度
  132. * Output: 实际发送的字节数,错误返回-1
  133. */
  134. static int dlt645_hw_write(dlt645_t *ctx, uint8_t *buf, uint16_t len)
  135. {
  136. delay_1ms(1000);
  137. memset(dlt645_port.rxBuf, 0, DLT_RXSIZE);
  138. gpio_bit_set(DLT645_CTRL_GPIO, DLT645_CTRL_PIN);
  139. for (uint16_t i = 0; i < len; i++)
  140. {
  141. usart_data_transmit(DLT645_USART, buf[i]);
  142. while (RESET == usart_flag_get(DLT645_USART, USART_FLAG_TC))
  143. ;
  144. }
  145. gpio_bit_reset(DLT645_CTRL_GPIO, DLT645_CTRL_PIN);
  146. dlt645_port.index = 0;
  147. dlt645_port.done = 0;
  148. return len;
  149. }
  150. void dlt645_init(uint32_t timeout)
  151. {
  152. gpio_bit_set(DLT645_USART, DLT645_CTRL_PIN);
  153. dlt645_port.timeout = timeout;
  154. dlt645_port.dlt645_Tx = 0;
  155. dlt645_port.index = 0;
  156. }
  157. // 645结构体注册
  158. static dlt645_t dlt645 = {
  159. {0},
  160. 0,
  161. dlt645_hw_write,
  162. dlt645_hw_read,
  163. (void *)&dlt645_port};