📄 rtc.c
字号:
#include <./Atmel/at89x52.h>
#include <stdio.h>
#include "source.h"
#include <intrins.h>
#include <absacc.h>
//_nop_();0.65us fosc=18.432
/*i2c max rate: 100k, so delay is needed*/
#define DELAY _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
#define I2CDATA SDA /*为I2C的数据口*/
#define I2CSETDATA SDA=1 /*设置SDA为1*/
#define I2CCLRDATA SDA=0 /*设置SDA为0*/
#define I2CSETCLK SCL=1 /*设置SCL为1*/
#define I2CCLRCLK SCL=0 /*设置SCL为0*/
void i2c_start(){//为I2C的开始时序列
I2CSETDATA;
I2CSETCLK;
DELAY;
I2CCLRDATA;
DELAY;
I2CCLRCLK;
}
void i2c_stop(){//为I2C的停止时序
I2CCLRCLK;
I2CCLRDATA;
DELAY;
I2CSETCLK;
DELAY;
I2CSETDATA;
}
void i2c_write_byte(unsigned char ch)//为I2C的写一个字节的时序
{
unsigned char i=8;
while(i--){
I2CCLRCLK;_nop_();
if(ch&0x80)
I2CSETDATA;
else
I2CCLRDATA;
ch<<=1;DELAY;
I2CSETCLK;DELAY;
}
I2CCLRCLK;
}
unsigned char i2c_read_byte(void)//为I2C的读一个字节的时序
{
unsigned char i=8;
unsigned char ddata=0;
I2CSETDATA ;
while (i--){
ddata<<=1 ;
I2CCLRCLK;DELAY;
I2CSETCLK;DELAY;
ddata|=I2CDATA;
}
I2CCLRCLK;
return ddata;
}
bit i2c_wait_ack(void)//为I2C的等待应答时序
{
unsigned char errtime=255;//因故障接收方无ACK 超时值为255
I2CSETDATA;DELAY;
I2CSETCLK ;DELAY;
while(I2CDATA){
errtime--;
if (!errtime){
i2c_stop();
return 0;
}
}
I2CCLRCLK;
return 1;
}
void i2c_send_ack(void)//为I2C的发送应答时序
{
I2CCLRDATA; DELAY;
I2CSETCLK; DELAY;
I2CCLRCLK;
}
void i2c_send_notack(void)//为I2C的发送无应答的时序列
{
I2CSETDATA ; DELAY;
I2CSETCLK ; DELAY;
I2CCLRCLK;
}
#define RTCWTIME 0X64
#define RTCRTIME 0X65
#define RTCRHOUR 0X67
#define RTCWSTAT 0X62
#define RTCWINT1 0X68
#define RTCWINT2 0X6A
unsigned char MSBTOLSM(unsigned char ch){//把MSB形式的字节转化为LSM的形式
unsigned char tmp=0;
unsigned char cvt;
unsigned char i;
cvt=ch;
for(i=0;i<8;i++){
tmp>>=1;
if(cvt&0x80){
tmp |=0x80;
}
else{
}
cvt<<=1;
}
return tmp;
}
unsigned char SD2000_set_time(struct RTC_TIME *p){//为SDA200设置时间的函数
unsigned char ch;
EA=0;
i2c_start();
i2c_write_byte(RTCWTIME);
ch=MSBTOLSM(p->year);
if(i2c_wait_ack()){
i2c_write_byte(ch);
ch=MSBTOLSM(p->month);
i2c_wait_ack();
i2c_write_byte(ch);
ch=MSBTOLSM(p->dayom);
i2c_wait_ack();
i2c_write_byte(ch);
ch=MSBTOLSM(p->week);
i2c_wait_ack();
i2c_write_byte(ch);
ch=MSBTOLSM(p->hour);
i2c_wait_ack();
i2c_write_byte(ch);
ch=MSBTOLSM(p->minute);
i2c_wait_ack();
i2c_write_byte(ch);
ch=MSBTOLSM(p->second);
i2c_wait_ack();
i2c_write_byte(ch);
i2c_wait_ack();
i2c_stop();
}
else{
// RTC write ack error.
}
EA=1;
return 1;
}
unsigned char SD2000_read_time(struct RTC_TIME *p){//为SDA2000读时间(年月日时分秒)的函数
unsigned char ch;
EA=0;
i2c_start();
i2c_write_byte(RTCRTIME);
if(!i2c_wait_ack()){
EA=1;
return 0;//no ack.
}
ch=i2c_read_byte();
i2c_send_ack();
p->year=MSBTOLSM(ch);
ch=i2c_read_byte();
i2c_send_ack();
p->month=MSBTOLSM(ch);
ch=i2c_read_byte();
i2c_send_ack();
p->dayom=MSBTOLSM(ch);
ch=i2c_read_byte();
i2c_send_ack();
p->week=MSBTOLSM(ch);
ch=i2c_read_byte();
i2c_send_ack();
p->hour=MSBTOLSM(ch);
p->hour &=0x3f;//24 hour AM/PM bit ivalid.
ch=i2c_read_byte();
i2c_send_ack();
p->minute=MSBTOLSM(ch);
ch=i2c_read_byte();
i2c_send_notack();
p->second=MSBTOLSM(ch);
i2c_stop();
EA=1;
}
void SD2000_read_hour(struct RTC_TIME *p){//为SDA2000读时间(时分秒)的函数
unsigned char ch;
i2c_start();
i2c_write_byte(RTCRHOUR);
if(i2c_wait_ack()){
// I2c read ack ok.
}
else{
//I2c read ack error.
return;
}
ch=i2c_read_byte();
i2c_send_ack();
ch=MSBTOLSM(ch);
ch &=0x3f;//24 hour AM/PM bit invalid.
ch=i2c_read_byte();
i2c_send_ack();
ch=MSBTOLSM(ch);
ch=i2c_read_byte();
i2c_send_notack();
ch=MSBTOLSM(ch);
i2c_stop();
}
void SD2000_set_status(unsigned char ch){//为SDA200的设置状态函数
EA=0;
i2c_start();
i2c_write_byte(RTCWSTAT);
if(i2c_wait_ack()){
//I2c set status ack ok.
}
else{
//I2c set status ack error.
EA=1;
return;
}
ch |=0x40;//interrupt 1 output vaild.
i2c_write_byte(ch);//24hour 1Hz interrupt.
i2c_wait_ack();
i2c_stop();
for(ch=0;ch<250;ch++){
;//delay;
}
i2c_start();
i2c_write_byte(RTCWINT1);
if(i2c_wait_ack()){
//I2c set Freq ack ok.
}
else{
// I2c set Freq ack error.
EA=1;
return;
}
i2c_write_byte(0);//f7~f0=0;
i2c_wait_ack();
i2c_write_byte(1);//f15=1,f14~f8=0;
i2c_wait_ack();
i2c_stop();
EA=1;
}
void SD2000_set_freq(unsigned char ch1,unsigned char ch2, unsigned char ch3){//为SDA200设置中断频率的函数
unsigned char ch;
EA=0;
i2c_start();
i2c_write_byte(RTCWSTAT);
if(i2c_wait_ack()){
//I2c set status ack ok.
}
else{
//I2c set status ack error.
EA=1;
return;
}
ch=MSBTOLSM(ch1);
i2c_write_byte(ch);//24hour 1Hz interrupt.
i2c_wait_ack();
i2c_stop();
for(ch=0;ch<250;ch++){
;//delay;
}
i2c_start();
i2c_write_byte(RTCWINT1);
if(i2c_wait_ack()){
//I2c set Freq ack ok.
}
else{
// I2c set Freq ack error.
EA=1;
return;
}
ch=MSBTOLSM(ch2);
// f0~f7=%bx",ch
i2c_write_byte(ch);//f7~f0=0;
i2c_wait_ack();
ch=MSBTOLSM(ch3);
// f8~f15=%bx",ch
i2c_write_byte(ch);//f15=1,f14~f8=0;
i2c_wait_ack();
i2c_stop();
EA=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -