单片机串口通信紊乱

     参加西门子比赛的时候用到了51单片机,涉及到多级通信,当时把卫星信号传输,红外信号发射,语音控制等几个功能全整合到51上,想通过一块芯片实现,奈何51太渣渣,串口就一个。实现三个模块之间的数据通信实在太累了。

  当时想全把波特率设置成9600,再加上延时通信,感觉在理论上可以行得通,整合了好几天,时间上的处理一直达不到理想效果,出现最普遍的现象就是程序跑飞,虽然能通信,但是不是按照人为设想的那样。但是两个模块间的数据通信在使用一个串口的情况下,程序基本正常,所以将51换成12,没办法没钱,只能拿手边东西凑。总的程序没法给,给单个程序,只要会 点C,花点时间就能整合了,一下分别是1602显示经纬度,语音模块,红外通信,想了解更多的,可以私聊,能力有限不一定帮你解决。

#include<reg52.h>
sbit BEEP=P3^6;
sbit K1=P3^5;
#define uchar unsigned char
#define uint unsigned int
uchar temp,flag; 
uint x,y;
void delay(uint z)
{
    for(x=z;x>0;x--)
	    for(y=100;y>0;y--); 
}
void send_cmd(uchar dat)
{
	SBUF=dat;			 //发送指令到SBUF
	while(!TI);			 //等待发送结束
	TI=0;
} 

void send_2dat_cmd(uchar kl)
{
     send_cmd(0xA1);
	 send_cmd(0xF1);
	 send_cmd(0x1C);
	 send_cmd(0x2F);
	 send_cmd(kl);
}
void Serial_init(void)
{
    TMOD=0x20;
    TH1=0xfd;
	TL1=0xfd;
	TR1=1;
	REN=1;
	SM0=0;
	SM1=1;
	EA=1;
	ES=1;

}
void main()
{	
	Serial_init() ;//串口寄存器的初始化设置
	K1=1;
	flag=1;
	BEEP=1;
	while(1)
	{  
	if(K1==0)
	    {	
	       while(1)
	      {
	        send_2dat_cmd(0x33);
	        delay(2000);
		    if(K1==1) break;
	      }
	    }
    if(flag==0)
	   {
	   	  BEEP=0;
		  delay(2000);
		  BEEP=1;
		  flag=1;
	   }
	}		
}  
void ser() interrupt 4
{
    RI=0;
	temp=SBUF;
	flag=0;
}

include "main.h"
#include "LCD1602.h"
#include "GPS.h"

//定义变量
unsigned char KEY_NUM = 0;
char temp,temp1,b,d;
bit Page = 0;
unsigned char xdata Display_GPGGA_Buffer[68];
unsigned char xdata Display_GPRMC_Buffer[68];
bit Flag_OV = 0;
bit Flag_Calc_GPGGA_OK = 0;
bit Flag_Calc_GPRMC_OK = 0;

//****************************************************
//主函数
//****************************************************
void main()
{
	unsigned char i = 0;
	Init_LCD1602();
	LCD1602_write_com(0x80);						//指针设置
	LCD1602_write_word("Welcome to use!");

	Delay_ms(1000);


	Uart_Init();

	while(1)
	{
		Scan_Key();
		if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'G' && RX_Buffer[6] == ',' && RX_Buffer[13] == '.')			//确定是否收到"GPGGA"这一帧数据
		{
			for( i = 0; i < 68 ; i++)
			{
				Display_GPGGA_Buffer[i] = RX_Buffer[i];	
			}
			Hour = (Display_GPGGA_Buffer[7]-0x30)*10+(Display_GPGGA_Buffer[8]-0x30)+8;//UTC时间转换到北京时间		UTC+8
																								//0x30为ASCII转换为数字
			if( Hour >= 24)				//溢出
			{
				Hour %= 24;				//获取当前Hour
				Flag_OV = 1;			//日期进位
			}
			else
			{
				Flag_OV = 0;
			}

			Min_High = Display_GPGGA_Buffer[9];
			Min_Low = Display_GPGGA_Buffer[10];
	
			Sec_High = Display_GPGGA_Buffer[11];
			Sec_Low = Display_GPGGA_Buffer[12];

			Flag_Calc_GPGGA_OK = 1;
		}

		if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'M' && RX_Buffer[52] == ',' && RX_Buffer[59] == ',')	//确定是否收到"GPRMC"这一帧数据
		{
			for( i = 0; i < 68 ; i++)
			{
				Display_GPRMC_Buffer[i] = RX_Buffer[i];	
			}

			Year_High = Display_GPRMC_Buffer[57];
			Year_Low = Display_GPRMC_Buffer[58];

			Month_High = Display_GPRMC_Buffer[55];
			Month_Low = Display_GPRMC_Buffer[56];

			Day_High = Display_GPRMC_Buffer[53];
			Day_Low = Display_GPRMC_Buffer[54];


			if(Flag_OV == 1)			//有进位
			{
				UTCDate2LocalDate();			//UTC日期转换为北京时间		
			}

			Flag_Calc_GPRMC_OK = 1;
		}

		if(Page == 0 && Flag_Calc_GPGGA_OK == 1)							//接收到GPGGA数据  按键未按下
		{
			/*LED1 = ~LED1;	*/
			Flag_Calc_GPGGA_OK = 0;
			LCD1602_write_com(0x80);			//设置指针
			LCD1602_write_data(Display_GPGGA_Buffer[28]);			//N 或者S 将变量赋予Display GPGGA BUFFER 并直接读取

			LCD1602_write_data(Display_GPGGA_Buffer[17]);			//纬度
			LCD1602_write_data(Display_GPGGA_Buffer[18]);			//纬度
			LCD1602_write_data(0xdf);								//度
			LCD1602_write_data(Display_GPGGA_Buffer[19]);			//纬度
			LCD1602_write_data(Display_GPGGA_Buffer[20]);

			LCD1602_write_data(Display_GPGGA_Buffer[21]);	 
			LCD1602_write_data(Display_GPGGA_Buffer[22]);
			LCD1602_write_data(Display_GPGGA_Buffer[23]);
			LCD1602_write_data(Display_GPGGA_Buffer[24]);
			LCD1602_write_data(Display_GPGGA_Buffer[25]);
			LCD1602_write_data(Display_GPGGA_Buffer[26]);
			LCD1602_write_word("'");			//分
	
			LCD1602_write_com(0x80+0x40);			//设置指针			
			LCD1602_write_data(Display_GPGGA_Buffer[42]);			//E 或者 W		  同上

			LCD1602_write_data(Display_GPGGA_Buffer[30]);			//经度
			LCD1602_write_data(Display_GPGGA_Buffer[31]);	
			LCD1602_write_data(Display_GPGGA_Buffer[32]);	
			LCD1602_write_data(0xdf);								
			LCD1602_write_data(Display_GPGGA_Buffer[33]);			
			LCD1602_write_data(Display_GPGGA_Buffer[34]);
			
			LCD1602_write_data(Display_GPGGA_Buffer[35]);	 //小数点
			LCD1602_write_data(Display_GPGGA_Buffer[36]);
			LCD1602_write_data(Display_GPGGA_Buffer[37]);
			LCD1602_write_data(Display_GPGGA_Buffer[38]);
			LCD1602_write_data(Display_GPGGA_Buffer[39]);
			LCD1602_write_data(Display_GPGGA_Buffer[40]);  
			LCD1602_write_word("'");	 
			
			

						
		}
		


		if(Page == 1 && Flag_Calc_GPRMC_OK == 1)
		{
			/*LED1 = ~LED1;*/
			Flag_Calc_GPRMC_OK = 0;
			LCD1602_write_com(0x80);			//设置指针
			LCD1602_write_word("20");
			LCD1602_write_data(Year_High);
			LCD1602_write_data(Year_Low);
			LCD1602_write_data('-');
	
			LCD1602_write_data(Month_High);
			LCD1602_write_data(Month_Low);
			LCD1602_write_data('-');
	
			LCD1602_write_data(Day_High);
			LCD1602_write_data(Day_Low);
			
			
			LCD1602_write_com(0x80+0x40);			//设置指针
						LCD1602_write_data(Hour/10+0x30);
			LCD1602_write_data(Hour%10+0x30);

			LCD1602_write_data(':');

			LCD1602_write_data(Min_High);
			LCD1602_write_data(Min_Low);

			LCD1602_write_data(':');
	
			LCD1602_write_data(Sec_High);
			LCD1602_write_data(Sec_Low);

			LCD1602_write_word("  ");
			
			LCD1602_write_data(Display_GPGGA_Buffer[54]);	
			LCD1602_write_data(Display_GPGGA_Buffer[55]);	
			LCD1602_write_data(Display_GPGGA_Buffer[56]);	
			LCD1602_write_data(Display_GPGGA_Buffer[57]);
			LCD1602_write_word("m");
				
		}		
	}
}
//****************************************************
//UTC日期与当地日期转换
//****************************************************
void UTCDate2LocalDate(void)
{
	Day = (Day_High - 0x30) * 10 + (Day_Low-0x30) + 1;		//日  加一
	Month = (Month_High - 0x30) * 10 + (Month_Low - 0x30);
	Year = 2000 + (Year_High - 0x30) * 10 + (Year_Low - 0x30);
	
	MaxDay = GetMaxDay(Month,Year);				//获取当月 天数 最大值
	if(Day > MaxDay)		//溢出
	{
		Day = 1;
		Month += 1;
		if(Month > 12)
		{
			Year+=1;
		}
	}

	Day_High = Day/10 + 0x30;				//转换日期值为ASCII
	Day_Low = Day%10 + 0x30;

	Month_High = Month/10 + 0x30;			//转换月份值为ASCII
	Month_Low = Month%10 + 0x30;

	Year_High = Year%100/10 + 0x30;			//转换年份值为ASCII
	Year_Low = Year%10 + 0x30;			
}

//****************************************************
//获取当月日期最大值
//****************************************************
unsigned char GetMaxDay(unsigned char Month_Value,unsigned int Year_Value)
{
	unsigned char iDays;
	switch(Month_Value)
	{
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			{
				iDays = 31;
			}
			break;
		case 2:
			{
				//2月份比较特殊,需要根据是不是闰年来判断当月是28天还29天
				iDays = IsLeapYear(Year_Value)?29:28;
			}
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			{
				iDays = 30;
			}
			break;
		default : break;
	}
	return(iDays);						
}

//****************************************************
//闰年检测
//****************************************************
bit IsLeapYear(unsigned int uiYear)
{
	return (((uiYear%4)==0)&&((uiYear%100)!=0))||((uiYear%400)==0);
}


//****************************************************
//按键扫描程序
//****************************************************
void Scan_Key()
{
	if( KEY4 == 0 )	 					//按键1扫描
	{
		Delay_ms(10);					//延时去抖
		if( KEY4 == 0 )
		{
			while(KEY4 == 0);			//等待松手
			KEY_NUM = 3;
			Page = ~Page;
			LCD1602_write_com(0X01);	//清屏
		}
	}
}
//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void Delay_ms(unsigned int n)
{
	unsigned int  i,j;
	for(i=0;i<n;i++)
		for(j=0;j<123;j++);
}

***/
#include<reg52.h>	   //包括一个52标准内核的头文件
#define uchar unsigned char     //定义一下方便后面使用
#define uint  unsigned int	    //定义一下方便后面使用
#define ulong unsigned long	    //定义一下方便后面使用		
#define COMM_BAUD_RATE  9600    //串口波特率
#define OSC_FREQ        11059200    //运行晶振:11.05926MHZ
 void Delay_Ms(int z)
{
	int   x=0 , y=0;
	for(x=110 ; x>0 ;x--)
	for(y=z; y>0;y-- );
}

/******************************************************************************
 - 功能描述: 串口1初始化
 - 注:	     设置为9600波特率
******************************************************************************/
void Serial_init(void)
{
	TMOD = 0x20;                // 设置 T1 为波特率发生器
	SCON = 0x50;                // 0101,0000 8位数据位, 无奇偶校验		
	PCON = 0x00;                //PCON=0;
	TH1=256-(OSC_FREQ/COMM_BAUD_RATE/32/12);//设置为9600波特率
	TL1=256-(OSC_FREQ/COMM_BAUD_RATE/32/12);
    TR1     = 1; 			   //定时器1打开
    REN     = 1;			   //串口1接收使能
    ES      = 1;			   //串口1中断使能
}
 
/*********************************************************************************
* 【函 数 名】: void send_cmd(uchar dat)
* 【功    能】: 串口发送数据命令 						
**********************************************************************************/
void send_cmd(uchar dat)
{
	SBUF=dat;			 //发送指令到SBUF
	while(!TI);			 //等待发送结束
	TI=0;				 //清除结束标志,以便再发送数据
}
/*********************************************************************************
* 【函 数 名】: void send_3dat_cmd(uchar cmd,uchar dat)
* 【功    能】: 除了起始和结束标志外,发三位长度的数据 
*send_3dat_cmd(0x11,0x12);	  // 播放
*send_3dat_cmd(0x12,0x11);    //暂停
* send_3dat_cmd(0x13,0x10);    // 下一曲
* send_3dat_cmd(0x14,0x17);   //上一曲
*send_3dat_cmd(0x15,0x16);	  //音量加
*send_3dat_cmd(0x16,0x15);	  //音量减
* send_3dat_cmd(0x1A,0x19);	  //快进
*send_3dat_cmd(0x1B,0x18);	    //快退
* send_3dat_cmd(0x1C,0x1F);	   //播放/暂停						
**********************************************************************************/
void send_3dat_cmd(uchar cmd,uchar jy)
{
	send_cmd(0x7E);		 //发送“开始命令”到SBUF
	send_cmd(0x03);		 //发送“命令长度”到SBUF
	send_cmd(cmd);		 //发送“命令”到SBUF
	send_cmd(jy);	     //  发送校验码到SBUF
	send_cmd(0xEF);		 //发送“结束指令”到SBUF
}
/*********************************************************************************
* 【函 数 名】: void send_4dat_cmd(uchar cmd,uchar cs,uchar jy ) 
* 【功    能】: 除了起始和结束标志外,发四位长度的数据 	
*  send_4dat_cmd(0x32,0x00,0x36 ) ;	      //设置EQ
*  send_4dat_cmd(0x34,0x01,0x31 ) ;	      //文件切换
*  send_4dat_cmd(0x35,0x01,0x30 ) ;	  //设备切换					
**********************************************************************************/
  void send_4dat_cmd(uchar cmd,uchar cs,uchar jy ) 
{
	send_cmd(0x7E);		 //发送“开始命令”到SBUF
	send_cmd(0x04);		 //发送“命令长度”到SBUF
	send_cmd(cmd);		 //发送“插播指令”到SBUF
	send_cmd(cs);		 //	发送参数 到SBUF
	send_cmd(jy);		 //  发送校验码到SBUF
	send_cmd(0xEF);		 //发送“结束指令”到SBUF
} 
/*********************************************************************************
* 【函 数 名】: void send_5dat_cmd(uchar cmd,uchar cs,uchar gq,uchar jy ) 
* 【功    能】: 除了起始和结束标志外,发四位长度的数据 
* send_5dat_cmd(0x43,0x00,0x03,0x45);      //插播功能
* send_5dat_cmd(0x44,0x01,0x06,0x46) ;    //插播指定文件夹的歌曲播放,本指令为文件夹01的第6首歌曲						
**********************************************************************************/
  void send_5dat_cmd(uchar cmd,uchar cs,uchar gq,uchar jy ) 
{
	send_cmd(0x7E);		 //发送“开始命令”到SBUF
	send_cmd(0x05);		 //发送“命令长度”到SBUF
	send_cmd(cmd);		 //发送“插播指令”到SBUF
	send_cmd(cs);		 //	发送参数 到SBUF	
	send_cmd(gq);		 //发送第几首歌曲到SBUF
	send_cmd(jy);		 //  发送校验码到SBUF
	send_cmd(0xEF);		 //发送“结束指令”到SBUF
} 								
		
void main()
 {	
    while(1)
{
	Serial_init() ;//串口寄存器的初始化设置

	 send_3dat_cmd(0x11,0x12);	  // 播放
	  Delay_Ms(3800) ;
	 send_3dat_cmd(0x13,0x10);    // 下一曲
	   Delay_Ms(3800) ;	
	
	send_cmd(0x7E);		 //发送“开始命令”到SBUF
	send_cmd(0x05);		 //发送“命令长度”到SBUF
	send_cmd(0x42);		 //发送“插播指令”到SBUF
	send_cmd(0x00);		 //	发送参数 到SBUF	
	send_cmd(0x02);		 //发送第几首歌曲到SBUF
	send_cmd(0x45);		 //  发送校验码到SBUF
	send_cmd(0xEF);		 //发送“结束指令”到SBUF
    Delay_Ms(3800) ;
	
	}
}

#include "LCD1602.h"

//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void LCD1602_delay_ms(unsigned int n)
{
	unsigned int  i,j;
	for(i=0;i<n;i++)
		for(j=0;j<123;j++);
}

//****************************************************
//写指令
//****************************************************
void LCD1602_write_com(unsigned char com) //使LCD1602使能等指令
{
	LCD1602_RS = 0;
	LCD1602_delay_ms(1);
	LCD1602_EN = 1;
	LCD1602_PORT = com;
	LCD1602_delay_ms(1);
	LCD1602_EN = 0;
}

//****************************************************
//写数据
//****************************************************
void LCD1602_write_data(unsigned char dat)
{
	LCD1602_RS = 1;
	LCD1602_delay_ms(1);	
	LCD1602_PORT = dat;
	LCD1602_EN = 1;
	LCD1602_delay_ms(1);
	LCD1602_EN = 0;
}

//****************************************************
//连续写字符
//****************************************************
void LCD1602_write_word(unsigned char *s)
{
	while(*s>0)
	{
		LCD1602_write_data(*s);
		s++;
	}
}

void Init_LCD1602()		//未接到GPS指令前 LCD1602等待状态
{
	LCD1602_EN = 0;
	LCD1602_RW = 0;						//设置为写状态
	LCD1602_write_com(0x38);			//显示模式设定
	LCD1602_write_com(0x0c);			//开关显示、光标有无设置、光标闪烁设置
	LCD1602_write_com(0x06);			//写一个字符后指针加一
	LCD1602_write_com(0x01);			//清屏指令
}

include "main.h"
#include "LCD1602.h"
#include "GPS.h"

//定义变量
unsigned char KEY_NUM = 0;
char temp,temp1,b,d;
bit Page = 0;
unsigned char xdata Display_GPGGA_Buffer[68];
unsigned char xdata Display_GPRMC_Buffer[68];
bit Flag_OV = 0;
bit Flag_Calc_GPGGA_OK = 0;
bit Flag_Calc_GPRMC_OK = 0;

//****************************************************
//主函数
//****************************************************
void main()
{
	unsigned char i = 0;
	Init_LCD1602();
	LCD1602_write_com(0x80);						//指针设置
	LCD1602_write_word("Welcome to use!");

	Delay_ms(1000);


	Uart_Init();

	while(1)
	{
		Scan_Key();
		if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'G' && RX_Buffer[6] == ',' && RX_Buffer[13] == '.')			//确定是否收到"GPGGA"这一帧数据
		{
			for( i = 0; i < 68 ; i++)
			{
				Display_GPGGA_Buffer[i] = RX_Buffer[i];	
			}
			Hour = (Display_GPGGA_Buffer[7]-0x30)*10+(Display_GPGGA_Buffer[8]-0x30)+8;//UTC时间转换到北京时间		UTC+8
																								//0x30为ASCII转换为数字
			if( Hour >= 24)				//溢出
			{
				Hour %= 24;				//获取当前Hour
				Flag_OV = 1;			//日期进位
			}
			else
			{
				Flag_OV = 0;
			}

			Min_High = Display_GPGGA_Buffer[9];
			Min_Low = Display_GPGGA_Buffer[10];
	
			Sec_High = Display_GPGGA_Buffer[11];
			Sec_Low = Display_GPGGA_Buffer[12];

			Flag_Calc_GPGGA_OK = 1;
		}

		if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'M' && RX_Buffer[52] == ',' && RX_Buffer[59] == ',')	//确定是否收到"GPRMC"这一帧数据
		{
			for( i = 0; i < 68 ; i++)
			{
				Display_GPRMC_Buffer[i] = RX_Buffer[i];	
			}

			Year_High = Display_GPRMC_Buffer[57];
			Year_Low = Display_GPRMC_Buffer[58];

			Month_High = Display_GPRMC_Buffer[55];
			Month_Low = Display_GPRMC_Buffer[56];

			Day_High = Display_GPRMC_Buffer[53];
			Day_Low = Display_GPRMC_Buffer[54];


			if(Flag_OV == 1)			//有进位
			{
				UTCDate2LocalDate();			//UTC日期转换为北京时间		
			}

			Flag_Calc_GPRMC_OK = 1;
		}

		if(Page == 0 && Flag_Calc_GPGGA_OK == 1)							//接收到GPGGA数据  按键未按下
		{
			/*LED1 = ~LED1;	*/
			Flag_Calc_GPGGA_OK = 0;
			LCD1602_write_com(0x80);			//设置指针
			LCD1602_write_data(Display_GPGGA_Buffer[28]);			//N 或者S 将变量赋予Display GPGGA BUFFER 并直接读取

			LCD1602_write_data(Display_GPGGA_Buffer[17]);			//纬度
			LCD1602_write_data(Display_GPGGA_Buffer[18]);			//纬度
			LCD1602_write_data(0xdf);								//度
			LCD1602_write_data(Display_GPGGA_Buffer[19]);			//纬度
			LCD1602_write_data(Display_GPGGA_Buffer[20]);

			LCD1602_write_data(Display_GPGGA_Buffer[21]);	 
			LCD1602_write_data(Display_GPGGA_Buffer[22]);
			LCD1602_write_data(Display_GPGGA_Buffer[23]);
			LCD1602_write_data(Display_GPGGA_Buffer[24]);
			LCD1602_write_data(Display_GPGGA_Buffer[25]);
			LCD1602_write_data(Display_GPGGA_Buffer[26]);
			LCD1602_write_word("'");			//分
	
			LCD1602_write_com(0x80+0x40);			//设置指针			
			LCD1602_write_data(Display_GPGGA_Buffer[42]);			//E 或者 W		  同上

			LCD1602_write_data(Display_GPGGA_Buffer[30]);			//经度
			LCD1602_write_data(Display_GPGGA_Buffer[31]);	
			LCD1602_write_data(Display_GPGGA_Buffer[32]);	
			LCD1602_write_data(0xdf);								
			LCD1602_write_data(Display_GPGGA_Buffer[33]);			
			LCD1602_write_data(Display_GPGGA_Buffer[34]);
			
			LCD1602_write_data(Display_GPGGA_Buffer[35]);	 //小数点
			LCD1602_write_data(Display_GPGGA_Buffer[36]);
			LCD1602_write_data(Display_GPGGA_Buffer[37]);
			LCD1602_write_data(Display_GPGGA_Buffer[38]);
			LCD1602_write_data(Display_GPGGA_Buffer[39]);
			LCD1602_write_data(Display_GPGGA_Buffer[40]);  
			LCD1602_write_word("'");	 
			
			

						
		}
		


		if(Page == 1 && Flag_Calc_GPRMC_OK == 1)
		{
			/*LED1 = ~LED1;*/
			Flag_Calc_GPRMC_OK = 0;
			LCD1602_write_com(0x80);			//设置指针
			LCD1602_write_word("20");
			LCD1602_write_data(Year_High);
			LCD1602_write_data(Year_Low);
			LCD1602_write_data('-');
	
			LCD1602_write_data(Month_High);
			LCD1602_write_data(Month_Low);
			LCD1602_write_data('-');
	
			LCD1602_write_data(Day_High);
			LCD1602_write_data(Day_Low);
			
			
			LCD1602_write_com(0x80+0x40);			//设置指针
						LCD1602_write_data(Hour/10+0x30);
			LCD1602_write_data(Hour%10+0x30);

			LCD1602_write_data(':');

			LCD1602_write_data(Min_High);
			LCD1602_write_data(Min_Low);

			LCD1602_write_data(':');
	
			LCD1602_write_data(Sec_High);
			LCD1602_write_data(Sec_Low);

			LCD1602_write_word("  ");
			
			LCD1602_write_data(Display_GPGGA_Buffer[54]);	
			LCD1602_write_data(Display_GPGGA_Buffer[55]);	
			LCD1602_write_data(Display_GPGGA_Buffer[56]);	
			LCD1602_write_data(Display_GPGGA_Buffer[57]);
			LCD1602_write_word("m");
				
		}		
	}
}
//****************************************************
//UTC日期与当地日期转换
//****************************************************
void UTCDate2LocalDate(void)
{
	Day = (Day_High - 0x30) * 10 + (Day_Low-0x30) + 1;		//日  加一
	Month = (Month_High - 0x30) * 10 + (Month_Low - 0x30);
	Year = 2000 + (Year_High - 0x30) * 10 + (Year_Low - 0x30);
	
	MaxDay = GetMaxDay(Month,Year);				//获取当月 天数 最大值
	if(Day > MaxDay)		//溢出
	{
		Day = 1;
		Month += 1;
		if(Month > 12)
		{
			Year+=1;
		}
	}

	Day_High = Day/10 + 0x30;				//转换日期值为ASCII
	Day_Low = Day%10 + 0x30;

	Month_High = Month/10 + 0x30;			//转换月份值为ASCII
	Month_Low = Month%10 + 0x30;

	Year_High = Year%100/10 + 0x30;			//转换年份值为ASCII
	Year_Low = Year%10 + 0x30;			
}

//****************************************************
//获取当月日期最大值
//****************************************************
unsigned char GetMaxDay(unsigned char Month_Value,unsigned int Year_Value)
{
	unsigned char iDays;
	switch(Month_Value)
	{
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			{
				iDays = 31;
			}
			break;
		case 2:
			{
				//2月份比较特殊,需要根据是不是闰年来判断当月是28天还29天
				iDays = IsLeapYear(Year_Value)?29:28;
			}
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			{
				iDays = 30;
			}
			break;
		default : break;
	}
	return(iDays);						
}

//****************************************************
//闰年检测
//****************************************************
bit IsLeapYear(unsigned int uiYear)
{
	return (((uiYear%4)==0)&&((uiYear%100)!=0))||((uiYear%400)==0);
}


//****************************************************
//按键扫描程序
//****************************************************
void Scan_Key()
{
	if( KEY4 == 0 )	 					//按键1扫描
	{
		Delay_ms(10);					//延时去抖
		if( KEY4 == 0 )
		{
			while(KEY4 == 0);			//等待松手
			KEY_NUM = 3;
			Page = ~Page;
			LCD1602_write_com(0X01);	//清屏
		}
	}
}
//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void Delay_ms(unsigned int n)
{
	unsigned int  i,j;
	for(i=0;i<n;i++)
		for(j=0;j<123;j++);
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值