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

📄 ds1302+lcd1602-c51.c.bak

📁 这是一个基于51单片机的DS1302_实时时钟驱动程序
💻 BAK
📖 第 1 页 / 共 2 页
字号:
//LCD1602+ds1302显示
#include<reg51.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit LCD_RS = P2^0;             
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;

sbit  K1 = P1^4;
sbit  K2 = P1^5;
sbit  K3 = P1^6;
sbit  K4 = P1^7;

sbit reset = P1^2;
sbit sclk  = P1^0;
sbit io    = P1^1;

sbit  BEEP = P3^7;
bit flag=1,hour=0,min=0,sec=0;
bit year=0,month=0,day=0,week=0;
bit alarm_flag=0;
uchar  timecount=0,count=0; 

uchar str1[]="  -  -   Week:  ";
uchar str2[]="Time:           ";
uchar str3[]="Alarm:          ";

uchar init [] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00};  //
uchar init1[] ={0x00,0x00};
uchar init2[] ={0x00,0x59,0x23,0x01,0x05,0x01,0x06}; //
               //秒, 分, 时, 日, 月,星期,年
uchar bj_time[] ={0x00,0x00,0x00}; 
                 //秒, 分, 时
uchar code  mytab[8] = {0x01,0x1b,0x1d,0x19,0x1d,0x1b,0x01,0x00};//小喇叭

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

void  Set_W1302(uchar addr);
void  Set_Flash(uchar row,uchar col);
void  Set_place(uchar row,uchar col);
void  Play_nowtime();
void  key_set(uchar num,uchar row,uchar col );
void  alarm_time();
void  Play_alarmtime();
void  Time_compare();
/******************************************************************/

/******************************************************************/
void delay1(int ms)
{
 unsigned char y;
  while(ms--)
 {
  for(y = 0; y<250; y++)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  }
 }
}

/******************************************************************/
/*                                                                */
/*检查LCD忙状态                                                   */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。     */
/*                                                                */
/******************************************************************/ 

bit lcd_busy()
 {                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result); 
 }

/*********************************************************/
/*                                                       */
/*写指令数据到LCD                                        */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                   */
/*                                                       */
/*********************************************************/

void lcd_wcmd(uchar cmd)
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_(); 
    P0 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}

/*********************************************************/
/*                                                       */
/*写显示数据到LCD                                        */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                     */
/*                                                       */
/*********************************************************/
void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0; 
}

/*********************************************************/
/*                                                       */
/*  LCD初始化设定                                        */
/*                                                       */
/*********************************************************/

void init_lcd()
{ 
    delay1(15);   
    lcd_wcmd(0x01);      //清除LCD的显示内容
            
    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);

    lcd_wcmd(0x0c);      //显示开,关光标
    delay1(5);
    lcd_wcmd(0x06);      //移动光标
    delay1(5);
    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay1(5);
}

/*********************************************************/
// 
/*********************************************************/
void delay()
{
   uchar j;
   for(j=250;j>0;j--);
}

/*********************************************************/
/*                                                       */
/*  写字符串函数                                         */
/*                                                       */
/*********************************************************/
void write_str(uchar addr,uchar *p)
{
   uchar i=0; 
   lcd_wcmd(addr);
   while(p[i]!='\0')
   {
    lcd_wdat(p[i]);
    i++;
   }
}

/*********************************************************/
/*                                                       */
/*  设定显示位置                                         */
/*                                                       */
/*********************************************************/
void write_position(uchar row,uchar col)
 {
   uchar place;
   if(row==1)
   {
     place=0x80+col-1;
     lcd_wcmd(place);
   }
   else
   {
     place=0xc0+col-1;
     lcd_wcmd(place);
   }
 }

/*********************************************************/
/*                                                       */
/*自定义字符写入CGRAM                                    */
/*                                                       */
/*********************************************************/
void  writetab()  
{  
    unsigned char i;
    lcd_wcmd(0x40);            //写CGRAM
    for (i = 0; i< 8; i++)       
    lcd_wdat(mytab[i]);        
}

/**********************************************************/
//
/**********************************************************/
void write_byte(uchar inbyte)
{
   uchar i;
   for(i=0;i<8;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=0;i<7;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)
{
   sclk=0;
   reset=1;
   write_byte(cmd);        
   write_byte(indata);
   
   sclk=0;
   reset=0;
}

/**********************************************************/
// 读ds1302某地址的的数据 
/**********************************************************/
uchar read_ds1302(uchar addr)
{
   uchar backdata;
   sclk=0;
   reset=1;

   write_byte(addr);      //先写地址
   backdata=read_byte();  //然后读数据
  
   sclk=0;
   reset=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;
  } 
}

/**********************************************************/
// 初始化DS1302
/**********************************************************/
void init_ds1302()
{
   reset=0;
   sclk=0;
   write_ds1302(0x80,0x00); 
   write_ds1302(0x90,0xa6); //一个二极管+4K电阻充电
   write_ds1302(0x8e,0x80); //写保护控制字,禁止写
}

/**********************************************************/
/*                                                        */
/* 蜂鸣器响一声                                           */
/*                                                        */
/**********************************************************/
void beep()
  {
    unsigned char y;
    for (y=0;y<100;y++)
    {
      delay();
      BEEP=!BEEP;                //BEEP取反
    } 
    BEEP=1;                      //关闭蜂鸣器
	delay1(50);
  }

/**********************************************************/
/*                                                        */
/* 闪动函数                                          */
/*                                                        */
/**********************************************************/
void  flash()
{
   if(flag)
    {
      write_position(2,9);
      lcd_wdat(':');
      write_position(2,12);
      lcd_wdat(':');     
    }
    else
    {
      write_position(2,9);
      lcd_wdat(0x20);
      write_position(2,12);
      lcd_wdat(0x20);     
    }
}
/**********************************************************/
// 主函数
/**********************************************************/
void main()
{
  
   P1=0xff;
   TMOD=0x01;
   TH0=0x4c;          //50ms定时
   TL0=0x00;
   EA=1;
   ET0=1;  
   TR0=1;
   init_lcd();                 //初始化LCD
   write_str(0x80,str1);       //液晶显示提示信息
   write_str(0xc0,str2);       //液晶显示提示信息
   init_ds1302();              //初始化ds1302

   writetab();               //自定义字符写入CGRAM
//   delay1(5);
//   write_position(2,16);
//   lcd_wdat(0x00);           //显示自定义字符小喇叭
   
   while(1)
   {
//---------------------------------------------------------
   if(!K1)
      {
        if(!K2)
		{
	      set_ds1302(0x80,init2,7);  //设置初始时间,日期,年月
		  beep();
        }
      
  		if(!K3)
		{
		  write_str(0xc0,str3);    //显示报警信息
          if(alarm_flag)              //alarm_flag=1,开定时
	      {
	        write_position(2,16);
            lcd_wdat(0x00);           //显示自定义字符小喇叭
	      }
	      Play_alarmtime();        //查看报警时间
		  beep();
		  delay1(700);
		  write_str(0xc0,str2);    //显示时间信息
		  if(alarm_flag)              //alarm_flag=1,开定时
	      {
	        write_position(2,16);
            lcd_wdat(0x00);           //显示自定义字符小喇叭
	      }
		}

		if(!K4)
		{

⌨️ 快捷键说明

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