📄 rtc._c
字号:
#include <io8535v.h>
#include <macros.h>
#ifndef uchar
#define uchar unsigned char
#define uint unsigned int
#endif
#define SD2303 0x64 //SD2303器件IIC识别码
uchar F_Flag;
uchar Table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void DelayMs(uint i) //0.25ms
{uchar j;
for(;i!=0;i--)
{for(j=2000;j!=0;j--) {;}}
}
void Display(uchar *p) //间隔5ms显示
{uchar i,sel=0x01;
for(i=0;i<4;i++)
{PORTB=~sel;
PORTA=Table[*p];
p++;
DelayMs(20);
sel=sel<<1;
}
}
void NOPNOP(uchar i)
{for(;i!=0;i--) NOP();}
//sbit SCL=PC^0; //定义SD2303IIC时钟线
void SetSCL(uchar i)
{if(i==1) PORTC=PORTC|0x01;
else PORTC=PORTC&0xfe;}
//sbit SDA=PC^1; //定义SD2303IIC数据线
void SetSDA(uchar i)
{if(i==1) PORTC=PORTC|0x02;
else PORTC=PORTC&0xfd;}
K
//sbit INTRB=PD^6; //定义SD2303中断线A
//sbit INTRA=P1^7; //定义SD2303中断线B
void Start() //IIC总线开始
{SetSDA(1);//SDA=1; //条件:SCL高电平时SDA的下降沿
SetSCL(1);//SCL=1;
NOPNOP(50);//while(SCL==0){;} //等待时钟信号变成高电平以确保总线开始
//_nop_();
//_nop_();
SetSDA(0);//SDA=0;
NOPNOP(50);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
SetSCL(0);// SCL=0; //拉低时钟信号线
}
void Stop() //IIC总线结束
{SetSDA(0);//SDA=0; //条件:SCL为高电平时SDA的上升沿
SetSCL(1);//SCL=1;
NOPNOP(50);//while(SCL==0){;} //等待时钟信号变成低电平以确保总线结束
// _nop_();
// _nop_();
SetSDA(1);//SDA=1;
NOPNOP(50);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
SetSCL(0);//SCL=0;
}
void Ack() //IIC总线应答
{SetSDA(0);//SDA=0; //应答方式:读完一个字节后将SDA线拉低,即应答0
SetSCL(1);//SCL=1;
NOPNOP(50);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
SetSCL(0);//SCL=0;
SetSDA(1);//SDA=1;
}
void Nack() //IIC总线应答
{SetSDA(1);//SDA=1; //应答方式:读完所要求的字节数据后将SDA线拉高,即
SetSCL(1);//SCL=1; //应答1,为结束IIC总线操作做准备
NOPNOP(50);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
SetSCL(0);//SCL=0;
SetSDA(0);//SDA=0;
}
void Check_Ack() //检查IIC器件应答情况
{SetSDA(1);//SDA=1;
SetSCL(1);//SCL=1;
F_Flag=0;//F0=0;
DDRC=DDRC&0xfd; //设置SDA为输入
//if(SDA==0)
if((PINC&0x02)==0)
{
SetSCL(0);//SCL=0;
NOPNOP(50);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
}
else
{
F_Flag=1;//F0=1;
SetSCL(0);//SCL=0;
NOPNOP(50);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
}
DDRC=DDRC|0x02; //重新设置SDA为输出
}
void Write_Bit0() //写1bit数据:0
{SetSDA(0);//SDA=0;
SetSCL(1);//SCL=1;
NOPNOP(50);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
SetSCL(0);//SCL=0;
}
void Write_Bit1() //写1bit数据:1
{SetSDA(1);//SDA=1;
SetSCL(1);//SCL=1;
NOPNOP(50);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
SetSCL(0);//SCL=0;
SetSDA(0);//SDA=0;
}
void Write_Byte(uchar Data) //写一字节数据:Data:要写入的数据
{uchar i;
for(i=0;i<8;i++)
{if((Data&0x80)>0) //传输位从高位到低位,先传最高位
Write_Bit1();
else
Write_Bit0();
Data<<=1; //数据左移
}
}
uchar Read_Byte() //读一字节数据:返回值即读的数据
{uchar nn=0xff; //nn:初始化为0xff,读入的数据也放在此
uchar j;
for (j=0;j<8;j++)
{SetSDA(1);//SDA=1;
SetSCL(1);//SCL=1;
DDRC=DDRC&0xfd;//设置SDA为输入线
//if(SDA==0) //数据读出,若是0则移位;若是1则与0x01或
if((PINC&0x02)==0)
{nn<<=1;
nn=(nn&0xfe);
SetSCL(0);}//SCL=0;}
else
{nn<<=1;
nn=(nn|0x01);
SetSCL(0);}//SCL=0;}
}
DDRC=DDRC|0x02;//设置SDA为输出线
return(nn); //返回读出的字节
}
//********************写N个字节子程序************************//
//函数参数说明:
//Slave:IIC器件地址,如上文定义的SD2303
//Address:起始地址
//Array:读数据存放的数组
//Number:读取的字节数
void Write_Nbyte(uchar Slave,uchar Address,uchar *Array,uchar Number)
{uchar k;
writ:do //开始->写IIC器件地址->检查应答位
{Start();
Write_Byte(Slave);
Check_Ack();
}while(F_Flag==1);//while(F0==1);
do
{Write_Byte(Address<<4); //送起始地址->检查应答位
Check_Ack();
}while(F_Flag==1);//while(F0==1);
for(k=0;k<Number;k++) //写Number个数据
{Write_Byte(*Array);
Array++;
Check_Ack(); //检查应答位
//if(F0==1) goto writ;
} //若任意一个应答位不对,重新开始整个过程
Stop(); //停止信号
}
//***********写一个字节******************************//
void Write_1byte(uchar Slave,uchar Address,uchar Data)
{writ:do //开始->写IIC器件地址->检查应答位
{Start();
Write_Byte(Slave);
Check_Ack();
}while(F_Flag==1);//while(F0==1);
do
{Write_Byte(Address<<4); //送起始地址->检查应答位
Check_Ack();
}while(F_Flag==1);//while(F0==1);
Write_Byte(Data);
Check_Ack(); //检查应答位
// if(F0==1) goto writ; //若应答位不对,重新开始整个过程
Stop(); //停止信号
}
//***************读N个字节子程序*********************//
//函数参数说明:
//Slave:IIC器件地址,如上文定义的SD2303
//Address:起始地址
//Array:读数据存放的数组
//Number:读取的字节数
void Read_Nbyte(uchar Slave,uchar Address,uchar *Array,uchar Number)
{uchar data0,x;
//第一步:开始信号->写IIC器件地址->检查应答位
do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);//while(F0==1);
//第二步:写起始地址->检查应答位
do {Write_Byte(Address<<4);Check_Ack();}while(F_Flag==1);// while(F0==1);
//第三步:开始信号->写IIC器件地址+1(表示读)->检查应答位
do{Start();Write_Byte(Slave+1);Check_Ack();}while(F_Flag==1);//while(F0==1);
//第四步:读N字节,每读完一字节发一个Ack应答,最后一字节发Nack
for(x=0;x<Number;x++)
{data0=Read_Byte();*Array=data0;Array++;
if(x<(Number-1)) { Ack(); }}
Nack();
//第五步:发停止信号,结束读操作
Stop();
}
void main(void)
{uchar i;
uchar time[15]={2,0,0,4,1,2,2,7,1,1,7,3,0,5,0};
uchar Set_Time[7]={0x50,0x30,0x17,0x01,0x27,0x12,0x04};
// 2004-12-27 Monday 17-30-50
uchar SD2303_Controller1=0x00;//禁止中断
uchar SD2303_Controller2=0x20;//24小时制;
// InitLCD();
DDRA=0xff;
DDRB=0xff;
DDRC=0xFF;
Write_1byte(SD2303,0x0e,SD2303_Controller1);
Write_1byte(SD2303,0x0f,SD2303_Controller2);
Write_Nbyte(SD2303,0x00,Set_Time,7);
while(1)
{Read_Nbyte(SD2303,0x00,Set_Time,7);
time[2]=Set_Time[6]>>4; //年高位;
time[3]=Set_Time[6]&0x0f;//年低位;
time[4]=Set_Time[5]>>4; //月高位;
time[5]=Set_Time[5]&0x0f; //月低位;
time[6]=Set_Time[4]>>4;//日高位;
time[7]=Set_Time[4]&0x0f; //日低位;
time[8]=Set_Time[3]; //WEEK;
time[9]=Set_Time[2]>>4;//时高位;
time[10]=Set_Time[2]&0x0f; //时低位;
time[11]=Set_Time[1]>>4; //分高位;
time[12]=Set_Time[1]&0x0f; //分低位;
time[13]=Set_Time[0]>>4;//秒高位;
time[14]=Set_Time[0]&0x0f; //秒低位;
for(i=0;i<200;i++)
Display(time);
for(i=0;i<200;i++)
Display(time+4);
for(i=0;i<200;i++)
Display(time+9);
for(i=0;i<200;i++)
Display(time+11);
Display(time);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -