本帖最后由 caizhiwei 于 2015-7-27 09:16 编辑
实现步骤如下:
1.初始化usart3:
- #define UART3_TX_BUF_SIZE 1*128
- #define UART3_RX_BUF_SIZE 512
复制代码- unsigned char Uart1TxBuf[UART1_TX_BUF_SIZE]={0}; /* com1_rf发送缓冲区 */
- unsigned char Uart1RxBuf[UART1_RX_BUF_SIZE]={0}; /* com1_rf接收缓冲区 */
- unsigned char Uart3TxBuf[UART3_TX_BUF_SIZE]={0}; /* com3_发送缓冲区 */
- unsigned char Uart3RxBuf[UART3_RX_BUF_SIZE]={0}; /* com3_接收缓冲区 */
- bool Uart1RxBuf_full =false;
- bool Uart3RxBuf_full =false;
复制代码
- void USART3_Init(u32 Baudrate)
- {
- USART_InitTypeDef USART_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
-
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
-
- //这里USART3映射到PC10和PC11是部分映射,没有映射时时端口是PB10和PB11,
- //完全映射时(GPIO_FullRemap_USART3)是PD8和PD9 (但是64引脚没有引出PD8和PD9)
- GPIO_PinRemapConfig(GPIO_PartialRemap_USART3,ENABLE);// I/O口重映射开启.
-
- /*Remap Pc10 USART3.TX推挽输出*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
-
- /*remap Pc11 USART3.RX浮空输入 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
-
- USART_InitStructure.USART_BaudRate = Baudrate;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART3, &USART_InitStructure);
-
- USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//接收中断使能
- USART_Cmd(USART3, ENABLE);
- }
复制代码 2.写带fifo缓冲区的串口中断:
- void USART3_IRQHandler(void)
- {
- static u16 RxCount;
-
- if(USART_GetFlagStatus(USART3,USART_IT_RXNE)==SET)
- {
- USART_ClearITPendingBit(USART3,USART_IT_RXNE);//清除中断标志
-
- Uart3RxBuf[RxCount] = USART_ReceiveData(USART3);
-
- RxCount++; // must not change it !
-
- if (RxCount >= UART3_RX_BUF_SIZE) //
- {
- RxCount=0;
- Uart3RxBuf_full = true;
- }
- }
- }
复制代码 3.从缓冲区中提取有效数据:- /*
- *********************************************************************************************************
- * 函 数 名: gps_pro
- * 功能说明: 从串口缓冲区中解析出GPS数据包。插入到主程序中执行即可。分析结果存放在全局变量 myGPS
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void gps_pro(void)
- {
- uint16_t i=0;
-
- char *p,*pt;
- if (Uart3RxBuf_full)
- {
- USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //禁止接收中断
-
- Uart3RxBuf_full = false;
-
- //LCD_print_0816Num(3, 5, 1 ,0);//debug
- p = (char *)Uart3RxBuf;
- pt = strchr(p, '
- 4. 解析语义:
- [code]void GPS_Data_update()
- {
-
- char * start_p = GpsBuf;
- char *pos_p;
- /*
- int strncmp(const char *string1, const char *string2, size_t count);
- 比较字符串string1和string2大小,只比较前面count个字符. 比较过程中,
- 任何一个字符串的长度小于count, 则count将被较短的字符串的长度取代.
- 此时如果两串前面的字符都相等, 则较短的串要小.
- 返回值< 0, 表示string1的子串小于string2的子串;
- 返回值为0, 表示string1的子串等于string2的子串;
- 返回值> 0, 表示string1的子串大于string2的子串.
- */
- if(strncmp(GpsBuf, "$GPGGA",6)==0)
- {
- //ShowStringPos (0, 4,"$GPGGA"); //bebug
-
- /*字段1 :UTC 时间,hhmmss.sss,时分秒格式 */
- pos_p = strchr(start_p, ','); //查找字符串s中首次出现字符c的位置,剥离c前面的信息
- if (pos_p == 0)
- {
- return;//2个逗号连在一起的情况
- }
- pos_p++; // p+1后指向UTC时间
- myGPS.Hour = StrToIntFix(pos_p, 2);
- pos_p += 2;
- myGPS.Min = StrToIntFix(pos_p, 2);
- pos_p += 2;
- myGPS.Sec = StrToIntFix(pos_p, 2);
- //微秒忽略
-
- /* 字段2 :纬度ddmm.mmmm,度分格式(前导位数不足则补0)*/
- pos_p = strchr(pos_p, ','); //接着刚才指针位置找下一个逗号
- if (pos_p == 0)
- {
- return;
- }
- pos_p++;
-
- myGPS.WeiDu_Du = StrToIntFix(pos_p, 2);
- pos_p += 2;
- myGPS.WeiDu_Fen = StrToIntFix(pos_p, 2) * 10000;
- pos_p += 3;
- myGPS.WeiDu_Fen += StrToIntFix(pos_p, 4);
-
- /* 字段3 :N(北纬)或S(南纬) */
- pos_p = strchr(pos_p, ',');
- if (pos_p == 0)
- {
- return;
- }
- pos_p++;
- if (*pos_p == 'S')
- {
- myGPS.NS = 'S';
- }
- else if (*pos_p == 'N')
- {
- myGPS.NS = 'N';
- }
- else
- {
- return;
- }
-
- /* 字段4 :经度dddmm.mmmm,度分格式(前导位数不足则补0) */
- pos_p = strchr(pos_p, ',');
- if (pos_p == 0)
- {
- return;
- }
- pos_p++;
- myGPS.JingDu_Du = StrToIntFix(pos_p, 3);
- pos_p += 3;
- myGPS.JingDu_Fen = StrToIntFix(pos_p, 2) * 10000;
- pos_p += 3;
- myGPS.JingDu_Fen += StrToIntFix(pos_p, 4);
-
- /* 字段5 :E(东经)或W(西经) */
- pos_p = strchr(pos_p, ',');
- if (pos_p == 0)
- {
- return;
- }
- pos_p++;
- if (*pos_p == 'E')
- {
- myGPS.EW = 'E';
- }
- else if (*pos_p == 'W')
- {
- myGPS.EW = 'W';
- }
-
- /* 字段6 :GPS状态,0=未定位,1=非差分定位,2=差分定位,3=无效PPS,6=正在估算 */
- pos_p = strchr(pos_p, ',');
- if (pos_p == 0)
- {
- return;
- }
- pos_p++;
- if ((*pos_p == '1') || (*pos_p == '2'))
- {
- myGPS.PositionOk = 1;
- }
- else
- {
- myGPS.PositionOk = 0;
- }
-
- /* 字段7:正在使用的卫星数量(00 - 12)(前导位数不足则补0) */
- pos_p = strchr(pos_p, ',');
- if (pos_p == 0)
- {
- return;
- }
- pos_p++;
- myGPS.ViewNumber = StrToInt(pos_p);
-
- //p += 2;
-
- /* 字段8:HDOP水平精度因子(0.5 - 99.9) */
- pos_p = strchr(pos_p, ',');
- if (pos_p == 0)
- {
- return;
- }
- pos_p++;
- myGPS.HDOP = StrToInt(pos_p);
-
- /* 字段9:海拔高度(-9999.9 - 99999.9) */
- pos_p= strchr(pos_p, ',');
- if (pos_p == 0)
- {
- return;
- }
- pos_p++;
- myGPS.Altitude = StrToInt(pos_p);
- //后面的,39.5,M,-15.5,M,6.8,0000*68 丢弃
-
-
- }
-
- //if(strncmp(GpsBuf, "$GPRMC",6)==0)
- //{
- //ShowStringPos (0, 4,"$GPRMC"); //bebug
- //}
-
- }
复制代码
5.运行:
在RTOS中用一个或两个任务执行 gps_pro(); GPS_Data_update();
在main函数中用while(1){gps_pro(); GPS_Data_update();}
BSP.zip
(10.35 KB, 下载次数: 336)
|
å¾
上面是我试的代码,感觉挺好用……