📄 password.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 + -