gps和传感器同时串口接入stm32之后,电脑上只有gps的数据

问题遇到的现象和发生背景

在网上分别找到了gps串口接stm32以及jy60倾角传感器的程序,将他们整合在一起后,实际运行的时候串口助手上只有gps的数据。

img

问题相关代码,请勿粘贴截图
main.c
#include <string.h>
#include <stdio.h>
#include "Main.h"
#include "UART1.h"
#include "UART2.h"
#include "delay.h"
#include "JY61.h"
#include "DIO.h"
#include "stm32f10x.h"
#include "usart.h"
#include "string.h"
#include "gps.h"




/************************************************
 ALIENTEK 战舰STM32F103开发板实验0
 工程模板
 注意,这是手册中的新建工程章节使用的main文件 
 技术支持:www.openedv.com
 淘宝店铺:http://eboard.taobao.com 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/
static u8  fac_us=0;//us延时倍乘数
static u16 fac_ms=0;//ms延时倍乘数
extern short int point1;
extern const short int USART3_MAX_RECV_LEN;
extern char USAR3_RX_BUF[200];
extern const short int GPS_Buffer_Length;
short int point1;
extern struct Data Save_Data;

void My_USART3_Init(void){
    GPIO_InitTypeDef GPIO_InitStrue;
    USART_InitTypeDef USART3_InitStrue;
    NVIC_InitTypeDef NVIC_InitStrue;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    
    GPIO_InitStrue.GPIO_Mode = GPIO_Mode_AF_PP;//推挽输出(发射)
    GPIO_InitStrue.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStrue.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOB, &GPIO_InitStrue);
    
    GPIO_InitStrue.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入(接收)
    GPIO_InitStrue.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStrue.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOB, &GPIO_InitStrue);
    
    USART3_InitStrue.USART_BaudRate = 9600;
    USART3_InitStrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART3_InitStrue.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
    USART3_InitStrue.USART_Parity = USART_Parity_No;//奇偶校验位
    USART3_InitStrue.USART_StopBits = USART_StopBits_1;//停止位
    USART3_InitStrue.USART_WordLength = USART_WordLength_8b;//数据位
    USART_Init(USART3, &USART3_InitStrue);
    
    USART_Cmd(USART3, ENABLE);
    
    
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//打开接收中断,当接收到数据时开启中断
    NVIC_InitStrue.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStrue.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStrue.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStrue);
}
void Initial_UART1(unsigned long baudrate)
{
     GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure; 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);    

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &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(USART1, &USART_InitStructure); 
    USART_ITConfig(USART1, USART_IT_TXE, DISABLE);  
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);        
    USART_ClearFlag(USART1,USART_FLAG_TC);
    USART_Cmd(USART1, ENABLE);
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


struct SAcc         stcAcc;
struct SGyro         stcGyro;
struct SAngle     stcAngle;


//用串口2给JY模块发送指令
void sendcmd(char cmd[])
{
    char i;
    for(i=0;i<3;i++)
        UART2_Put_Char(cmd[i]);
}

//CopeSerialData为串口2中断调用函数,串口每收到一个数据,调用一次这个函数。
void CopeSerial2Data(unsigned char ucData)
{
    static unsigned char ucRxBuffer[250];
    static unsigned char ucRxCnt = 0;    
    
    LED_REVERSE();                    //接收到数据,LED灯闪烁一下
    ucRxBuffer[ucRxCnt++]=ucData;    //将收到的数据存入缓冲区中
    if (ucRxBuffer[0]!=0x55) //数据头不对,则重新开始寻找0x55数据头
    {
        ucRxCnt=0;
        return;
    }
    if (ucRxCnt<11) {return;}//数据不满11个,则返回
    else
    {
        switch(ucRxBuffer[1])//判断数据是哪种数据,然后将其拷贝到对应的结构体中,有些数据包需要通过上位机打开对应的输出后,才能接收到这个数据包的数据
        {
            //memcpy为编译器自带的内存拷贝函数,需引用"string.h",将接收缓冲区的字符拷贝到数据结构体里面,从而实现数据的解析。
            case 0x51:    memcpy(&stcAcc,&ucRxBuffer[2],8);break;
            case 0x52:    memcpy(&stcGyro,&ucRxBuffer[2],8);break;
            case 0x53:    memcpy(&stcAngle,&ucRxBuffer[2],8);break;

        }
        ucRxCnt=0;//清空缓存区
    }
}

void CopeSerial1Data(unsigned char ucData)
{    
    UART2_Put_Char(ucData);//转发串口1收到的数据给串口2(JY模块)
}
void SysTick_init(u8 SYSCLK,u16 nms)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    SysTick->VAL =0x00;           //清空计数器
    SysTick->LOAD = nms*SYSCLK*125;//72MHz,最大1864ms
    SysTick->CTRL=3;//bit2清空,选择外部时钟  HCLK/8
    fac_us=SYSCLK/8;            
    fac_ms=(u16)fac_us*1000;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void USART3_IRQHandler(void){
    u8 res;
    if(USART_GetITStatus(USART3, USART_IT_RXNE)){
        res = USART_ReceiveData(USART3);
        if(res == '$'){
            point1 = 0;
        }
        USAR3_RX_BUF[point1++] = res;
        if(USAR3_RX_BUF[0] == '$' && USAR3_RX_BUF[4] == 'M' && USAR3_RX_BUF[5] == 'C'){
            if(res == '\n'){
                memcpy(Save_Data.GPS_Buffer, USAR3_RX_BUF, point1);
                Save_Data.isGetData = TRUE;
                point1 = 0;
                memset(USAR3_RX_BUF, 0, USART3_MAX_RECV_LEN);//清空数组
                
                parseGpsBuffer();//解析数据
                printfGpsBuffer();//打印数据
            }
        }
        if(point1 >= USART3_MAX_RECV_LEN)
        {
            point1 = USART3_MAX_RECV_LEN;
        }
    }
}
 
int main(void)
{          
    unsigned char i = 0;
    SysTick_init(72,10);//设置时钟频率
    Initial_UART1(9600);//接PC的串口
    Initial_UART2(9600);//接JY61模块的串口
    
        uart_init(9600);
    printf("L80-R GPS Module test...\r\n");
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    My_USART3_Init();
    printf("GPE Enable ok.\r\n");
    LED_ON();
    delay_ms(1000);delay_ms(1000);//等等JY61初始化完成
    


    //功能现象,10秒钟左右会进行一次加速度校准,Z轴角度归零,XYZ角度会缓慢回到0度状态
    while(1)
    {            
        delay_ms(1000);
        i++;
        if(i>10)
        {
            i = 0;
            printf("正在进行加速度校准\r\n");
            sendcmd(ACCCMD);//等待模块内部自动校准好,模块内部会自动计算需要一定的时间
            printf("加速度校准完成\r\n");
            delay_ms(100);
            printf("进行Z轴角度清零\r\n");
            sendcmd(YAWCMD);
            printf("Z轴角度清零完成\r\n");
        }
        printf("-----------------------------------\r\n");
        //输出加速度
        //串口接受到的数据已经拷贝到对应的结构体的变量中了,根据说明书的协议,以加速度为例 stcAcc.a[0]/32768*16就是X轴的加速度,
        printf("Acc:%.3f %.3f %.3f\r\n",(float)stcAcc.a[0]/32768*16,(float)stcAcc.a[1]/32768*16,(float)stcAcc.a[2]/32768*16);
        delay_ms(10);
        //输出角速度
        printf("Gyro:%.3f %.3f %.3f\r\n",(float)stcGyro.w[0]/32768*2000,(float)stcGyro.w[1]/32768*2000,(float)stcGyro.w[2]/32768*2000);
        delay_ms(10);
        //输出角度
        printf("Angle:%.3f %.3f %.3f\r\n",(float)stcAngle.Angle[0]/32768*180,(float)stcAngle.Angle[1]/32768*180,(float)stcAngle.Angle[2]/32768*180);
        delay_ms(10);//等待传输完成
    }//主循环
}


gps.c
#include "gps.h"
#include "usart.h"
#include "string.h"
#include "stdlib.h"


const short int USART3_MAX_RECV_LEN = 200;
char USAR3_RX_BUF[USART3_MAX_RECV_LEN];
const short int GPS_Buffer_Length = 200;
struct Data Save_Data;

void parseGpsBuffer(void){
    char *subString;
    char *subStringNext;
    int i = 0;
    if(Save_Data.isGetData)
    {
        Save_Data.isGetData = FALSE;
        printf("*****************\r\n");
        printf("%s",Save_Data.GPS_Buffer);
        
        for(i = 0; i <= 6; i++){
            if(i == 0){
                if((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
                    printf("解析错误");
                }
                else{
                    subString++;//到达逗号的下一位
                    if((subStringNext = strstr(subString, ",")) != NULL)
                    {
                        char usefullBuffer[2];
                        switch(i){
                            case 1: 
                                //利用subStringNext和subString的首地址相减来确定为指针开辟空间的大小,以防指针不合法。
                                Save_Data.UTCTime = (char *)malloc((subStringNext - subString)*sizeof(char));
                                memcpy(Save_Data.UTCTime, subString, subStringNext - subString); 
                                break;
                            case 2: memcpy(usefullBuffer, subString, subStringNext - subString); break;
                            case 3: Save_Data.latitude = (char *)malloc((subStringNext - subString)*sizeof(char));
                                memcpy(Save_Data.latitude, subString, subStringNext - subString); 
                                break;
                            case 4: Save_Data.N_S = (char *)malloc((subStringNext - subString)*sizeof(char));
                                memcpy(Save_Data.N_S, subString, subStringNext - subString); 
                                break;
                            case 5: Save_Data.longitude = (char *)malloc((subStringNext - subString)*sizeof(char));
                                memcpy(Save_Data.longitude, subString, subStringNext - subString); 
                                break;
                            case 6: Save_Data.E_W = (char *)malloc((subStringNext - subString)*sizeof(char));
                                memcpy(Save_Data.E_W, subString, subStringNext - subString); 
                                break;
                            default: break;
                        }
                        subString = subStringNext;
                        Save_Data.isParseData = TRUE;
                        if(usefullBuffer[0] == 'A')
                            Save_Data.isUsefull = TRUE;
                        else if(usefullBuffer[0] == 'V')
                            Save_Data.isUsefull = FALSE;
                    }
                    else{
                            printf("解析错误2");
                    }
                }
            }
        }
    
}


void printfGpsBuffer(void){
    if(Save_Data.isParseData){
        Save_Data.isParseData = FALSE;
        printf("Save_Data.UTCTime = %s\r\n", Save_Data.UTCTime);//串口一打印到电脑上
        free(Save_Data.UTCTime);//释放空间
        
        if(Save_Data.isUsefull){
            Save_Data.isUsefull = FALSE;
            printf("Save_Data.latitude = %s\r\n", Save_Data.latitude);
            free(Save_Data.latitude);
            printf("Save_Data.N_S = %s\r\n", Save_Data.N_S);
            free(Save_Data.N_S);
            printf("Save_Data.longitude = %s\r\n", Save_Data.longitude);
            free(Save_Data.longitude);
            printf("Save_Data.E_W = %s\r\n", Save_Data.E_W);
            free(Save_Data.E_W);
        }
        else
        {
            printf("GPS DATA is not usefull!\r\n");
        }
    }
}

dio.c
#include "DIO.h"

#define LED_GPIO_CLK   RCC_APB2Periph_GPIOA 
#define LED_PORT          GPIOA
#define LED_PIN        GPIO_Pin_15

void DIO_Initial(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin,GPIOMode_TypeDef GPIO_Mode,GPIOSpeed_TypeDef GPIO_Speed)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOF, ENABLE);  
    
    GPIO_StructInit(&GPIO_InitStructure); 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed;
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin;
    GPIO_Init(GPIOx, &GPIO_InitStructure);    
}    

void IOSleep()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_APB2Periph_GPIOF, ENABLE);  
    
    GPIO_StructInit(&GPIO_InitStructure); 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_All;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_Init(GPIOF, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
    
    //GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_All;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    WriteDO(GPIOB,GPIO_Pin_8,0);//EN
    WriteDO(GPIOB,GPIO_Pin_6,1);//??BRTS*
    
}    

void WriteDO(GPIO_TypeDef* GPIOx,uint32_t GPIO_Pin,unsigned char ucData)
{
    if (ucData>0)
        GPIOx->BSRR = GPIO_Pin;
    else
        GPIOx->BRR = GPIO_Pin;
}
unsigned char ReadDI(GPIO_TypeDef * GPIOx,uint32_t GPIO_Pin)
{
    return (GPIOx->IDR&GPIO_Pin)==GPIO_Pin;
}

/****************************************************
函数功能:LED初始化
输入参数:无
输出参数:无
备    注:调用此函数前,需要在LED.h修改宏定义LED引脚
****************************************************/
unsigned char ucLEDInitial=0;
void LED_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
    RCC_AHBPeriphClockCmd(LED_GPIO_CLK, ENABLE);
    DIO_Initial(LED_PORT,LED_PIN,GPIO_Mode_Out_PP,GPIO_Speed_10MHz);
    ucLEDInitial=1;
}

/****************************************************
函数功能:LED开
输入参数:无
输出参数:无
****************************************************/
void LED_ON(void)
{
    if (ucLEDInitial==0) LED_Init();
    GPIO_SetBits(LED_PORT, LED_PIN);
    
}

/****************************************************
函数功能:LED关
输入参数:无
输出参数:无
****************************************************/
void LED_OFF(void)
{
    if (ucLEDInitial==0) LED_Init();
    GPIO_ResetBits(LED_PORT, LED_PIN);
}

void LED_REVERSE(void)
{
    if (ucLEDInitial==0) LED_Init();
    if (GPIO_ReadOutputDataBit(LED_PORT, LED_PIN))    
        GPIO_ResetBits(LED_PORT, LED_PIN);
    else
        GPIO_SetBits(LED_PORT, LED_PIN);
}




运行结果及报错内容
我的解答思路和尝试过的方法

最开始我以为是程序一直处于gps相关程序的循环中,我尝试屏蔽掉gps的输出部分即void printfGpsBuffer(void)部分,结果依然没有传感器的数据

img

图上数据为void parseGpsBuffer(void)的数据

我想要达到的结果

同时输出gps和传感器的数据。

你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。


因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。