在网上分别找到了gps串口接stm32以及jy60倾角传感器的程序,将他们整合在一起后,实际运行的时候串口助手上只有gps的数据。
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)部分,结果依然没有传感器的数据
图上数据为void parseGpsBuffer(void)的数据
同时输出gps和传感器的数据。
你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答
本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。
因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。