void GPS_REV_TASK(void *p_arg) { uint8_t data_temp; (void)p_arg; USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); comClearRxFifo(COM2); GpsRevCnt = 0; while(1) { BSP_OS_TimeDlyMs(10000); comClearRxFifo(COM2); GpsRevCnt = 0; USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); while(GpsRevCnt < GPS_MAX_REV_SIZE) { while(comGetChar(COM2, &data_temp)) { GpsRevBuf[GpsRevCnt++] = data_temp; } BSP_OS_TimeDlyMs(10); } USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); GPS_Analysis(&GpsCurInfo, GpsRevBuf); } }
/* ********************************************************************************************************* * 函 数 名: fgetc * 功能说明: 重定义getc函数,这样可以使用getchar函数从串口1输入数据 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ int fgetc(FILE *f) { #if 0 /* 从串口接收FIFO中取1个数据, 只有取到数据才返回 */ uint8_t ucData; while(comGetChar(COM1, &ucData) == 0); return ucData; #else /* 等待串口1输入数据 */ while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(USART1); #endif }
/* ********************************************************************************************************* * 函 数 名: gps_pro * 功能说明: 轮询GPS数据包。插入到主程序中执行即可。分析结果存放在全局变量 g_tGPS * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void gps_pro(void) { uint8_t ucData; static uint8_t ucGpsHead = 0; static uint8_t ucaGpsBuf[512]; static uint16_t usGpsPos = 0; /* 从 GPS模块串口读取1个字节 comGetChar() 函数由 bsp_uart_fifo.c 实现 */ while (1) { if (comGetChar(COM2, &ucData)) { #ifdef DEBUG_GPS_TO_COM1 /* 将收到的GPS模块数据按原样 打印到COM1 口,便于跟踪调试 */ comSendChar(COM1, ucData); #endif if (ucGpsHead == 0) { if (ucData == '$') { ucGpsHead = 1; usGpsPos = 0; } } else { if (usGpsPos < sizeof(ucaGpsBuf)) { ucaGpsBuf[usGpsPos++] = ucData; if ((ucData == '\r') || (ucData == '\n')) { Analyze0183(ucaGpsBuf, usGpsPos-1); ucGpsHead = 0; g_tGPS.UartOk = 1; /* 接收到正确的命令 */ } } else { ucGpsHead = 0; } } continue; /* 可能还有数据,继续分析 */ } break; /* 分析完毕,退出函数 */ } }
/* ********************************************************************************************************* * 函 数 名: SIM800_ReadResponse * 功能说明: 读取SIM800返回应答字符串。该函数根据字符间超时判断结束。 本函数需要紧跟AT命令发送函数。 * 形 参: _pBuf : 存放模块返回的完整字符串 * _usBufSize : 缓冲区最大长度 * _usTimeOut : 命令执行超时,0表示一直等待. >0 表示超时时间,单位1ms * 返 回 值: 0 表示错误(超时) > 0 表示应答的数据长度 ********************************************************************************************************* */ uint16_t SIM800_ReadResponse(char *_pBuf, uint16_t _usBufSize, uint16_t _usTimeOut) { uint8_t ucData; uint16_t pos = 0; uint8_t ret; uint8_t status = 0; /* 接收状态 */ /* _usTimeOut == 0 表示无限等待 */ if (_usTimeOut > 0) { bsp_StartTimer(SIM800_TMR_ID, _usTimeOut); /* 使用软件定时器作为超时控制 */ } while (1) { bsp_Idle(); /* CPU空闲执行的操作, 见 bsp.c 和 bsp.h 文件 */ if (status == 2) /* 正在接收有效应答阶段,通过字符间超时判断数据接收完毕 */ { if (bsp_CheckTimer(SIM800_TMR_ID)) { _pBuf[pos] = 0; /* 结尾加0, 便于函数调用者识别字符串结束 */ ret = pos; /* 成功。 返回数据长度 */ break; } } else { if (_usTimeOut > 0) { if (bsp_CheckTimer(SIM800_TMR_ID)) { ret = 0; /* 超时 */ break; } } } if (comGetChar(COM_SIM800, &ucData)) { SIM800_PrintRxData(ucData); /* 将接收到数据打印到调试串口1 */ switch (status) { case 0: /* 首字符 */ if (ucData == AT_CR) /* 如果首字符是回车,表示 AT命令不会显 */ { _pBuf[pos++] = ucData; /* 保存接收到的数据 */ status = 2; /* 认为收到模块应答结果 */ } else /* 首字符是 A 表示 AT命令回显 */ { status = 1; /* 这是主机发送的AT命令字符串,不保存应答数据,直到遇到 CR字符 */ } break; case 1: /* AT命令回显阶段, 不保存数据. 继续等待 */ if (ucData == AT_CR) { status = 2; } break; case 2: /* 开始接收模块应答结果 */ /* 只要收到模块的应答字符,则采用字符间超时判断结束,此时命令总超时不起作用 */ bsp_StartTimer(SIM800_TMR_ID, 5); if (pos < _usBufSize - 1) { _pBuf[pos++] = ucData; /* 保存接收到的数据 */ } break; } } } return ret; }
/* ********************************************************************************************************* * 函 数 名: SIM800_WaitResponse * 功能说明: 等待SIM800返回指定的应答字符串. 比如等待 OK * 形 参: _pAckStr : 应答的字符串, 长度不得超过255 * _usTimeOut : 命令执行超时,0表示一直等待. >0表示超时时间,单位1ms * 返 回 值: 1 表示成功 0 表示失败 ********************************************************************************************************* */ uint8_t SIM800_WaitResponse(char *_pAckStr, uint16_t _usTimeOut) { uint8_t ucData; uint8_t ucRxBuf[256]; uint16_t pos = 0; uint32_t len; uint8_t ret; len = strlen(_pAckStr); if (len > 255) { return 0; } /* _usTimeOut == 0 表示无限等待 */ if (_usTimeOut > 0) { bsp_StartTimer(SIM800_TMR_ID, _usTimeOut); /* 使用软件定时器3,作为超时控制 */ } while (1) { bsp_Idle(); /* CPU空闲执行的操作, 见 bsp.c 和 bsp.h 文件 */ if (_usTimeOut > 0) { if (bsp_CheckTimer(SIM800_TMR_ID)) { ret = 0; /* 超时 */ break; } } if (comGetChar(COM_SIM800, &ucData)) { SIM800_PrintRxData(ucData); /* 将接收到数据打印到调试串口1 */ if (ucData == '\n') { if (pos > 0) /* 第2次收到回车换行 */ { if (memcmp(ucRxBuf, _pAckStr, len) == 0) { ret = 1; /* 收到指定的应答数据,返回成功 */ break; } else { pos = 0; } } else { pos = 0; } } else { if (pos < sizeof(ucRxBuf)) { /* 只保存可见字符 */ if (ucData >= ' ') { ucRxBuf[pos++] = ucData; } } } } } return ret; }