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

📄 password.c

📁 采用时钟芯片PCF8563
💻 C
字号:
/*======================================*/
/*  名称:PCF8563时钟                   */
/*  建立时间:2008.4.3                  */
/*  程序功能:实现年月日时分秒显示      */
/*  修改时间:2008.4.6                  */
/*  编       写: 陈 雷 
/*======================================*/

#include <reg52.h>		  //文件包含
#include "intrins.h"

#define uchar unsigned char    //宏定义
#define uint unsigned int
#define Nop() _nop_()     //定义空指令

#define I2C_DeviceAddress 0xa2			 /* 定义器件在I2C总线中的地址 */


uchar code LED[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40};//共阴LED段码表--不带小数点
uchar code display[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};	  //共阳数码管
//uchar data reg_set;
uchar data time_set[5]={0x55,0x59,0x23,0xD6,0x88};	   //初始时间03年8月16日21时59分25秒,星期4
uchar data time_show[13]={0,0,0,0,0,0};	   //显示时间
uchar data time_disp[5];
/*8583端口位定义*/

sbit SCL=P3^0;	   //模拟I2C时钟控制位
sbit SDA=P3^1;	   //模拟I2C数据传送位,串行双向数据输入/输出线


sbit ge=P2^0;	   //位选
sbit shi=P2^1;
sbit bai=P2^2;	   
sbit qian=P2^3;

uchar second,minute,hour,day,month,year,week;
uchar data x,y,count,i,sel,sele;
/*状态标志*/
bit ack;           //应答标志位	 或bit bdata ack(定义可位寻址区);


/*延时1ms/10程序*/
void delay(int x)				
{	int i,j;
	for(j=0;j<x;j++)
	{ for(i=0;i<10;i++);}		//空循环产生延时
}


  
/********************************************************************/
void Start_I2C()
{
 SDA=1;   						 //数据线高电平
 SCL=1;							 //时钟线高电平
 Nop();Nop();Nop();Nop();Nop();  //起始条件建立时间大于4.7μs  
 SDA=0;   						 //发送起始信号
 Nop();Nop();Nop();Nop();Nop();  //起始条件锁定时间大于4μs     
 SCL=0;  						 //钳住I2C总线,准备发送或接收数据 
 Nop();Nop();
}	  

/*
********************************************************************/
void Stop_I2C()
{ //SCL=0; 可省略
 SDA=0;               	  //发送结束条件的数据信号
 Nop();               	  //发送结束条件的时钟信号
 SCL=1;               	  //结束条件建立时间大于4μs
 Nop();Nop();Nop();Nop();
 SDA=1;               	  //数据信号由0跳变为1
 Nop();Nop();Nop();Nop(); //SCL=0; 可省略
}


/**
********************************************************************/
void Ack_I2C(bit a)
{
  SDA=a;                     //0表示应答,1表示非应答    					
  Nop();Nop();Nop();     
SCL=1;
  Nop();Nop();Nop();Nop();Nop(); 	//时钟低电平周期大于4μs
SCL=0;                              //清时钟线,钳住I2C总线以便继续接收
  Nop();Nop();   
}

/**
********************************************************************/
bit checkAck_I2C()
{ 
  SDA=1; Nop();  Nop();           //8位发送完后释放数据线,准备接收应答位    
  SCL=1; Nop();  Nop();  Nop(); 
  if(SDA==1)ack=0;   
    else    ack=1;     //判断是否接收到应答信号,SDA=1表示无应答,SDA=0表示有应答
  SCL=0; Nop();  Nop();  
  return(ack);
}
/**
********************************************************************/
void Write_8bit(uchar input)
{
  uchar i;
  for(i=0;i<8;i++)        //要传送的数据长度为8位(一个字节)
  {
    if((input<<i)&0x80)	  //判断发送位,并发送,先发高位
	   SDA=1;   
     else 
	   SDA=0;           
    Nop();
    SCL=1;                                    //置时钟线为高,通知被控器开始接收数据位	
    Nop();  Nop();  Nop();  Nop();  Nop();    //保证时钟高电平周期大于4μs   
    SCL=0; 
  }  
}

/*********************************************************************/    
uchar Read_8bit()
{
  uchar temp=0,i;
  SDA=1;            //置数据线为输入方式
  for(i=0;i<8;i++)
    {          
     //SCL=0;         //*置时钟线为低,准备接收数据位
     //Nop();  Nop();  Nop();   Nop();  Nop();	   //*时钟低电平周期大于4.7μs
     SDA=1;
	 SCL=1; Nop();  Nop();   //置时钟线为高使数据线上数据有效   
     temp=temp<<1;          //临时存放接收的数据,先接受的是最高位
     if(SDA==1)temp=temp+1; //读数据位,接收的数据位放入temp中,temp=temp|0x01;
     Nop(); Nop(); 
     SCL=0;   
     Nop(); Nop();
   }
  return(temp);
}

/********************************************************************/
I2C_SendByte(uchar addr,uchar n)
{
  uchar i;
  Start_I2C();                          //启动总线
  Write_8bit(I2C_DeviceAddress);    
  if(checkAck_I2C()==0)return(0);	   
  Write_8bit(addr);                 //发送写入地址
  if(checkAck_I2C()==0)return(0);	   
  
  for(i=0;i<n;i++)		      
	{
	  Write_8bit(time_set[i]);
	  if(checkAck_I2C()==0)return(0);	 
    }
  Stop_I2C();            //结束总线 
}

/**********************************************************************/
I2C_SendByte1(uchar addr,uchar reg_set)
{
  //uchar i;
  Start_I2C();                      
  Write_8bit(I2C_DeviceAddress);    
  if(checkAck_I2C()==0)return(0);	    
  Write_8bit(addr);                 
  if(checkAck_I2C()==0)return(0);	    
  
  Write_8bit(reg_set);
  if(checkAck_I2C()==0)return(0);	 
    
  Stop_I2C();            //结束总线 
}

/*********************************************************************/
I2C_RcvByte(uchar addr,uchar n)
{
  uchar i;
  Start_I2C();           //启动总线
  Write_8bit(I2C_DeviceAddress);     //发送读控制字
  if(checkAck_I2C()==0)return(0);
  Write_8bit(addr);        //发送要读取的寻址单元地址
  if(checkAck_I2C()==0)return(0);	 

  Start_I2C();           //启动总线
  Write_8bit(I2C_DeviceAddress+1);     //发送读控制字——1010+从器件地址信息+1
  if(checkAck_I2C()==0)return(0);
  for(i=0;i<n;i++)					  
  {									     time_disp[i]=Read_8bit();    
	if(i!=n-1)Ack_I2C(0);		 
  	 else	  Ack_I2C(1);		
  }
            
  Stop_I2C();             //结束总线   
}


display_led()		   //共阳数码管显示
{
  sel=0X01;
  for(i=0;i<8;i++)
    { 	  
	  P2=sel;
	  P0=display[time_show[i]];delay(1);
	  sel=sel<<1;
	}
    P2=0;
  sel=0X01;
  for(i=8;i<13;i++)
    { 	  
	  P1=sel;
	  P0=display[time_show[i]];delay(1);
	  sel=sel<<1;
	}
  P1=0;
}		

main()	           
{
  SDA=1;
  SCL=1;

  
  I2C_SendByte1(0x00,0x20);   // 向地址00H单元写入0x20,停止计时
  I2C_SendByte(0x02,5);	      // 向地址02H单元和03H单元分别写入秒和分两个字节
  I2C_SendByte1(0x00,0x00);   // 向地址00H单元写入0x00,起动计时

  
  delay(10);
  
  while(1)
   {
   	 I2C_RcvByte(2,5);                   //将02单元开始的秒分时读出
	 second=time_disp[0]&0x7F;
	 minute=time_disp[1]&0x7F;
	 hour=time_disp[2]&0x3F;
	 day=time_disp[3]&0x3F;
	 month=time_disp[4]&0x1F;
	 year=time_disp[3]&0xC0;
	 week=time_disp[4]&0xE0;

	 time_show[0]=second&0x0F;        //秒低位	 
	 time_show[1]=(second&0xF0)>>4;   //秒高位

	 time_show[2]=minute&0x0F;        //分低位
	 time_show[3]=(minute>>4)&0x0F;   //分高位

     time_show[4]=hour&0x0F;        //时低位
	 time_show[5]=(hour>>4)&0x0F;   //时高位

	 time_show[6]=day&0x0F;        //日低位
	 time_show[7]=(day>>4)&0x0F;   //日高位

	 time_show[8]=month&0x0F;        //月低位
	 time_show[9]=(month>>4)&0x0F;   //月高位

	 time_show[10]=(year>>6)&0x03;        //年低位
	 time_show[11]=0x00;             //年高位

	 time_show[12]=(week>>5)&0x07;   //星期位



	 display_led();

   }
 }


							  

⌨️ 快捷键说明

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