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

📄 rtc.c

📁 51单片机C语言常用模块与综合系统设计实例精讲
💻 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 + -