参加西门子比赛的时候用到了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++);
}