这里记录下SYTM32驱动一个模块的程序
主要是因为,官方给的例程是HAL库的,这里我改成标准库的形式写一遍:
文章提供测试代码讲解、完整工程下载、测试效果图
目录
串口1中断:
1
void USART1_IRQHandler(void) // 串口1中断服务程序 { u8 Res; if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // 接收中断 { Res = USART_ReceiveData(USART1); // 读取接收到的数据 if (Res == '$') point1 = 0; USART_RX_BUF[point1++] = Res; if (USART_RX_BUF[0] == '$' && USART_RX_BUF[4] == 'M' && USART_RX_BUF[5] == 'C' ) { if (Res == '\n') { memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length); // 清空 memcpy(Save_Data.GPS_Buffer, USART_RX_BUF, point1); // 保存数据 Save_Data.isGetData = true; point1 = 0; memset(USART_RX_BUF, 0, USART_REC_LEN); // 清空 } if (point1 >= USART_REC_LEN) point1 = USART_REC_LEN; } } // 清除中断标志 USART_ClearITPendingBit(USART1, USART_IT_RXNE); }
数据处理:
这里为了我自己的显示问题,我将数据完整性校验去除了,使得打印没有解算出的数据为0:
void ParseGpsBuffer_G60(void) { char *subString; char *subStringNext; char i = 0; if (Save_Data.isGetData) { Save_Data.isGetData = false; //UsartPrintf(USART1, "**************\r\n"); //UsartPrintf(USART1, "%s",Save_Data.GPS_Buffer); sprintf(buf,"t10.txt=\"%s\"",Save_Data.GPS_Buffer); UsartPrintf(USART1, "%s",buf); for(i=0; i<3; i++) { USART_SendData(USART1,0xff); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } for (i = 0 ; i <= 6 ; i++) { if (i == 0) { if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL){} //ErrorLog(1); //解析错误 } else { subString++; if ((subStringNext = strstr(subString, ",")) != NULL) { char usefullBuffer[2]; switch(i) { case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break; //获取UTC时间 case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break; //获取UTC时间 case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break; //获取纬度信息 case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break; //获取N/S case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break; //获取经度信息 case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break; //获取E/W default:break; } subString = subStringNext; Save_Data.isParseData = true; Save_Data.isUsefull = true; // if(usefullBuffer[0] == 'A') // Save_Data.isUsefull = true; // else if(usefullBuffer[0] == 'V') // Save_Data.isUsefull = false; } else { //ErrorLog(2); //解析错误 } } } } } // GPS数据转化单位为度。 double Convert_to_degrees(char* data) { double temp_data = atof(data); int degree = (int)(temp_data / 100); double f_degree = (temp_data / 100.0 - degree)*100/60.0; double result = degree + f_degree; return result; } void PrintGpsBuffer_G60(void) { double f_latitude = 0.0; double f_longitude = 0.0; int i =0; if (Save_Data.isParseData) { Save_Data.isParseData = false; sprintf(buf,"t2.txt=\"%s\"",Save_Data.UTCTime); UsartPrintf(USART1, "%s",buf); for(i=0; i<3; i++) { USART_SendData(USART1,0xff); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } if(Save_Data.isUsefull) { f_latitude = Convert_to_degrees(Save_Data.latitude); sprintf(buf,"t12.txt=\"%lf%s\"",f_latitude,Save_Data.N_S); UsartPrintf(USART1, "%s",buf); for(i=0; i<3; i++) { USART_SendData(USART1,0xff); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } sprintf(buf,"t4.txt=\"%s\"",Save_Data.N_S); UsartPrintf(USART1, "%s",buf); for(i=0; i<3; i++) { USART_SendData(USART1,0xff); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } f_longitude = Convert_to_degrees(Save_Data.longitude); f_latitude = Convert_to_degrees(Save_Data.latitude); sprintf(buf,"t6.txt=\"%lf%s\"", f_longitude, Save_Data.E_W); UsartPrintf(USART1, "%s",buf); for(i=0; i<3; i++) { USART_SendData(USART1,0xff); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } sprintf(buf,"t8.txt=\"%s\"",Save_Data.E_W); UsartPrintf(USART1, "%s",buf); for(i=0; i<3; i++) { USART_SendData(USART1,0xff); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } Save_Data.isUsefull = false; } else { UsartPrintf(USART1, "GPS DATA is not usefull!\r\n"); } } }
主函数调用:
按键程序:
uint8_t KEY_Scan(uint8_t mode)
{
static uint8_t key_up=1;//按键按松开标志
uint8_t KEY1,KEY2,KEY3,KEY4;
KEY1=1;KEY2=1;KEY3=1;KEY4=1;
if( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_12) == 0 ){KEY1=0;}
if( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_13) == 0 ){KEY2=0;}
if( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_11) == 0 ){KEY3=0;}
if( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_10) == 0 ){KEY4=0;}
if(mode)key_up=1; //支持连按
if(key_up&&(KEY2==0||KEY1==0||KEY3==0||KEY4==0))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY2==0) return 2;
else if(KEY1==0)return 1;
else if(KEY3==0)return 3;
else if(KEY4==0)return 4;
}
else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)key_up=1;
return 0;// 无按键按下
}
void KEY2_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 1. 使能GPIOD时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
// 2. 配置PD10-PD13为输入模式(带上拉)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // 输入模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 内部上拉(按键另一端接地时有效)
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* 如果按键另一端接VCC,需要改为下拉:
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; */
}
测试效果视频:
这个程序不理想,会让系统变卡,尤其是拿到室外接收到卫星数据之后,大量浮点数的运算让按键切屏都不是很流畅
STM32F407ZGT6笔记15:G60_GPS北斗导航模