基於stm32f10x系列單片機demo程序修改

配置串口

void USART1_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	/* 使能串口時鐘*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); 

	/* USART1的IO腳配置*/    
  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);   //³õʼ»¯GPIOA
	
	/* USART1 工作模式配置*/
	USART_InitStructure.USART_BaudRate = 115200;	//波特率
	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_Cmd(USART1, ENABLE);// USART1使能
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);    // 使能串口中斷
	
	NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;  //中斷配置
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStructure);
}

NVIC_InitTypeDef 函數接口需要的頭文件 #include "misc.h"

串口數據發送(發送到串口助手的數據,我們一般在單片機接收到串口數據後不知道數據是否正確,需要將接收到的數據顯示出來可以用這個函數來實現)

void UART1SendByte(USART_TypeDef* USARTx,unsigned char SendData)
{	   
		USART_SendData(USARTx,SendData);
		while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);	    
}

串口中斷方式進行數據的接收

void USART1_IRQHandler(void) 
{		
	uint8_t rec = 0;
    char str[15];
	char str1[15];
	char str2[5];

	uint16_t  x=0;
	uint16_t  x1 = 0;
		
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{
		USART_ClearITPendingBit(USART1,USART_IT_RXNE); 
		rec = USART_ReceiveData(USART1);
        //頭判斷
		if(rec == '$')
		{
			gps_count =0;
			count = 1;
			for(i=0;i<RECEIVE_BUF_LEN;i++)
			{
				ReceiveBuff[i] = 0;
				sendBuff[i] = 0;
			}
			ReceiveBuff[0] = rec;
			gps_state = f_start;
		}
		else if(gps_state == f_start)
		{
			//判斷接收的數據個數
			if(rec == ',')
			{
				sendBuff[gps_count++] = count;
						
			}
			if(rec == '*' && gps_count > 15)
			{
				gps_state = f_end;

			}
			ReceiveBuff[count++] = rec;
		}
		else if(gps_state == f_end)
		{
			gps_state = f_finished;
			//UART1SendByte(2);
			for(i=0; i< count; i++)
			{
				UART1SendByte(USART1, ReceiveBuff[i]);
			}
			// ½âÎö
			for( i =sendBuff[8]+1; i < sendBuff[9]; i++)
			{
				str[x++] = ReceiveBuff[i];
			}
			for( i =sendBuff[9]+1; i < sendBuff[10]; i++)
			{
				str1[x1++] = ReceiveBuff[i];
			}

					
			if(second_get == 1)
			{
				x_latitude = atof(str)*10;
				y_longtitude = atof(str1)*10;
				second_get = 2;
			}
			else if(second_get == 2)
			{
				 x1_latitude = atof(str)*10;
				 y1_longtitude = atof(str1)*10;
				three_get = 1;
			}
					
			if(three_get == 1)
			{
				float result1 = x_latitude - x1_latitude;
				float result2 = y_longtitude -  y1_longtitude;
				if((abs(result1) > 5.0)||(abs(result2) > 5.0))
				{
					LED1( ON );
				}
				else if((abs(result1) < 5.0)&&(abs(result2) < 5.0))
				{
					//UART1SendByte(USART1, 2);
					LED1( OFF );
				}
				x_latitude = x1_latitude;
				y_longtitude =  y1_longtitude;
				second_get = 2;
			}
		 }				
	}

	if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET)
	{   

		USART_ClearFlag(USART1,USART_FLAG_TC); 
		USART_ReceiveData(USART1); 
	}  
}

中斷函數中主要實現邏輯,接收串口發送的字節rec,對rec進行判斷是否為符合要求的數據頭,如果符合,將接收串口數據保存到ReceiveBuff中,這裏沒有對校驗位進行判斷,通過對‘"," 和結束符來判定數據是否接收完成,接收完成後在if(gps_state == f_end)中對最終的數據進行解析,

for(i=0; i< count; i++)
{
	UART1SendByte(USART1, ReceiveBuff[i]);
}

將接收的完整數據打印出來

for( i =sendBuff[8]+1; i < sendBuff[9]; i++)
{
	str[x++] = ReceiveBuff[i];
}

sendBuff中存儲的是數據中的每一個", "的位置,通過這個我們能找到需要的字符串數據保存到str數組中

if(second_get == 1)
{
	x_latitude = atof(str)*10;
	y_longtitude = atof(str1)*10;  //字符轉float
	second_get = 2;
}
else if(second_get == 2)
{
	x1_latitude = atof(str)*10;
	y1_longtitude = atof(str1)*10;
	three_get = 1;
}

if(three_get == 1)
{
	float result1 = x_latitude - x1_latitude;
	float result2 = y_longtitude -  y1_longtitude;
	if((abs(result1) > 5.0)||(abs(result2) > 5.0))
	{
		LED1( ON );
	}
	else if((abs(result1) < 5.0)&&(abs(result2) < 5.0))
	{
			//UART1SendByte(USART1, 2);
		LED1( OFF );
	}
	x_latitude = x1_latitude;
	y_longtitude =  y1_longtitude;
	second_get = 2;
}

這個裏面的作用是取接收到的相鄰的兩組數據進行比較判斷來確定我們當前是否需要進行其他的操作

atof函數使用的頭文件#include <stdlib.h>

sqrt函數使用的頭文件 #include <math.h>

附 :使用的GPS模塊的通信協議

CUBeMX 配置STM32F103c8 串口2_數據