⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 T89S52单片机以及DS1302时钟芯片
💻 C
字号:

#include"reg52.h"
#include<intrins.h>
#define uchar unsigned char 
#define uint unsigned int
uchar i=0;
uchar SHEZHI[15];
uchar init[7]={0x11,0x21,0x23,0x23,0x04,0x04,0x08};//秒,分,时,日,月,星期,年
void DISP_DATA(void);

//*******************LCD模块
#define LCD_DATA P0        //LCD的数据口

sbit LCD_BUSY=LCD_DATA^7;  //LCD忙信号位

sbit LCD_RW=P3^5;          //LCD读写控制
sbit LCD_RS=P3^4;          //LCD寄存器选择
sbit LCD_EN=P3^6;          //LCD使能信号

void LCD_check_busy(void)   //检测LCD状态,看它是不是还在忙呢
{
 while(1)
  {
   LCD_EN=0;
   LCD_RS=0; //指令寄存器通信
   LCD_RW=1;  //read data
   LCD_DATA=0xff;
   LCD_EN=1;
   if(!LCD_BUSY)break;
  }
 LCD_EN=0;
}

void LCD_cls(void)          //LCD清屏
{
 
 LCD_check_busy();
 LCD_RS=0;
 LCD_RW=0;
 LCD_DATA=1;
 LCD_EN=1;
 LCD_EN=0;
 
}

void LCD_write_instruction(unsigned char LCD_instruction)   //写指令到LCD
{
 LCD_check_busy();
 LCD_RS=0;
 LCD_RW=0;	//写数据
 
 LCD_DATA=LCD_instruction;
 LCD_EN=1;
 LCD_EN=0;
 }

void LCD_write_data(unsigned char LCD_data)      //输出一个字节数据到LCD
{
 LCD_check_busy();
 LCD_RS=1;
 LCD_RW=0;
 
 LCD_DATA=LCD_data;
 LCD_EN=1;
 LCD_EN=0;
 }
 
void LCD_set_position(unsigned char x)            //LCD光标定位到x处
{
LCD_write_instruction(0x80+x);
}





void LCD_printc(unsigned char lcd_data)          //输出一个字符到LCD
{
 LCD_write_data(lcd_data);
}

void LCD_prints(unsigned char *lcd_string)       //输出一个字符串到LCD
{
 unsigned char i=0;
 while(lcd_string[i]!=0x00)
  {
   LCD_write_data(lcd_string[i]);
   i++;
  } 
}

void LCD_initial(void)                        //初始化LCD
{
 LCD_write_instruction(0x3c);
 LCD_write_instruction(0x0c);
 LCD_write_instruction(0x06);//显示屏一定要不移动。
 LCD_cls();
}
//*************************LCD模块结束

//键盘

uchar temp_OUT=0x0A;
uchar flag_san_key=0;
void delay1(void)
{
uint i;
for(i=300;i>0;i--);
}

void scan_key(void)
{
unsigned char i,temp1;
         P1=0XF0;
		 for(i=0;i<4;i++)
		 {
 		 P1=~(1<<i);
		delay1();
		 temp1=P1&0xF0;
		 		if(temp1!=0xF0)
		 		   {	
           			delay1();
					temp1=P1&0xF0;
		    		switch(temp1)
					{
 					case 0xe0:temp_OUT=3-(3-i)*1;SHEZHI[flag_san_key++]=temp_OUT;break;  //   0 1 2 3
 					case 0xd0:temp_OUT=7-(3-i)*1;SHEZHI[flag_san_key++]=temp_OUT;break;  //   4 5 6 7
 					case 0xb0:temp_OUT=11-(3-i)*1;SHEZHI[flag_san_key++]=temp_OUT;break;  //  8 9 a b
 					case 0x70:temp_OUT=15-(3-i)*1;SHEZHI[flag_san_key++]=temp_OUT;break;  //  c d e f
 					default:break;//0x3f;
 					}
						 
						tt:temp1=P1&0xF0;
						if(temp1!=0xF0)
		 				   {
		 				  ; 
		 				   goto tt;
		 				    }
		         }  
        }
}

void DISP_DATA(void)
{
scan_key();
if(temp_OUT!=0X0A)
{
init[6]=(SHEZHI[0]<<4)|SHEZHI[1];
init[5]=(SHEZHI[2]<<4)|SHEZHI[3];
init[4]=(SHEZHI[4]<<4)|SHEZHI[5];
init[3]=(SHEZHI[6]<<4)|SHEZHI[7];
init[2]=(SHEZHI[8]<<4)|SHEZHI[9];
init[1]=(SHEZHI[10]<<4)|SHEZHI[11];
init[0]=(SHEZHI[12]<<4)|SHEZHI[13];

//显示
LCD_set_position(1);
      LCD_printc(0X32);

      LCD_set_position(2);
      LCD_printc(0X30);

      LCD_set_position(3);
      LCD_printc(0X30+init[6]/16);

      LCD_set_position(4);
      LCD_printc(0X30+init[6]%16);

      LCD_set_position(5);
      LCD_prints("  "); 
      //月日

      LCD_set_position(7);
      LCD_printc(0X30+init[4]/16);
      LCD_set_position(8);
      LCD_printc(0X30+init[4]%16);

      LCD_set_position(9);
      LCD_prints("-");

      LCD_set_position(10);
      LCD_printc(0X30+init[3]/16);

      LCD_set_position(11);
      LCD_printc(0X30+init[3]%16);
      LCD_set_position(12);
      LCD_prints("  ");
      //星期

      LCD_set_position(14);
      LCD_printc(0X30+init[5]%16);


      //时分秒

     LCD_set_position(0X4E);
     LCD_printc(0X30+init[0]%16);

     LCD_set_position(0X4D);
     LCD_printc(0X30+init[0]/16);

     LCD_set_position(0X4C);
     LCD_prints(":");

     LCD_set_position(0x4B);
     LCD_printc(0X30+init[1]%16);

     LCD_set_position(0x4a);
     LCD_printc(0X30+init[1]/16);

    LCD_set_position(0X49);
    LCD_prints(":");

    LCD_set_position(0X48);
    LCD_printc(0X30+init[2]%16);
    LCD_set_position(0X47);
    LCD_printc(0X30+init[2]/16);

}

}


//ds1302控制
sbit reset=P3^7;
sbit sclk=P2^6;
sbit io=P2^7;




void delay()
{uint j;
for(j=500;j>0;j--);
}
 
//-----------ds1302模块开始-------------------
//注意点:sclk的上升沿输入数据,sclk的下跳沿输出数据
//读写时都是从第0位开始
void write_byte(uchar inbyte)
{
uchar i;
for(i=8;i>0;i--)
{
  sclk=0;   //写的时候低电平改变数据
  if(inbyte&0x01)
      io=1;
  else
      io=0; 
  sclk=1;  //写的时候高电平,把数据写入ds1302
  _nop_();
  inbyte=inbyte>>1;
}
}
uchar read_byte() //sclk的下跳沿读数据
{
uchar i,temp=0; 
io=1;          //设置为输入口
for(i=7;i>0;i--)
{
   sclk=0;
   if(io==1)
   temp=temp|0x80;
   else
   temp=temp&0x7f;
   sclk=1;       //产生下跳沿
   temp=temp>>1;
}
return (temp);
}
//----------往ds1302的某个地址写入数据-------------
void write_ds1302(uchar cmd,uchar indata)
{
  reset=1;
  write_byte(cmd);
  write_byte(indata);
  reset=0;
  sclk=0;
}
//----------读ds1302某地址的的数据-----------------
uchar read_ds1302(uchar addr)
{
uchar backdata;
reset=1;
write_byte(addr);
backdata=read_byte();//先写地址,然后读数据
reset=0;
sclk=0;
return (backdata);
}
//------------设置初始时间-------------------
void set_ds1302(uchar addr,uchar *p,uchar n)//写入n个数据
{
  write_ds1302(0x8e,0x00);//写控制字,允许写操作
  for(;n>0;n--)
  {write_ds1302(addr,*p);
   p++;
   addr=addr+2;
  }
  write_ds1302(0x8e,0x80);//写保护,不允许写
}
//----------- 读取当前时间-------------------
void read_nowtime(uchar addr,uchar *p,uchar n)
{
for(;n>0;n--)
{
   *p=read_ds1302(addr);
   p++;
   addr=addr+2;
}      
}
void init_ds1302()
{
  reset=0;
  sclk=0;
  write_ds1302(0x80,0x00);//写控制字,允许写
  write_ds1302(0x90,0x00);//禁止涡流充电 
}
//-----------ds1302模块结束-------------------


//-  ----------公历转阴历结束-------------------
//LCD1602显示
void LCD1602_DISP(void)
{
uchar format=0;
		if(SHEZHI[14]==0x0A)
		{
		flag_san_key=0;
		set_ds1302(0x80,init,7);//设置初始时间,日期,年月
        SHEZHI[14]=0x00;
				for(format=0;format<14;format++)
				{
				SHEZHI[format]=0;
				}

		}

	    if(temp_OUT==0X0A)
     {
	 
     
      read_nowtime(0x81,init,7); //读出当前时间,读出7个字节 
      //年
      LCD_set_position(1);
      LCD_printc(0X32);

      LCD_set_position(2);
      LCD_printc(0X30);

      LCD_set_position(3);
      LCD_printc(0X30+init[6]/16);

      LCD_set_position(4);
      LCD_printc(0X30+init[6]%16);

      LCD_set_position(5);
      LCD_prints("  "); 
      //月日

      LCD_set_position(7);
      LCD_printc(0X30+init[4]/16);
      LCD_set_position(8);
      LCD_printc(0X30+init[4]%16);

      LCD_set_position(9);
      LCD_prints("-");

      LCD_set_position(10);
      LCD_printc(0X30+init[3]/16);

      LCD_set_position(11);
      LCD_printc(0X30+init[3]%16);
      LCD_set_position(12);
      LCD_prints("  ");
      //星期

      LCD_set_position(14);
      LCD_printc(0X30+init[5]%16);


      //时分秒

     LCD_set_position(0X4E);
     LCD_printc(0X30+init[0]%16);

     LCD_set_position(0X4D);
     LCD_printc(0X30+init[0]/16);

     LCD_set_position(0X4C);
     LCD_prints(":");

     LCD_set_position(0x4B);
     LCD_printc(0X30+init[1]%16);

     LCD_set_position(0x4a);
     LCD_printc(0X30+init[1]/16);

    LCD_set_position(0X49);
    LCD_prints(":");

    LCD_set_position(0X48);
    LCD_printc(0X30+init[2]%16);
    LCD_set_position(0X47);
    LCD_printc(0X30+init[2]/16);
   }
}



void main()

{   
   LCD_initial();
   init_ds1302();          //初始化ds1302
   set_ds1302(0x80,init,7);//设置初始时间,日期,年月

		while(1)
		{
        DISP_DATA();
		LCD1602_DISP();

		}



	
		   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -