|
本帖最后由 xinxiaojun 于 2018-10-22 14:39 编辑
基于MC20E的移动设备电池电压远程监测系统
技术背景:
移动发电机的油车,需要对电池的电压和发电机的电压进行监控,评估发电机的工作状况和工作时的位置定位信息.
初步的方案选型
发电机数据采集模块方案 1,单片机 采用M0518 具备6个串口,软硬件平台熟悉,外围的铁电和实时时钟,还是采用原来方案,时钟的电池采用ER14250,工作时间长. 2, 通信和定位模块,尽量采用集成的(未包含天线) 其一,采用深圳合方圆的GU620,性价比高,集成度高.
其二,安可信的A9G
3, GPS+GPRS天线 可以采用二合一天线,提高集成度
最后的方案: 首批少量测试采用的是新唐M0518, 原理图如下:
主要的原理就是一个多串口操作. 新唐此款M0具备6个串口, 正好契合本项目的运用. 1, 串口需求1: 485采集外部的485接口的变送器 2, 串口需求2: 用于接收GPS模块定时发出的GPRMC字符串 3, 串口需求3: 用于和GPRS模块进行通信,实现数据到服务器的上传.
目前的因为是低配版, 串口需求的1的功能暂时不用, 电压的采集 是通过电源变压器在本机实现,因此总共需要2个串口就可以了. 目 前新唐的串口存在一定的痛点, 应对gprs时 略显疲惫 ,因为没有DMA ,没有复杂的串口控制功能. 一般是通过定时器+接收中断来出来数据 现在改用GD32F350 就方便多了 .毕竟是M4 ,数据处理速度,主频,串口功能都有质的提升.也是本次评测的意义所在.
因为用的模块是MC20E,比较灵活 ,可以把gps定位信息输出的串口 直接跳接到模块自己的辅助串口 ,这样 定位信息,就可以从主串口读取了 .这样省下一个串口. 因为咱们的350速度足够的快.而且只有2个串口.考虑到将来的扩展性.因此采用这样的接法.这样F350就可以嵌入到原来的系统工作了,把原来的单片机串口所在的端口设置为高阻输入.
- u8 data=0,ret=0;
- u8 err=0;
- USART2_RX_STA=0;
- if(MC20_send_cmd("AT","OK","NULL","NULL",1000))err|=1<<0;//检测是否应答AT指令
- USART2_RX_STA=0;
- if(MC20_send_cmd("ATE0","OK","NULL","NULL",2000))err|=1<<1;//不回显
- USART2_RX_STA=0;
- if(MC20_send_cmd("AT+CPIN?","OK","NULL","NULL",2000))err|=1<<3; //查询SIM卡是否在位
- USART2_RX_STA=0;
-
- MC20_send_cmd("AT+QGNSSC=1\r\n","OK","+CME ERROR: Operation failed","NULL",200);
- USART2_RX_STA=0;
- data = 0;
- //查询GSM网络注册状态,确认找网成功
- while (MC20_send_cmd("AT+CREG?\r\n","\r\n+CREG: 0,1","NULL","NULL",2000)!= 1 && data < 10)
- {
- USART2_RX_STA=0;
- delay_ms(100);
- data++;
- }
- USART2_RX_STA=0;
- if (data == 10)
- {
- return ERROR; //找网不成功模块重启
- }
- /* 查询GPRS是否成功附着*/
- MC20_send_cmd("AT+CGATT?\r\n","+CGATT: 1","OK","NULL",2000);
- USART2_RX_STA=0;
- delay_ms(200);
- /* 设置模块为透明传输模式:*/
- MC20_send_cmd("AT+QIMODE=1\r\n","OK","NULL","NULL",2000);
- USART2_RX_STA=0;
- delay_ms(200);
- /* 配置前置场景: ???不懂 */
- MC20_send_cmd("AT+QIFGCNT=0\r\n","OK","NULL","NULL",2000);
- USART2_RX_STA=0;
- delay_ms(200);
- /* 通过 AT+QIOPEN= 建立TCP连接.*/
- data=MC20_send_cmd(SERVERIP,"OK","ALREADY CONNECT","CONNECT OK",200); //设置被叫号码显示
- USART2_RX_STA=0;
- ret=MC20_send_cmd("NULL","CONNECT","NULL","NULL",20); //检测第二个参数 连接成功
- USART2_RX_STA=0;
-
- /* 为防止被服务器踢开,立即发送心跳 */
- dtu_heartbeat_now();
- //delay_ms(4000);
- if (data == 1 || data == 2 || data == 3 || ret==1)
- {
- //printf("data=%d\r\n",data);
- return SUCCESS;
- }
- else
- {
- return ERROR;
- }
复制代码
以上为 MC20E的初始化和连接代码.
- //====================================================================//
- // 语法格式:int GPS_RMC_Parse(char *line, GPS_INFO *GPS)
- // 实现功能: 把gps模块的GPRMC信息解析为可识别的数据
- // 参 数:存放原始信息字符数组、存储可识别数据的结构体
- // 返 回 值:
- // 1: 解析GPRMC完毕
- // 0: 没有进行解析,或数据无效
- //====================================================================//
- int GPS_RMC_Parse(char *line, GPS_INFO *GPS)
- {
- unsigned char ch, status, tmp;
- float lati_cent_tmp, lati_second_tmp;
- float long_cent_tmp, long_second_tmp;
- float speed_tmp;
- char *buf = line; /// 得到缓存
- ch = buf[5];
- status = buf[GetComma(2, buf)];
- if (ch == 'C') /// 如果第五个字符是C,($GPRMC)
- {
- if (status == 'A') /// 如果数据有效,则分析已经定位
- {
- GPS -> NS = buf[GetComma(4, buf)];
- GPS -> EW = buf[GetComma(6, buf)];
- GPS->latitude = Get_Double_Number(&buf[GetComma(3, buf)]);
- GPS->longitude = Get_Double_Number(&buf[GetComma( 5, buf)]);
- GPS->latitude_Degree = (int)GPS->latitude / 100; /// 分离纬度
- lati_cent_tmp = (GPS->latitude - GPS->latitude_Degree * 100);
- GPS->latitude_Cent = (int)lati_cent_tmp;
- lati_second_tmp = (lati_cent_tmp - GPS->latitude_Cent) * 60;
- GPS->latitude_Second = (int)lati_second_tmp;
- GPS->longitude_Degree = (int)GPS->longitude / 100; /// 分离经度
- long_cent_tmp = (GPS->longitude - GPS->longitude_Degree * 100);
- GPS->longitude_Cent = (int)long_cent_tmp;
- long_second_tmp = (long_cent_tmp - GPS->longitude_Cent) * 60;
- GPS->longitude_Second = (int)long_second_tmp;
- speed_tmp = Get_Float_Number(&buf[GetComma(7, buf)]); /// 速度(单位:海里/时)
- GPS->speed = speed_tmp * 1.85; /// 1海里=1.85公里
- GPS->direction = Get_Float_Number(&buf[GetComma(8, buf)]); /// 角度
- GPS->D.hour = (buf[7] - '0') * 10 + (buf[8] - '0'); /// 时间
- GPS->D.minute = (buf[9] - '0') * 10 + (buf[10] - '0');
- GPS->D.second = (buf[11] - '0') * 10 + (buf[12] - '0');
- tmp = GetComma(9, buf);
- GPS->D.day = (buf[tmp + 0] - '0') * 10 + (buf[tmp + 1] - '0'); //日期
- GPS->D.month = (buf[tmp + 2] - '0') * 10 + (buf[tmp + 3] - '0');
- GPS->D.year = (buf[tmp + 4] - '0') * 10 + (buf[tmp + 5] - '0')+2000;
- UTC2BTC(&GPS->D);
- return 1;
- }
- }
- return 0;
- }
复制代码
总结: 本次测评,充分领略了GD32F350系列的不凡性能. 较之前使用的M0,是一个飞跃的感觉. 速度块,处理迅速. 尤其在解析GPS数据方面显得游刃有余. 支持9位数据模式 支持485方式操作. 极大的适应了 工控现场的需要.
|
|