?? 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 + -