我要发布第一篇程序文档

这是我的第一篇关于51单片机的程序,用红外遥控设置,lcd1602实现显示时间。并且通过遥控按键可以实现播放音乐、调整时间、设置闹钟的功能。时钟芯片用DS1302实现具体的时间。

源代码:(如要转载,请注明出处)

/********************************
maker:  LeeCo-zhu
Version:  1-0-0
time date: 2012.12.12
copyright: copyright  is owned by zhulike so you if you want to 
           copy ,please send email to 1094520627@qq.com 。 the C code counldn't
           be used for commeral without the permission of author ,it is  allowed
           that copy the code in personal.       
********************************/




#include<reg51.h>
#include<intrins.h>
#include<demo6.h>




/******************************************************************/
/*                    DS1302函数声明                                    */
/******************************************************************/
void Write_Ds1302_byte(unsigned char idata temp); 
void Write_Ds1302( unsigned char idata address,unsigned char idata dat );
unsigned char Read_Ds1302 ( unsigned char address );
void Read_RTC(void);//read RTC 
void Set_RTC(void); //set RTC 
void InitTIMER0(void);//inital timer0
/******************************************************************/
/*                   写一个字节                                   */
/******************************************************************/
void Write_Ds1302_Byte(unsigned  char temp) 
{
 unsigned char idata i;
 for (i=0;i<8;i++)     //循环8次 写入数据
  { 
   SCK=0;
     SDA=temp&0x01;     //每次传输低字节 
     temp>>=1;   //右移一位
     SCK=1; //上升沿写入
   }
}
/******************************************************************/
/*                  写入DS1302                                    */
/******************************************************************/
void Write_Ds1302( unsigned char address,unsigned char dat )     
{
  RST=0;
_nop_();
  SCK=0;
_nop_();
  RST=1;
    _nop_();                    //启动
  Write_Ds1302_Byte(address);//发送地址
  Write_Ds1302_Byte(dat);//发送数据
  RST=0;              //恢复
}
/******************************************************************/
/*                   读出DS1302数据                               */
/******************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
{
  unsigned char i,temp=0x00;
  RST=0;
_nop_();
_nop_();
  SCK=0;
_nop_();
_nop_();
  RST=1; //启动数据传输
_nop_();
_nop_();
  Write_Ds1302_Byte(address);//写入读命令
  for (i=0;i<8;i++) //循环8次 读取数据
  {
  if(SDA)
  temp|=0x80; //每次传输低字节
SCK=0; //下降沿读取数据
temp>>=1; //右移一位
_nop_();
  _nop_();
  _nop_();
  SCK=1;

  RST=0;
_nop_();           //以下为DS1302复位的稳定时间
  _nop_();
RST=0;
SCK=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCK=1;
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
return (temp);//返回
}
/******************************************************************/
/*                   读时钟数据                                   */
/******************************************************************/
void Read_RTC(void)        //读取 日历
{
 unsigned char i,*p;
 p=read_rtc_address;    //地址传递
 for(i=0;i<7;i++)    //分7次读取 秒分时日月周年
 {
  l_tmpdate[i]=Read_Ds1302(*p);
  p++;
 }
}
/******************************************************************/
/*                  设定时钟数据                                  */
/******************************************************************/
void Set_RTC(void)    //设定 日历
{
unsigned char i,*p,tmp;
for(i=0;i<7;i++){   //BCD处理就是按二进制的缩写成十六进制的形式
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
l_tmpdate[i]=l_tmpdate[i]+tmp*16;
}  
  Write_Ds1302(0x8E,0X00); //未写保护

  p=write_rtc_address;//传地址
  for(i=0;i<7;i++)//7次写入 秒分时日月周年
  {
 Write_Ds1302(*p,l_tmpdate[i]);
  p++;  
}
Write_Ds1302(0x8E,0x80);
}
/******************************************************************/
/*                  function: key_scan     延时函数                                   */
/******************************************************************/
void dlms(unsigned int n)  
{ int i,j;
for(i=0;i<n;i++)
for(j=0;j<85;j++);


}
/*
void keyscan()
{
if((key1==0)||(key2==0)||(key3==0))// 检测有按键按下执行下面语句
{
set=1;
while(set)
{
if(key1==0)  //调时按键
{  
dlms(200);
while(!key1);    //松手检测


l_tmpdate[2]=((l_tmpdate[2]+1)>>4)*10 + ((l_tmpdate[2]+1)&0x0f);  //时加1


if(l_tmpdate[2]>23)l_tmpdate[2]=0;  //判断
l_tmpdate[2]=l_tmpdate[2]%10+l_tmpdate[2]/10*16;  //转十进制

Write_Ds1302(0x8E,0X00); //开写保护
Write_Ds1302(0x84,l_tmpdate[2]);  //写时寄存器   此处写调时寄存器就行,以免把所以寄存器全写上按键加时出乱
Write_Ds1302(0x8E,0x80); //关写保护


set=0;     //退出
}


if(key2==0)   //调分按键
{  
dlms(200);
while(!key2);    //松手检测


l_tmpdate[1]=((l_tmpdate[1]+1)>>4)*10 + ((l_tmpdate[1]+1)&0x0f);   //分加1


if(l_tmpdate[1]>59)l_tmpdate[1]=0;  //判断
l_tmpdate[1]=l_tmpdate[1]%10+l_tmpdate[1]/10*16;   //转十进制


Write_Ds1302(0x8E,0X00); //开写保护
Write_Ds1302(0x82,l_tmpdate[1]);  //写分寄存器
Write_Ds1302(0x8E,0x80);  //关写保护


set=0;
}


if(key3==0) //调秒按键
{  
dlms(200);
while(!key3);     //松手检测


l_tmpdate[0]=((l_tmpdate[0]+1)>>4)*10 + ((l_tmpdate[0]+1)&0x0f);  //秒加1


if(l_tmpdate[0]>59)l_tmpdate[0]=0;  //判断
l_tmpdate[0]=l_tmpdate[0]%10+l_tmpdate[0]/10*16;   //转十进制


Write_Ds1302(0x8E,0X00);  //开写保护
Write_Ds1302(0x80,l_tmpdate[0]);  //写秒寄存器
Write_Ds1302(0x8E,0x80);   //关写保护


set=0;
}



}
}   
} */
void  keyscan()
{
   uchar idata i=0;
   if(key1==0||key2==0)
   {
      lcd_wcmd(0x01,0);
 delay(2); //延时消抖
 if(key1==0)
 {
   a4=1;  //时间设置标志,用红外遥控复位
key1=1;
lcd_pos(0);
while(tab6[i] != '\0')
{
 lcd_wcmd(tab6[i],1);i++;
}
while(a4) //设置时间
{
  a1=(a1>>4)*10 + (a1&0x0f);  //时加1
  if(a1>23) a1=0;  //判断
  a1=a1%10+(a1/10*16);  //转十进制


  a3=(a3>>4)*10 + (a3&0x0f);  //秒加1
           if(l_tmpdate[0]>59) l_tmpdate[0]=0; //判断
  a3=a3%10+a3/10*16;   //转十进制


  a2=(a2>>4)*10 + (a2&0x0f);   //分加1
           if(a2>59) a2=0; //判断
  a2=a2%10+a2/10*16;   //转十进制


   lcd_pos(0x47);
lcd_wcmd(a1/16+0x30,1);delayMs(200);
lcd_wcmd((a1&0x0f)+0x30,1);delayMs(200);
   lcd_wcmd(0x3a,1);delayMs(200);
lcd_wcmd(a2/16+0x30,1);delayMs(200);
lcd_wcmd((a2&0x0f)+0x30,1);delayMs(200);
   lcd_wcmd(0x3a,1);delayMs(200);
lcd_wcmd(a3/16+0x30,1);delayMs(200);
lcd_wcmd((a3&0x0f)+0x30,1);delayMs(200);
Write_Ds1302(0x8E,0X00);  //开写保护
Write_Ds1302(0x80,a3);  //写秒寄存器
Write_Ds1302(0x82,a2);  //写分寄存器
Write_Ds1302(0x84,a1);  //写时寄存器
Write_Ds1302(0x8E,0x80);   //关写保护
}
  }
i=0;
if(key2==0) //设置闹钟
{
  a5=1;
  key2=1;
  lcd_pos(0);
  while(tab5[i] != '\0')
  {
   lcd_wcmd(tab5[i],1);i++;
  }
  while(a5)
  {
     lcd_pos(0x44);
              lcd_wcmd(NOW[0]/10+0x30,1);delayMs(200);
 lcd_wcmd(NOW[0]%10+0x30,1);delayMs(200);
 lcd_wcmd(0x3a,1);delayMs(200);
 lcd_wcmd(NOW[1]/10+0x30,1);delayMs(200);
 lcd_wcmd(NOW[1]%10+0x30,1);delayMs(200);
 lcd_wcmd(0x3a,1);delayMs(200);
 lcd_wcmd(NOW[2]/10+0x30,1);delayMs(200);
 lcd_wcmd(NOW[2]%10+0x30,1);delayMs(200);


  }lcd_wcmd(0x01,0);
}
 


   }
}
/************************************************************************/
/*  闹钟函数 */
/************************************************************************/
void naozhong()
{


if(l_tmpdisplay[0]==NOW[0]/10&&l_tmpdisplay[1]==NOW[0]%10
&&l_tmpdisplay[3]==NOW[1]/10&&l_tmpdisplay[4]==NOW[1]%10
&&l_tmpdisplay[6]==NOW[2]/10&&l_tmpdisplay[7]==NOW[2]%10)// 设置NOW的时间与时钟时间显示比较
{
_Speak=0;   //开蜂鸣器
dlms(2000);
_Speak=1;
}
}

     




/******************************
function:make noise now!
******************************/
unsigned char code SONG[] ={      //祝你平安 
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,
0x10,0x20,0x80,0x26,0x20,0x30,0x20, 0x30,0x20,
0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,
0x20,0x20,0x20,0x1c,0x20, 0x20,0x80,0x2b,0x20,
0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,
0x80,0x26,0x20, 0x30,0x20,0x30,0x20,0x39,0x10,
0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,
0x20, 0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,
0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10, 0x2b,
0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,
0x2b,0x20,0x2b,0x40,0x40,0x20, 0x20,0x10,0x20,
0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,
0x18,0x20,0x26,0x20, 0x20,0x20,0x20,0x40,0x26,
0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,
0x20,0x20, 0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,
0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10, 
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,
0x10,0x26,0x10,0x2b,0x10,0x2b,0x80, 0x18,0x20,
0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,
0x10,0x2b,0x20,0x30,0x20, 0x30,0x20,0x1c,0x20,
0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,
0x10,0x30,0x20, 0x39,0x20,0x26,0x10,0x2b,0x10,
0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,
0x10, 0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,
0x00,    //路边的野华不要采 
0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,
0x20,0x10,0x1C,0x10,0x18,0x40,0x1C, 0x20,0x20,
0x20,0x1C,0x20,0x18,0x20,0x20,0x80,0xFF,0x20,
0x30,0x1C,0x10,0x18,0x20, 0x15,0x20,0x1C,0x20,
0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,
0x20,0x20,0x20, 0x30,0x80,0xFF,0x20,0x20,0x1C,
0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,
0x30, 0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,
0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30, 0x20,
0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,
0x20,0x1C,0x20,0x20,0x20,0x26, 0x40,0x20,0x20,
0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,
0x30,0x1C,0x10,0x20, 0x10,0x1C,0x10,0x20,0x20,
0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,
0x15,0x1F, 0x05,0x20,0x10,0x1C,0x10,0x20,0x20,
0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20, 
0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,
0x20,0x20,0x26,0x40,0x20,0x20,0x2B, 0x20,
0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,
0x1C,0x10,0x18,0x40,0x1C,0x20,0x20, 0x20,
0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,
0x13,0x40,0x18,0x80,0x00,  };


void Time0_Init() 

  TMOD = 0x01;  
  IE   = 0x82;
 // ET0=1;  
  TH0  = 0xD8;  
  TL0  = 0xEF;  //12MZ晶振,10ms 
}
void Time0_Int() interrupt 1 using 1
{  
   TH0 = 0xD8;  
   TL0 = 0xEF;  
   Count++;   //长度加1 
}  
/*------------------------------------------------- 
功能:1MS延时子程序 
-------------------------------------------------*/ 
void Delay_xMs(unsigned int x) 
{     unsigned int i,j;     
      for( i =0;i < x;i++ )     
      {     for( j =0;j<3;j++ );     
      } 
}
/*------------------------------------------------- 
function:this code are the major of play_song()
-------------------------------------------------*/ 
void Play_Song(unsigned char i) 
{  unsigned char idata Temp1,Temp2;  
   unsigned int idata Addr;  
   Count = 0;      //中断计数器清0  
   Addr = i * 217;  
   while(1)  
   {   Temp1 = SONG[Addr++];      
       if ( Temp1 == 0xFF )      //休止符      
       {    TR0 = 0;       
            Delay_xMs(100);      
       } 
       else if ( Temp1 == 0x00 )   //歌曲结束符      
       {  return;   }      
       else      
       {      Temp2 = SONG[Addr++];       
            TR0 = 1;      
        while(1)      
       {        _Speak = ~_Speak;        
           Delay_xMs(Temp1);        
        if ( Temp2 == Count )        
        {   Count = 0; break;     }       
        }      
       }  
      } 
}


void  sound()
{
   uchar idata i,j=1;
   set=1;//音乐播放标志置位
   lcd_wcmd(0x01,0);
   lcd_pos(0x03);//设置显示位置为第一行的第1个字符
   i = 0;
   while(tab2[ i ] != '\0')
   {   //show字符"play music"
lcd_wcmd(tab2[ i ],1);
i++;
delayMs(20);//control两字之间显示speed
   }
   Time0_Init();   //定时器0中断初始化  
   while(j--)  
   {   Play_Song(0);  //播放 
       TR0=0;
 // return ; 
   }
   lcd_wcmd(0x01,0);
}
/********************************
function:delay function
**********************************/
void delayMs(uchar idata i)
{  
   while(i--);
}


/*******************************
function:DS18B20initation
****************************/
void init_ds18b20()
{
   DQ=1;
   _nop_();
   DQ=0;
   delayMs(80);   //delay >= 81*6 us
   _nop_();
   DQ=1;  //release bus
   delayMs(14); //delay >= 10*6 usmake sure that idle state enough time
  // if(DQ==1);  //you'd better not to use it for test
   _nop_();
   _nop_();
   delayMs(25);
   DQ=1;   //release bus
}


/*************************************************
function:read & write on ds18b20 with 8 bits once
output: null when write ,u will be return when read
input:u will be return when write ,null when read
**************************************************/
uchar  rdByte()
{
  unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
DQ = 0;
u >>= 1;
DQ = 1;
if(DQ==1)
u |= 0x80;
delayMs (2);
_nop_();
}
return(u);


}


void wrByte(uchar idata bs)
{
  unsigned char idata i;
for (i=0;i<8;i++)
{
DQ = 0;
_nop_();
DQ=bs&0x01;
delayMs(3);   //delay 45 uS //5
_nop_();
_nop_();
DQ=1; //release bus
bs >>= 1;
}
}






/**********************************
 function:convert the temperature
 output:wendu
 input:null
**********************************/


uint read_temperature(void)
{ uchar idata sb1,sb2;
  uchar i;
  init_ds18b20();
  wrByte(0xcc); 
  wrByte(0x44);
 
  
  init_ds18b20();
  wrByte(0xcc);
  wrByte(0xbe); 
  
  sb1=rdByte();
  sb2=rdByte();
  init_ds18b20();
 // wendu=((sb2*256)+sb1)*0.0625;
 // wendu = wendu*10+0.5; //dai xiao shu dian
  //获取温度整数部分(高字节中的低3位与低字节中的高4位,无符号)
  wendu=((( sb1 & 0xf0) >> 4 )|((sb2 & 0x07)<<4)); 
 // wendu = tt*10+0.5;               //放大十倍
  i=(sb1 & 0x0f);
  decimal=dis[i]+0x30;
  return wendu;
}
/*******************************************
function:showing the temperature on lcd1602
*******************************************/
void wendu_dis()
{
   uchar idata i,j,z;
   read_temperature(); 
   //lcd_pos(0x10);
   lcd_wcmd(0x80+11,0);  
   i=wendu/100+0x30; //百位
   j=wendu%100/10+0x30; //十位
   z=wendu%10+0x30; //个位
   if(i==0x30)
     lcd_wcmd(0x20,1); //显示空字符
   else
     {lcd_wcmd(i,1);}
   if(j==0x30)
     lcd_wcmd(0x20,1); //显示空字符
   else
     {lcd_wcmd(j,1);}
   lcd_wcmd(z,1);
   lcd_wcmd(0x2e,1);   //小数点显示
   lcd_wcmd(decimal,1);
   lcd_wcmd(0xdf,1);
}
/*********************************
function:initation of lcd1602
********************************/


void lcd_init()
{   //LCD Initialization setting
lcd_wcmd(0x38,0);    //16*2show,5*7dot martix,8位data
delayMs(2);
lcd_wcmd(0x38,0);    //16*2showing,5*7dot martix,8位data
delayMs(2);
lcd_wcmd(0x38,0);    //ensure that initialization sucessful
delayMs(2);
lcd_wcmd(0x0c,0);    //cursor setting,do not show cursor
delayMs(2);
lcd_wcmd(0x06,0);    //移动cursor
delayMs(2);
lcd_wcmd(0x01,0);    //clear LCD的显示内容
delayMs(2);
}
/*****************************************
function:test the busy flag 
         about lcd1602 which
busy flag is P0^7 
*****************************************/
bit lcd_bz()
{                         
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EP = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0 & 0x80);//检测P0最高位是否为1
LCD_EP = 0;
return result;//返回侧忙结果
}
/*******************************
   写命令和数据的综合函数
*******************************/
void lcd_wcmd(uchar cmd,bit i)
{   // put order or data in LCD1602
while(lcd_bz());
LCD_RS = i;
LCD_RW = 0;
LCD_EP = 0;
_nop_();
_nop_(); 
P0 = cmd; //Eight bit instruction or data through the P0 oral tradition to 1602
_nop_();
_nop_(); //Used to produce a pulse width
_nop_();
_nop_();
LCD_EP = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EP = 0;  
}


void lcd_pos(uchar idata pos)
{  //reset the position of cursor
  lcd_wcmd(pos | 0x80,0);
}   










void Init_display()
{   //第二行整屏左移  
uchar idata i;
    delayMs(20);
    TR0=0;


    lcd_pos(0);//设置显示位置为第一行的第1个字符
    i = 0;
    while(tab3[ i ] != '\0')
    {   //show字符"welcom to mcu"
    lcd_wcmd(tab3[ i ],1);
    i++;
    delayMs(20);//control两字之间显示speed
    }
    lcd_pos(0x42);//setting显示position为the second line第1个字符
    i=0;
    while(tab4[i] != '\0')  //show字符"hello world "  
    {lcd_wcmd(tab4[i],1);i++;delayMs(20);}
  
while(a==1)
{ lcd_wcmd(0x18,0);
 delay(200);delay(200);
 delay(200);delay(200);
 delay(200);delay(200);
 delay(200);delay(200);
 delay(200);delay(200);
 delay(200);delay(200);
 delay(200);delay(200);
 delay(200);delay(200);} // dead in circle of display move left
 lcd_wcmd(0x01,0);//clear the lcd display
}


void time_show_rtc()   //xian shi rtc time
{              
 
uchar idata i=0;
lcd_pos(0x40);
while(tab1[i] != '\0') //显示时间文字
{ lcd_wcmd(tab1[i],1);i++;}




 Read_RTC();
l_tmpdisplay[0]=l_tmpdate[2]/16+0x30;  //小时
l_tmpdisplay[1]=((l_tmpdate[2]&0x0f)+0x30);
   
l_tmpdisplay[2]=l_tmpdate[1]/16+0x30; //分钟
l_tmpdisplay[3]=((l_tmpdate[1]&0x0f)+0x30);

l_tmpdisplay[4]=l_tmpdate[0]/16+0x30; //秒针
l_tmpdisplay[5]=((l_tmpdate[0]&0x0f)+0x30);


l_tmpdisplay[6]=l_tmpdate[3]/16+0x30; //日
l_tmpdisplay[7]=((l_tmpdate[3]&0x0f)+0x30);


   // l_tmpdisplay[8]=l_tmpdate[5]/16+0x30; //周
l_tmpdisplay[8]=((l_tmpdate[5]&0x0f)+0x30);


l_tmpdisplay[9]=l_tmpdate[4]/16+0x30; //月
l_tmpdisplay[10]=((l_tmpdate[4]&0x0f)+0x30);


l_tmpdisplay[11]=l_tmpdate[6]/16+0x30; //年
l_tmpdisplay[12]=((l_tmpdate[6]&0x0f)+0x30);

lcd_pos(0);
lcd_wcmd(0x32,1);delayMs(200);
lcd_wcmd(0x30,1);delayMs(200);
lcd_wcmd(l_tmpdisplay[11],1);delayMs(200);
lcd_wcmd(l_tmpdisplay[12],1);delayMs(200);
   lcd_wcmd(0x2d,1);delayMs(200);
lcd_wcmd(l_tmpdisplay[9],1);delayMs(200);
lcd_wcmd(l_tmpdisplay[10],1);delayMs(200);
   lcd_wcmd(0x2d,1);delayMs(200);
lcd_wcmd(l_tmpdisplay[6],1);delayMs(200);
lcd_wcmd(l_tmpdisplay[7],1);delayMs(200);

lcd_pos(0x43);
lcd_wcmd(0x30,1);delayMs(200);
lcd_wcmd(l_tmpdisplay[8],1);delayMs(200);


lcd_pos(0x47);
lcd_wcmd(l_tmpdisplay[0],1);delayMs(200);
lcd_wcmd(l_tmpdisplay[1],1);delayMs(200);
   lcd_wcmd(0x3a,1);delayMs(200);
lcd_wcmd(l_tmpdisplay[2],1);delayMs(200);
lcd_wcmd(l_tmpdisplay[3],1);delayMs(200);
   lcd_wcmd(0x3a,1);delayMs(200);
lcd_wcmd(l_tmpdisplay[4],1);delayMs(200);
lcd_wcmd(l_tmpdisplay[5],1);delayMs(200);
 
}
   
 
/*******************************
     主函数
*******************************/
void main()
{  


   lcd_init();// initalization LCD
   Set_RTC();//写入时钟值,如果使用备用电池时候,不需要每次上电写入,此程序应该屏蔽     
    IRIN=1;
  TR0=0;
    EA=1;
             //允许总中断中断,使能 INT0 外部中断
EX0=1;
IT0=1;               //触发方式为脉冲负边沿触发
    Init_display(); //显示开机画面
delay(100);
    while(1)
    {   
P1=0xff;   
keyscan();
wendu_dis();
if(set==0)sound();
//  a1=l_tmpdate[2];a2=l_tmpdate[1];a3=l_tmpdate[0];
  time_show_rtc();
     naozhong();delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);
delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);
delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);delay(200);  
    }  
   
}
void beep();
void delay(uchar);
/**********************************************************/
void IR_IN() interrupt 0 using 0
{
  unsigned char j,k,N=0;
     EX0 = 0;   
delay(15);
if (IRIN==1) 
     { EX0 =1;
  return;
 } 
                           //确认IR信号出现
  while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
    {delay(1);}


 for (j=0;j<4;j++)         //收集四组数据
 { 
  for (k=0;k<8;k++)        //每组数据有8位
  {
   while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
     {delay(1);}
    while (!IRIN)          //等 IR 变为高电平
     {delay(1);}
     while (IRIN)           //计算IR高电平时长
      {
    delay(1);
    N++;           
    if (N>=30)
{ EX0=1;
return;}                  //0.14ms计数过长自动离开。
      }                        //高电平计数完毕                
     IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
     if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
     N=0;
  }//end for k
 }//end for j
   
   if (IRCOM[2]!=~IRCOM[3])
   { EX0=1;
     return; }


   IRCOM[5]=IRCOM[2] & 0x0F;     //取键码的低四位
   IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位变为低四位


   if(IRCOM[5]>9)
    { IRCOM[5]=IRCOM[5]+0x37;}
   else   
 IRCOM[5]=IRCOM[5]+0x30;


   if(IRCOM[6]>9)
    { IRCOM[6]=IRCOM[6]+0x37;}
   else   
 IRCOM[6]=IRCOM[6]+0x30;
 


if((IRCOM[6]==0x34)&&(IRCOM[5]==0x36))   //对应遥控按键  mode跳出开机画面
  { a=0;}
else if((IRCOM[6]==0x34)&&(IRCOM[5]==0x34)) //对应于遥控板上的蓝色背景按键
  { set=0;   }   
else if((IRCOM[6]==0x31)&&(IRCOM[5]==0x38)) //对应于按键“2”时间设置中修改小时变量
  {a1++;NOW[0]++;if(NOW[0]==24)NOW[0]=0;}
else if((IRCOM[6]==0x30)&&(IRCOM[5]==0x38))  //对应于按键“4”时间设置中修改分变量
  {a2++;NOW[1]++;if(NOW[1]==60)NOW[1]=0;}
  else if((IRCOM[6]==0x34)&&(IRCOM[5]==0x32))  //对应于按键“7”时间设置中修改秒变量
  {a3++;NOW[2]++;if(NOW[2]==60)NOW[2]=0;}
  else if((IRCOM[6]==0x30)&&(IRCOM[5]==0x37))  //对应于按键“EQ”起复位作用
  {   a4=0;a5=0; }
  else if((IRCOM[6]==0x30)&&(IRCOM[5]==0x39))//设置时间,红外按键为音量加标志
  {key1=0;}
  else if((IRCOM[6]==0x31)&&(IRCOM[5]==0x35)) //设置闹钟,红外按键为音量减标志
  {key2=0;}
     beep();
     EX0 = 1; 

/**********************************************************/
void beep()
{
  unsigned char i;
  for (i=0;i<100;i++)
   {
   delay(4);
   _Speak=!_Speak;                 //BEEP取反
   } 
  _Speak=1;                      //关闭蜂鸣器
}
/**********************************************************/
void delay(unsigned char x)    //x*0.14MS
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++) {}
 }
}  

其中的demo头文件如下:

/************************************************
功能:主要用于lizi6的头文件,包括各种端口定义
时间:2012.12.12
*************************************************/


#ifndef   _DEMO6_H_
#define   _DEMO6_H_
typedef unsigned char uchar;
typedef unsigned int uint;


/***************************
function:extern function 声明
***************************/
void lcd_pos(unsigned char);
void lcd_wcmd(unsigned char,bit);
void delayMs(unsigned char);
void lcd_pos(unsigned char );
bit lcd_bz();  
void lcd_wcmd(unsigned char,bit);
void Read_RTC(void);        //读取 日历
void delay(unsigned char);
/*************************
端口:  P2
**************************/
sbit _Speak=P2^3;
sbit LCD_RS = P2^6;  //pin of reset          
sbit LCD_RW = P2^5; //pin of read or write
sbit LCD_EP = P2^7; //poin of enable


/*************************
端口:  P1 用于键盘
**************************/
//sbit  key1=P1^0; // 调时间
//sbit  key2=P1^1; //调闹钟
//sbit  key3=P1^2;
//sbit  k7=P1^7; //调整时间
//sbit  k6=P1^6; // play songs
/*************************
端口:  P3
**************************/
sbit IRIN=P3^2;         //红外接收器数据线
sbit SCK=P3^6; //时钟
sbit SDA=P3^4; //数据
sbit RST=P3^5;// DS1302复位 
sbit  DQ=P3^7;
/*************************
端口:varible demos 
**************************/
unsigned char idata wendu;
unsigned char idata decimal;
unsigned char Count;
uchar idata dis[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}; //wen du xiao shu wei 
uchar idata a=1; //用来设置开机时跳出循环
uchar idata set=1;   //用来设置音乐播放标志
uchar idata a1=0,a2=0,a3=0,a4,a5,a6;   //a1用于调时,a2用于调分,a3用于调秒,a4、a5分别用于时间闹铃的复位,a6用于闹钟的时位设置
unsigned char NOW[3]={17,18,19}; // 闹铃设置数组   初始时17:18:19 开闹钟
uchar code tab1[]="DAY";
uchar code tab2[]=" play music";
uchar code tab3[]="Welcom To MCU 522 do what you want demo"; // 开机时显示欢迎界面一行最多显示38个字
uchar code tab4[]="  hello China ! hello joinme ! kanzhan";
uchar code tab5[]=" set naozhong";
uchar code tab6[]=" set time";
uchar idata key1=1,key2=1;
uchar IRCOM[7]; //hong wai memory  


unsigned char l_tmpdate[7]={0,0,12,15,5,3,13};//秒分时日月周年08-05-15 12:00:00
unsigned char l_tmpdisplay[13];


code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位
code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};  


#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值