由于STM32需要同时处理三个串口的实时通讯消息,使用串口接收中断接收GPS信息非常占单片机运行资源,所以采用串口数据接收空闲中断和串口dma接收互相结合的办法节省资源
//DMA初始化函数
void GPS_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能MDA1时钟
/* DMA channel2 configuration */
DMA_DeInit(GPS_DMA_Channel); //指定DMA通道
DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)(USART2_BASE+0X4);//设置DMA外设地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)usart2.rx_buff; //设置DMA内存地址,ADC转换结果直接放入该地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设为设置为数据传输的来源
DMA_InitStructure.DMA_BufferSize =GPS_RX_BUFF_SIZE; //DMA缓冲区设置为200;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设地址不增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 内存地址自增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// 外设数据单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据单位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// DMA模式,一次或者循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;// 优先级:中
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 禁止内存到内存的传输
DMA_Init(GPS_DMA_Channel, &DMA_InitStructure); // 配置DMA通道
// DMA_ITConfig(GPS_DMA_Channel,DMA_IT_TE, ENABLE); 删除否则会进入中断
/* Enable DMA channel1 */
DMA_Cmd(GPS_DMA_Channel, ENABLE); //使能DMA通道
}
//经纬度和时间解析函数
void GPS_DATA_Analysis(void)
{
u8 data_pos=0,i=0,count=0,f=0,czu=0,cxu=0;
u16 w_zu=0,w_xu=0,j_zu=0,j_xu=0;
u32 g_time=0;
data_pos=star_pos();
if(data_pos<170)//有效数据
{
for(i=0;i<51;i++)
{
usart2.tx_buff[i]=usart2.rx_buff[data_pos+i];
count++;
if(usart2.tx_buff[i]=='\n')//帧结束符号
i=51;
//调试代码
// USART_SendData(USART3,usart2.tx_buff[i]);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
}
if(count>40)//有效数据开始解析
{
com_pos(2);
gps_data_p-=2;//定位到纬度的最后一个字节
w_zu=0;
w_xu=0;
j_zu=0;
j_xu=0;
while(*gps_data_p!=',')
{
if(*gps_data_p!='.')
{
if((*gps_data_p>='0')&&(*gps_data_p<='9'))
{
if(f==1)//整数部分
{
w_zu=w_zu+(*gps_data_p-'0')*NMEA_Pow(10,czu);
czu++;
}
else//小数部分
{
w_xu=w_xu+(*gps_data_p-'0')*NMEA_Pow(10,cxu);
cxu++;
}
}
else
break;//出现非法字符退出循环
}
else
f=1;
gps_data_p--;
}
com_pos(4);
gps_data_p-=2;//定位到纬度的最后一个字节
czu=0;
cxu=0;
f=0;
while(*gps_data_p!=',')
{
if(*gps_data_p!='.')
{
if((*gps_data_p>='0')&&(*gps_data_p<='9'))
{
if(f==1)//整数部分
{
j_zu=j_zu+(*gps_data_p-'0')*NMEA_Pow(10,czu);
czu++;
}
else//小数部分
{
j_xu=j_xu+(*gps_data_p-'0')*NMEA_Pow(10,cxu);
cxu++;
}
}
else
break;//出现非法字符退出循环
}
else
f=1;
gps_data_p--;
}
com_pos(6);
gps_data_p-=6;//定位到时间的最后一个字节
czu=0;
g_time=0;
while(*gps_data_p!=',')
{
if((*gps_data_p>='0')&&(*gps_data_p<='9'))
{
g_time=g_time+(*gps_data_p-'0')*NMEA_Pow(10,czu);
czu++;
}
else
break;//出现非法字符退出循环
gps_data_p--;
}
GPS_info.w_zu=w_zu;
GPS_info.w_xu=w_xu;
GPS_info.j_zu=j_zu;
GPS_info.j_xu=j_xu;
GPS_info.gps_time=g_time;
Fault_Clr(4);
GPS_info.time_out=0;
// 调试代码
// USART_SendData(USART3, (GPS_info.gps_time/100000)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3, (GPS_info.gps_time/10000)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3, (GPS_info.gps_time/1000)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.gps_time/100)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.gps_time/10)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.gps_time/1)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,';');
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3, (GPS_info.w_zu/1000)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.w_zu/100)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.w_zu/10)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.w_zu/1)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,'.');
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
//
// USART_SendData(USART3, (GPS_info.w_xu/1000)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.w_xu/100)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.w_xu/10)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.w_xu/1)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
//
// USART_SendData(USART3,':');
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
//
// USART_SendData(USART3, (GPS_info.j_zu/10000)+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3, (GPS_info.j_zu/1000)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.j_zu/100)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.j_zu/10)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.j_zu/1)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,'.');
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
//
// USART_SendData(USART3, (GPS_info.j_xu/1000)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.j_xu/100)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.j_xu/10)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
// USART_SendData(USART3,(GPS_info.j_xu/1)%10+0x30);
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
}
}
else//没有有效数据
{
GPS_info.w_zu=0;
GPS_info.w_xu=0;
GPS_info.j_zu=0;
GPS_info.j_xu=0;
Fault_Set(4);
}
}
//gps dma接收串口空闲中断处理函数
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2,USART_IT_IDLE)!=RESET)
{
GPS_info.time_out=0;
if(usart2.rx_ok==0)
{
GPS_DMA_Data_Receive();
usart2.rx_ok=1;
}
USART_ReceiveData(USART2);//读取数据时相当于清除中断标志
}
}