我使用STM32F103RBT6最小开发板系统,用管脚PA9,PA10连接北斗导航模块,串口RX1TX1接电脑,用SSCOM33串口调试助手观察接收到的信息,库函数使用正点原子的V1.3最小系统
下面是几个程序代码:
[mw_shl_code=c,true]#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
#include "my.h"
int main(void)
{
int i;
char gps_name[6]={48},gps_date[100]={48};
SystemInit();
delay_init();
NVIC_Configuration();
uart_init(9600);
// TIM3_PWM_Init(59999,23);
delay_ms(10);
while(1)
{
if(USART_ReceiveData(USART1)=='$')
{
for(i=0;i<6;i++)
{
delay_ms(1); //1ms才能接收一个字符
gps_name=USART_ReceiveData(USART1);
}
if(gps_name[5]=='C')
{
for(i=0;gps_date!='\n';i++)
{
delay_ms(1);
gps_date=USART_ReceiveData(USART1);
}
gps_date='\n';
for(i=0;i<6;i++)
{
delay_ms(1);
printf("%c",gps_name);
}
for(i=0;gps_date!='\n';i++)
{
delay_ms(1);
printf("%c",gps_date);
}
printf("\n");
}
}
}
}
[/mw_shl_code]
[mw_shl_code=c,true]void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
USART_DeInit(USART1); //复位串口1
//USART1_TX PA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
//USART1_RX PA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
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(USART1, &USART_InitStructure); //初始化串口
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
USART_Cmd(USART1, ENABLE); //使能串口
}
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
// USART_SendData(USART1,Res);
if((USART_RX_STA&0x80)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0a)USART_RX_STA|=0x80;
else
{
USART_RX_BUF[USART_RX_STA&0X3F]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
#endif[/mw_shl_code]
我用数组gps_name接收格式说明,$符号为固定开头,数组gps_date接收对应格式的GPS信息
北斗模块1s接收一次数据,一次数据有8行,下图是接收到的GPS信息
我需要提取的是GNRMC这一句GPS信息进行处理,可是输出结果却是
063435.000是时间,A是数据有效性判断位,2519.0761,N,11024.8420,E是我需要提取的信息,但是因为结果中存在很多重复和位移,导致数据无法正确的提取,上一张图显示接收到的数据格式是没有问题的,在只输出$GNRMC这6个字符的时候还会遇到GNNMCC、GRNMMC、$$GNMC等情况
求大神指导一下,我接触STM32才半个月,这个情况网上搜不到啊
猜测是因为传输数率不对导致存入数组时产生错误,但是想不到解决方法,手头上没别的板子测试
使用KEIl软件没有办法逐步仿真,因为GPS信息是被动接收,如果不是1MS接收一次,数组中存入的就是你仿真时点击“下一步”的那一刻对应的数据
|