L76K.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * Copyright (c) 2020  Jinan Bosai Network Technology Co., Ltd.
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include "L76K.h"
  18. #include "iot_errno.h"
  19. #include "iot_gpio.h"
  20. #include "iot_gpio_ex.h"
  21. #include "iot_pwm.h"
  22. #include "iot_uart.h"
  23. #define WIFI_IOT_PWM_PORT_PWM1 1
  24. #define WIFI_IOT_IO_FUNC_GPIO_8_PWM1_OUT 5
  25. #define WIFI_IOT_IO_FUNC_GPIO_7_GPIO 0
  26. #define BEEP_GPIO 8
  27. #define LED_GPIO 14
  28. #define RESET_GPIO 7
  29. #define STANDBY_GPIO 13
  30. #define WIFI_IOT_UART_IDX_1 1
  31. gps_msg gpsmsg;
  32. static unsigned char gps_uart[1000];
  33. /***************************************************************
  34. * 函数名称: BoardInit
  35. * 说 明: 初始化扩展板
  36. * 参 数: 无
  37. * 返 回 值: 无
  38. ***************************************************************/
  39. void BoardInit(void)
  40. {
  41. uint32_t ret;
  42. IoTGpioInit(BEEP_GPIO);
  43. IoTGpioSetFunc(BEEP_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
  44. IoTGpioSetDir(BEEP_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
  45. IoTGpioInit(LED_GPIO);
  46. IoTGpioSetFunc(LED_GPIO, IOT_GPIO_FUNC_GPIO_14_GPIO);
  47. IoTGpioSetDir(LED_GPIO, IOT_GPIO_DIR_OUT); //设置GPIO_7为输出模式
  48. IoTGpioInit(RESET_GPIO);
  49. IoTGpioSetFunc(RESET_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
  50. IoTGpioSetDir(RESET_GPIO, IOT_GPIO_DIR_OUT); //设置GPIO_7为输出模式
  51. IoTGpioSetOutputVal(RESET_GPIO, 0);
  52. IoTGpioInit(STANDBY_GPIO);
  53. IoTGpioSetFunc(STANDBY_GPIO, IOT_GPIO_FUNC_GPIO_13_GPIO);
  54. IoTGpioSetDir(STANDBY_GPIO, IOT_GPIO_DIR_OUT); //设置GPIO_7为输出模式
  55. IoTGpioSetOutputVal(STANDBY_GPIO, 0);
  56. IotUartAttribute uart_attr = {
  57. // baud_rate: 9600
  58. .baudRate = 9600,
  59. // data_bits: 8bits
  60. .dataBits = 8,
  61. .stopBits = 1,
  62. .parity = 0,
  63. };
  64. // Initialize uart driver
  65. ret = IoTUartInit(WIFI_IOT_UART_IDX_1, &uart_attr);
  66. if (ret != IOT_SUCCESS) {
  67. printf("Failed to init uart! Err code = %d\n", ret);
  68. return;
  69. }
  70. }
  71. /***************************************************\
  72. * 函数名称: NMEA_Comma_Pos
  73. * 函数功能:从buf里面得到第cx个逗号所在的位置
  74. * 输入值:
  75. * 返回值:0~0xFE,代表逗号所在位置的便宜
  76. * 0xFF,代表不存在第cx个逗号
  77. \***************************************************/
  78. uint8_t NMEA_Comma_Pos(uint8_t* buf, uint8_t cx)
  79. {
  80. uint8_t* p = buf;
  81. while (cx) {
  82. if (*buf == '*' || *buf < ' ' || *buf > 'z')
  83. return 0xFF;
  84. if (*buf == ',')
  85. cx--;
  86. buf++;
  87. }
  88. return buf - p;
  89. }
  90. /***************************************************\
  91. * 函数名称: NMEA_Pow
  92. * 函数功能:返回m的n次方值
  93. * 输入值:底数m和指数n
  94. * 返回值:m^n
  95. \***************************************************/
  96. uint32_t NMEA_Pow(uint8_t m, uint8_t n)
  97. {
  98. uint32_t result = 1;
  99. while (n--)
  100. result *= m;
  101. return result;
  102. }
  103. /***************************************************\
  104. * 函数名称: NMEA_Str2num
  105. * 函数功能:str数字转换为(int)数字,以','或者'*'结束
  106. * 输入值:buf,数字存储区
  107. * dx,小数点位数,返回给调用函数
  108. * 返回值:转换后的数值
  109. \***************************************************/
  110. int NMEA_Str2num(uint8_t* buf, uint8_t* dx)
  111. {
  112. uint8_t* p = buf;
  113. uint32_t ires = 0, fres = 0;
  114. uint8_t ilen = 0, flen = 0, i;
  115. uint8_t mask = 0;
  116. int res;
  117. while (1) {
  118. if (*p == '-') {
  119. mask |= 0x02;
  120. p++;
  121. } //说明有负数
  122. if (*p == ',' || *p == '*')
  123. break; //遇到结束符
  124. if (*p == '.') {
  125. mask |= 0x01;
  126. p++;
  127. } //遇到小数点
  128. else if (*p > '9' || (*p < '0')) //数字不在0和9之内,说明有非法字符
  129. {
  130. ilen = 0;
  131. flen = 0;
  132. break;
  133. }
  134. if (mask & 0x01)
  135. flen++; //小数点的位数
  136. else
  137. ilen++; // str长度加一
  138. p++; //下一个字符
  139. }
  140. if (mask & 0x02)
  141. buf++; //移到下一位,除去负号
  142. for (i = 0; i < ilen; i++) //得到整数部分数据
  143. {
  144. ires += NMEA_Pow(10, ilen - 1 - i) * (buf[i] - '0');
  145. }
  146. if (flen > 5)
  147. flen = 5; //最多取五位小数
  148. *dx = flen;
  149. for (i = 0; i < flen; i++) //得到小数部分数据
  150. {
  151. fres += NMEA_Pow(10, flen - 1 - i) * (buf[ilen + 1 + i] - '0');
  152. }
  153. res = ires * NMEA_Pow(10, flen) + fres;
  154. if (mask & 0x02)
  155. res = -res;
  156. return res;
  157. }
  158. /***************************************************\
  159. * 函数名称: NMEA_BDS_GPRMC_Analysis
  160. * 函数功能:解析GNRMC信息
  161. * 输入值:gpsx,NMEA信息结构体
  162. * buf:接收到的GPS数据缓冲区首地址
  163. \***************************************************/
  164. void NMEA_BDS_GPRMC_Analysis(gps_msg* gpsmsg, uint8_t* buf)
  165. {
  166. uint8_t *p4, dx;
  167. uint8_t posx;
  168. uint32_t temp;
  169. float rs;
  170. p4 = (uint8_t*)strstr((const char*)buf, "$GNRMC"); //"$GPRMC",经常有&和GPRMC分开的情况,故只判断GPRMC.
  171. if (p4 != NULL) {
  172. posx = NMEA_Comma_Pos(p4, 3); //得到纬度
  173. if (posx != 0XFF) {
  174. temp = NMEA_Str2num(p4 + posx, &dx);
  175. gpsmsg->latitude_bd = temp / NMEA_Pow(10, dx + 2); //得到°
  176. rs = temp % NMEA_Pow(10, dx + 2); //得到'
  177. gpsmsg->latitude_bd = gpsmsg->latitude_bd * NMEA_Pow(10, 5) + (rs * NMEA_Pow(10, 5 - dx)) / 60; //转换为°
  178. }
  179. posx = NMEA_Comma_Pos(p4, 4); //南纬还是北纬
  180. if (posx != 0XFF)
  181. gpsmsg->nshemi_bd = *(p4 + posx);
  182. posx = NMEA_Comma_Pos(p4, 5); //得到经度
  183. if (posx != 0XFF) {
  184. temp = NMEA_Str2num(p4 + posx, &dx);
  185. gpsmsg->longitude_bd = temp / NMEA_Pow(10, dx + 2); //得到°
  186. rs = temp % NMEA_Pow(10, dx + 2); //得到'
  187. gpsmsg->longitude_bd = gpsmsg->longitude_bd * NMEA_Pow(10, 5) + (rs * NMEA_Pow(10, 5 - dx)) / 60; //转换为°
  188. }
  189. posx = NMEA_Comma_Pos(p4, 6); //东经还是西经
  190. if (posx != 0XFF)
  191. gpsmsg->ewhemi_bd = *(p4 + posx);
  192. }
  193. }
  194. /***************************************************************
  195. * 函数名称: L76ReadData
  196. * 说 明: 获取经纬度信息
  197. * 参 数: 无
  198. * 返 回 值: 无
  199. ***************************************************************/
  200. void L76ReadData(L76Data* ReadData)
  201. {
  202. //通过串口1接收数据
  203. IoTUartRead(WIFI_IOT_UART_IDX_1, gps_uart, 1000);
  204. NMEA_BDS_GPRMC_Analysis(&gpsmsg, (uint8_t*)gps_uart); //分析字符串
  205. ReadData->Longitude = (float)((float)gpsmsg.longitude_bd / 100000);
  206. ReadData->Latitude = (float)((float)gpsmsg.latitude_bd / 100000);
  207. }
  208. /***************************************************************
  209. * 函数名称: BeepStatusSet
  210. * 说 明: Beep状态设置
  211. * 参 数: status,ENUM枚举的数据
  212. * OFF,关
  213. * ON,开
  214. * 返 回 值: 无
  215. ***************************************************************/
  216. void BeepStatusSet(SwitchStatus status)
  217. {
  218. if (status == ON) {
  219. IoTGpioSetOutputVal(BEEP_GPIO, 1); // 设置GPIO_7输出高电平点亮灯
  220. }
  221. if (status == OFF) {
  222. IoTGpioSetOutputVal(BEEP_GPIO, 0); // 设置GPIO_7输出低电平关闭灯
  223. }
  224. }
  225. /***************************************************************
  226. * 函数名称: LedWarnStatusSet
  227. * 说 明: LED_Warn状态设置
  228. * 参 数: status,ENUM枚举的数据
  229. * OFF,关
  230. * ON,开
  231. * 返 回 值: 无
  232. ***************************************************************/
  233. void LedWarnStatusSet(SwitchStatus status)
  234. {
  235. if (status == ON) {
  236. IoTGpioSetOutputVal(LED_GPIO, 1); // 设置输出高电平点亮灯
  237. }
  238. if (status == OFF) {
  239. IoTGpioSetOutputVal(LED_GPIO, 0); // 设置输出低电平关闭灯
  240. }
  241. }