1181zjf 发表于 2008-3-24 13:59:39

分享--调试成功的24c512和M41T81(RTC)的读写程序!

//-----i2c.h-----//
void NOPNOP(void);
void NOP_N(unsigned char n);
void SetSCL(unsigned char i);
void SetSDA(unsigned char i);
void Start(void);
void Stop(void);
void Ack(void);
void Nack(void);
void Check_Ack(void);
void Write_Bit0(void);
void Write_Bit1(void);
void Write_Byte(uchar Data);
uchar Read_Byte(void);
uintHEX2BCD(uint hex_data);
uchar BCD2HEX(uchar bcd_data);
void Rtc_Read_Nbyte(uchar Slave,uchar Address,uchar *Array,uchar n);
void Rtc_Write_1byte(uchar Slave,uchar Address,uchar Data);
void Rtc_Write_Nbyte(uchar Slave,uchar Address,uchar *Array,uchar Number);

void W_eeprom_Nbyte(uchar Slave,uint Address,uchar *Array,uchar Number);
void R_eeprom_Nbyte(uchar Slave,uint Address,uchar *Array,uchar n);

//--------在此设定芯片地址(根据地址实际情况改变)-------
#define W_ADD_EEPROM1 0xA0        //写字节命令及器件地址 1010 0 A1 A0 0
#define R_ADD_EEPROM1 0xA1        //读命令字节及器件地址 1010 0 A1 A0 1

#define W_ADD_EEPROM2 0xA2        //写字节命令及器件地址 1010 0 A1 A0 0
#define R_ADD_EEPROM2 0xA3        //读命令字节及器件地址 1010 0 A1 A0 1

//i2c.c

#include "includes.h"
uchar F_Flag=0;      //数据应答标志
/************************************************************
*   函数名称:void NOP_N(unsigned char n)
*   功    能:延时函数
*   入口参数:unsigned char n
*   出口参数:无
************************************************************/
void NOP_N(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
{
   asm volatile ("nop");
}
}
/************************************************************
*   函数名称:void NOPNOP(void)
*   功    能:延时函数
*   入口参数:无
*   出口参数:无
************************************************************/
void NOPNOP(void)                  
{
unsigned char i=0;
for(i=0;i<50;i++)
{
   asm volatile ("nop");
}
}
/************************************************************
*   函数名称:void SetSCL(unsigned char i)
*   功    能:IIC时钟线SCL设置
*   入口参数:无
*   出口参数:无
************************************************************/
void SetSCL(unsigned char i)                  
{
if(i==1) PORTB=PORTB|0x10;
else PORTB=PORTB&0xEF;
}
/************************************************************
*   函数名称:void SetSDA(unsigned char i)
*   功    能:IIC数据线SDA设置
*   入口参数:无
*   出口参数:无
************************************************************/
void SetSDA(unsigned char i)                  
{
if(i==1) PORTB=PORTB|0x20;
else PORTB=PORTB&0xDF;
}
/************************************************************
*   函数名称:void Start(void)
*   功    能:IIC总线开始信号
*   入口参数:无
*   出口参数:无
************************************************************/
void Start(void)                           
{
SetSDA(1);
SetSCL(1);
NOP_N(10);
SetSDA(0);
NOP_N(10);
SetSCL(0);
}
/************************************************************
*   函数名称:void Stop(void)
*   功    能:IIC总线停止信号
*   入口参数:无
*   出口参数:无
************************************************************/
void Stop(void)                           
{
SetSDA(0);
NOP_N(10);
SetSCL(1);
NOP_N(10);
SetSDA(1);
}
/************************************************************
*   函数名称:void Ack(void)
*   功    能:单片机应答信号
*   入口参数:无
*   出口参数:无
************************************************************/
void Ack(void)
{                           
SetSDA(0);
NOP_N(50);
SetSCL(1);   
NOP_N(50);
SetSCL(0);
NOPNOP();   
}
/************************************************************
*   函数名称:void Nack(void)
*   功    能:单片机非应答信号
*   入口参数:无
*   出口参数:无
************************************************************/
void Nack(void)                           
{
SetSDA(1);
SetSCL(1);
NOP_N(50);
SetSCL(0);
NOP_N(50);
}
/************************************************************
*   函数名称:void Check_Ack(void)
*   功    能:IIC器件应答信号检查
*   入口参数:无
*   出口参数:无
************************************************************/
void Check_Ack(void)                     
{
F_Flag=0;
DDRB=DDRB&0xDF;
SetSCL(1);
NOPNOP();
if((PINB&0x20)==0)
   {
    SetSCL(0);
    NOPNOP();
   }
else
    {
       F_Flag=1;
   SetSCL(0);
   NOPNOP();
        }
DDRB=DDRB|0x20;
}
/************************************************************
*   函数名称:void Write_Bit0(void)
*   功    能:向IIC总线写0
*   入口参数:无
*   出口参数:无
************************************************************/
void Write_Bit0(void)                     
{
SetSDA(0);
NOPNOP();
SetSCL(1);
NOPNOP();
SetSCL(0);
NOPNOP();
}
/************************************************************
*   函数名称:void Write_Bit1(void)
*   功    能:向IIC总线写1
*   入口参数:无
*   出口参数:无
************************************************************/
void Write_Bit1(void)                     
{
SetSDA(1);
NOPNOP();
SetSCL(1);
NOPNOP();
SetSCL(0);
NOPNOP();
}
/************************************************************
*   函数名称:uchar Read_Byte(void)
*   功    能:从IIC总线读一字节数据
*   入口参数:无
*   出口参数:无
************************************************************/
uchar Read_Byte(void)
{                     
uchar nn=0xff;            
uchar j;
DDRB=DDRB&0xDF;
for (j=0;j<8;j++)
    {
       SetSCL(1);
       NOP_N(20);        
      if((PINB&0x20)==0)
          {nn<<=1;
         nn=(nn&0xfe);               
         SetSCL(0);
               NOP_N(20);
               }
      else
      {nn<<=1;
         nn=(nn|0x01);               
         SetSCL(0);
               NOP_N(20);
               }
    }
DDRB=DDRB|0x20;
return(nn);            
}
/************************************************************
*   函数名称:void Write_Byte(uchar Data)
*   功    能:IIC写一个字节子程序
*   入口参数:uchar Data
*   出口参数:无
************************************************************/
void Write_Byte(uchar Data)            
{
uchar i;
for(i=0;i<8;i++)
   {
    if((Data&0x80)>0) Write_Bit1();         
    elseWrite_Bit0();      
    Data=Data<<1;                        
   }
}
/************************************************************
*   函数名称:uint HEX2BCD(uint hex_data)
*   功    能:HEX转为BCD子程序
*   入口参数:uint hex_data
*   出口参数:bcd_data
************************************************************/
uint HEX2BCD(uint hex_data)   
{         
unsigned int bcd_data,temp;
temp =hex_data%100;
bcd_data=((unsigned int)hex_data)/100<<8;
bcd_data=bcd_data|temp/10<<4;
bcd_data=bcd_data|temp%10;       
return(bcd_data);                       
}
/************************************************************
*   函数名称:uchar BCD2HEX(uchar bcd_data)
*   功    能:BCD转为HEX子程序
*   入口参数:uchar bcd_data
*   出口参数:uchar hex_data
************************************************************/
uchar BCD2HEX(uchar bcd_data)   
{
uchar hex_data;
hex_data=((bcd_data>>4)*10+(bcd_data & 0x0f));
return(hex_data);
}
/************************************************************
*   函数名称:void Rtc_Write_1byte()
*   功    能:RTC写一字节数据
*   入口参数:uchar Slave,uchar Address,uchar Data
*   出口参数:无
************************************************************/
void Rtc_Write_1byte(uchar Slave,uchar Address,uchar Data)
{
   do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);      
   do{Write_Byte(Address);Check_Ack();}while(F_Flag==1);
   do
          {               
           Write_Byte(Data);
           Check_Ack();               //检查应答位
          }while(F_Flag==1);
   Stop();
}
/************************************************************
*   函数名称:void Rtc_Read_Nbyte(uchar Slave,uchar Address,uchar *Array,uchar n)
*   功    能:RTC读N个字节子程序
*   入口参数:Slave(IIC器件地址),Address(起始地址),Array(读数据存放的数组),Number(读取的字节数)
*   出口参数:无
************************************************************/
void Rtc_Read_Nbyte(uchar Slave,uchar Address,uchar *Array,uchar n)
{
uchar data0=0,i=0;
do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);
do{Write_Byte(Address);Check_Ack();}while(F_Flag==1);
do{Start();Write_Byte(Slave+1);Check_Ack();}while(F_Flag==1);
for(i=0;i<n;i++)
{
   data0=Read_Byte();Ack();
   Array=BCD2HEX(data0);
}
Nack();
Stop();
}
/************************************************************
*   函数名称:void Rtc_Write_Nbyte(uchar Slave,uchar Address,uchar *Array,uchar Number)
*   功    能:RTC写N个字节子程序
*   入口参数:uchar Slave,uchar Address,uchar *Array,uchar Number
*   出口参数:无
************************************************************/
void Rtc_Write_Nbyte(uchar Slave,uchar Address,uchar *Array,uchar Number)
{
   uchar i;
   //开始->写IIC器件地址->检查应答位
   do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);
    //送起始地址->检查应答位         
   do{Write_Byte(Address);Check_Ack();}while(F_Flag==1);
    //写Number个数据
   for(i=0;i<Number;i++)      
    {
       do{Write_Byte(HEX2BCD(*Array));Check_Ack();}while(F_Flag==1);
   Array++;
    }         
   Stop();               
}       
/************************************************************
*   函数名称:void W_eeprom_Nbyte()
*   功    能:向24C512写N字节
*   入口参数:uchar Slave,uint Address,uchar *Array,uchar Number
*   出口参数:无
************************************************************/       
void W_eeprom_Nbyte(uchar Slave,uint Address,uchar *Array,uchar Number)
{
   uchar add_h,add_l,i;
   add_h=(0xff00&Address)>>8;
   add_l=(0x00ff&Address);
   //开始->写IIC器件地址->检查应答位
   do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);
    //送起始高地址->检查应答位   
   do{Write_Byte(add_h);Check_Ack();}while(F_Flag==1);
   //送起始低地址->检查应答位
   do{Write_Byte(add_l);Check_Ack();}while(F_Flag==1);
        //写Number个数据
for(i=0;i<Number;i++)      
    {
       do{Write_Byte(*Array);Check_Ack();}while(F_Flag==1);          
       Array++;
    }         
   Stop();
}
/************************************************************
*   函数名称:void R_eeprom_Nbyte()
*   功    能:从24C512读N字节
*   入口参数:uchar Slave,uint Address,uchar *Array,uchar n
*   出口参数:无
************************************************************/
void R_eeprom_Nbyte(uchar Slave,uint Address,uchar *Array,uchar n)
{
uchar data0=0,i=0;
uchar add_h,add_l;
add_h=(0xff00&Address)>>8;
add_l=(0x00ff&Address);
do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);
do{Write_Byte(add_h);Check_Ack();}while(F_Flag==1);
do{Write_Byte(add_l);Check_Ack();}while(F_Flag==1);
do{Start();Write_Byte(Slave+1);Check_Ack();}while(F_Flag==1);
for(i=0;i<n;i++)
   {
    data0=Read_Byte();Ack();
    Array=data0;
   }
Nack();
Stop();
}

1181zjf 发表于 2008-3-24 22:23:51

网上基于AVR的M41T81时钟程序几乎没有,希望对大家有帮助!!!!!!!!!!!
/*********************************************************
项         目:      mega128-test
编   译      器:      WINAVR20070525
目标   芯片:      MEGA128
时         钟:      7.3728M
*********************************************************/
#include"includes.h"

uchar time_wr_buf={0X00,0X39,0x1f,0x0a,0X02,25,12,7}; //时钟初始值
uchar time_rd_buf={0X00,0X00,0X00,0X00,0X00,0X00,0X00,0x00,0x00,0x00};
uchar eeprom_buf ={0X00,0X00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

uchari=0,j=0;
/************************************************************
*   函数名称: void port_init(void)
*   功    能:端口初始化
*   入口参数:无
*   出口参数:无
************************************************************/
void port_init(void)    // I/O端口初始化函数
{
PORTA = 0xff;
DDRA= 0x00;
PORTB = 0x3f; //PB6=0,OB7=0 禁止24c512写保护
DDRB= 0xff;
PORTC = 0xff; //m103 output only
DDRC= 0x00;
PORTD = 0xff;
DDRD= 0xff;//PD7=1,can_rst
PORTE = 0xff;
DDRE= 0xff;
PORTF = 0xff;
DDRF= 0x00;
PORTG = 0xff;
DDRG= 0x00;
}
/************************************************************
*   函数名称: void uart0_init(void)
*   功    能:串口初始化
*   入口参数:无
*   出口参数:无
************************************************************/
void uart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00;
UCSR0C = 0x06;
UBRR0L = 0x2F; //set baud rate lo
UBRR0H = 0x00; //set baud rate hi
UCSR0B = 0x18;
}
/************************************************************
*   函数名称: void init_devices(void)
*   功    能:系统初始化
*   入口参数:无
*   出口参数:无
************************************************************/
void init_devices(void)   
{
cli();            //disable all interrupts
//XMCRA = 0x0A;   // 外部存储器地址不分区,在RD、WR后插入2个等待周期
//XMCRB = 0x00;   //不使能总线保持功能,不释放地址线
port_init();      //I/O口初始化
uart0_init();   //串口初始化
mcp2515_init();   //mcp2515初始化
EIMSK=0x00;
EICRA=0x00;
EICRB=0x00;   //低电平产生中断
EIMSK=0x80;   //使能INT7
MCUCR = 0x00;   //
sei();          //re-enable interrupts
}


/************************************************************
*   函数名称: int main(void)
*   功    能:主函数
*   入口参数:无
*   出口参数:无
************************************************************/      
int main(void)
{
delay_ms(100);
init_devices();
delay_ms(100);
Rtc_Write_Nbyte(0xD0,0x00,time_wr_buf,8);
Rtc_Write_1byte(0xD0,0x01,0x00);
Rtc_Write_1byte(0xD0,0x0c,0x00);//清除HT位,当掉电发生时,允许更新当前时钟
delay_ms(100);
while(1)
      {       
       Rtc_Read_Nbyte(0xD0,0x01,time_rd_buf,7);       
       delay_ms(20);
          W_eeprom_Nbyte(W_ADD_EEPROM1,0x0000,time_rd_buf,7);
       delay_ms(20);
       R_eeprom_Nbyte(W_ADD_EEPROM1,0x0000,eeprom_buf,7);       
       delay_ms(20);
       PutString(eeprom_buf,7);
          delay_ms(500);
      }
return 0;
}

lovenashte 发表于 2008-8-20 11:31:53

谢谢分享!

mmf4125 发表于 2009-2-21 20:50:22

do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);应为Start();Write_Byte(Slave); do{Check_Ack();}while(F_Flag==1);吧?

mmf4125 发表于 2009-2-21 20:51:21

do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);?
    //送起始高地址->检查应答位   
   do{Write_Byte(add_h);Check_Ack();}while(F_Flag==1); ?
   //送起始低地址->检查应答位
   do{Write_Byte(add_l);Check_Ack();}while(F_Flag==1);   ??????????????

xjmlfm1 发表于 2010-3-11 23:51:49

mark

shaoye 发表于 2010-5-24 09:54:39

谢谢分享

Ruify_lee 发表于 2012-2-22 17:31:56

ddcchh 发表于 2012-12-24 09:07:29

支持强人!

newywx 发表于 2014-4-25 09:27:12

1181zjf 发表于 2008-3-24 22:23
网上基于AVR的M41T81时钟程序几乎没有,希望对大家有帮助!!!!!!!!!!!
/*********************************** ...

兄弟,这个MT41T81你用下来准不?相对于一般的DS1302怎样?

1181zjf 发表于 2014-4-25 09:41:07

newywx 发表于 2014-4-25 09:27
兄弟,这个MT41T81你用下来准不?相对于一般的DS1302怎样?

这个得问晶振啊!

newywx 发表于 2014-4-25 09:45:17

一般时钟芯片用的那种3*8的晶振不知道怎样,你选的时候有什么特别注意的不?

newywx 发表于 2014-4-25 11:24:59

1181zjf 发表于 2014-4-25 09:41
这个得问晶振啊!

兄弟,网上看了这个32768晶振有标6pf和12.5pf的,你当时用的是哪种?

newywx 发表于 2014-4-30 09:53:05

本帖最后由 newywx 于 2014-4-30 12:22 编辑

买了号称是12.5pf的32768的晶振,搭了一个电路,程序是参照你的这个改的,可是读出来的时间都是A5,哪位兄弟看看哪里不对?


/*
MCU:STC12LE5A60S2@22.1184M晶振
RTC:M41T81S
外部中断0(P3.2)启动按键脚
*/

#include "stc12c5a60s2.h"
#include<intrins.h>


sbit        RTC_SDA=P1^6;        //时钟芯片 SDA控制P1.6
sbit        RTC_SCL=P1^7;        //时钟芯片 SCL控制P1.7


/*=====年月日周时分秒 0.1秒=====
time_wr_buf=year,time_wr_buf=month,time_wr_buf=day,time_wr_buf=week,
time_wr_buf=hour,time_wr_buf=minute,time_wr_buf=second,time_wr_buf=tenth
*/

unsigned char time_wr_buf={44,33,22,11,2,29,4,14}; //时钟初始值2014年4月29日,星期二,11点22分33秒44分秒
unsigned char time_rd_buf={0X00,0X00,0X00,0X00,0X00,0X00,0X00,0x00};
unsigned char F_Flag=0;      //数据应答标志

#define                BUF_LENTH        128                //定义串口接收缓冲长度
unsigned char         uart0_wr;                //写指针
unsigned char         uart0_rd;                //读指针
unsigned char         xdata RX0_Buffer;        //接收缓冲
bit                B_TI;

/*=====函数定义=====*/
void Uart0_init(void);           //串口初始化
void DelayNus(unsigned int delay1us); //us级延时
void Delay1ms(unsigned int mDelay1);//ms级延时
void SendByte(unsigned char dat);          //串口发送单个数据


//时钟芯片相关操作函数
void Start(void);
void Stop(void);
void Ack(void);
void Nack(void);
void Check_Ack(void);
void Write_Bit0(void);
void Write_Bit1(void);
void Write_Byte(unsigned char Data);
unsigned char Read_Byte(void);
unsigned intHEX2BCD(unsigned int hex_data);
unsigned char BCD2HEX(unsigned char bcd_data);
void Rtc_Read_Nbyte(unsigned char Slave,unsigned char Address,unsigned char *Array,unsigned char n);
void Rtc_Write_1byte(unsigned char Slave,unsigned char Address,unsigned char Data);
void Rtc_Write_Nbyte(unsigned char Slave,unsigned char Address,unsigned char *Array,unsigned char Number);




/*=====主函数=====*/
void main()
{
        Delay1ms(1000);
        Uart0_init();
        P4SW=0x30;
        Rtc_Write_Nbyte(0xD0,0x00,time_wr_buf,8);
        Rtc_Write_1byte(0xD0,0x01,0x00);
        Rtc_Write_1byte(0xD0,0x0c,0x00);//清除HT位,当掉电发生时,允许更新当前时钟

        while(1)
        {
                Rtc_Read_Nbyte(0xD1,0x00,time_rd_buf,8);       //读取M41T81时间
                Delay1ms(5000);               

        }
}


/*=====串口及相关中断初始化=====*/
void Uart0_init(void)
{
        IT0 = 1;        // 外部中断0下降沿中断,板上按键
        EX0 = 1;        // 外部中断0允许

        TMOD = 0x20;
        TH1= 0xFF;       //波特率115200        ,22.1184MHz晶振
        TL1= 0xFF;
        SCON = 0x50;       //串行口控制寄存器:方式1,运行接收
        PCON = PCON|0x80;//电源控制寄存器:SMOD=1,数据传输率加倍
        TR1= 1;                     //启动定时器
        ES= 1;
        EA = 1;
}

/*=====延时函数=====*/


/* us级别延时函数,不准
22.1184MHz晶振下实测:
DelayNus(1)时:2.4us
DelayNus(2)时:3.2us
DelayNus(3)时:3.8us
DelayNus(4)时:4.5us
DelayNus(5)时:5.3us
DelayNus(6)时:6.0us
DelayNus(7)时:6.7us
DelayNus(8)时:7.4us
*/
void DelayNus(unsigned int delay1us)
{
        while(delay1us--);
}


void Delay1ms(unsigned int mDelay1)        //1ms延时,22.1184M晶振
{
        unsigned int mDelay2;
        for(;mDelay1>0;mDelay1--)
        {       
                for(mDelay2=0;mDelay2<2000;mDelay2++)
                {;;}
        }
}


void SendByte(unsigned char dat1)        //串口发送一个字节
{
        SBUF=dat1;                          //发送数据送缓冲
        while(!TI);                          //等待发送完成
        TI=0;
}



/************************************************************
*   函数名称:void Start(void)
*   功    能:IIC总线开始信号
*   入口参数:无
*   出口参数:无
************************************************************/
void Start(void)       
{
        RTC_SDA=1;       /*发送起始条件的数据信号*/
        DelayNus(1);
        RTC_SCL=1;
        DelayNus(10); /*起始条件建立时间大于4.7us,延时*/
        RTC_SDA=0;       /*发送起始信号*/
        DelayNus(10); /* 起始条件锁定时间大于4μs*/
        RTC_SCL=0;       /*钳住I2C总线,准备发送或接收数据 */
        DelayNus(2);
}


/************************************************************
*   函数名称:void Stop(void)
*   功    能:IIC总线停止信号
*   入口参数:无
*   出口参数:无
************************************************************/
void Stop(void)
{
        RTC_SDA=0;        /*发送结束条件的数据信号*/
        DelayNus(1);
        RTC_SCL=1;
        DelayNus(10);
        RTC_SDA=1; /*发送I2C总线结束信号*/
        DelayNus(2);
}


/************************************************************
*   函数名称:void Ack(void)
*   功    能:主器件为接收方,从器件为发送方时,从器件等待主器件的应答信号(单片机发送应答信号)
*   入口参数:无
*   出口参数:无
************************************************************/
void Ack(void)
{
        RTC_SDA=0;          //数据线保持低,时钟线发生一次从高低的跳变,发送一个应答信号
        DelayNus(5);
        RTC_SCL=1;
        DelayNus(10);//>4us
        RTC_SCL=0;
        DelayNus(5);
}


/************************************************************
*   函数名称:void Nack(void)
*   功    能:主器件为接收方,从器件为发送方时,非应答信号(单片机发送非应答信号)
*   入口参数:无
*   出口参数:无
************************************************************/
void Nack(void)
{
        RTC_SDA=1;        //数据线保持低,时钟线发生一次从高低的跳变,没有应答
        DelayNus(5);
        RTC_SCL=1;       
        DelayNus(10);//>4us
        RTC_SCL=0;
        DelayNus(4);
}


/************************************************************
*   函数名称:void Check_Ack(void)
*   功    能:IIC器件应答信号检查
*   入口参数:无
*   出口参数:无 111111
************************************************************/
void Check_Ack(void)                        
{
        F_Flag=0;
        RTC_SDA=0;   
        RTC_SCL=1;
        DelayNus(5);
        if(RTC_SDA==0)
        {
          RTC_SCL=0;
          DelayNus(5);
        }
        else
        {
               F_Flag=1;
          RTC_SCL=0;
          DelayNus(5);
        }
        RTC_SDA=1;
}



/************************************************************
*   函数名称:void Write_Bit0(void)
*   功    能:向IIC总线写0
*   入口参数:无
*   出口参数:无
************************************************************/
void Write_Bit0(void)                     
{
        RTC_SDA=0;
        DelayNus(1);
        RTC_SCL=1;
        DelayNus(5);
        RTC_SCL=0;
        DelayNus(2);
}



/************************************************************
*   函数名称:void Write_Bit1(void)
*   功    能:向IIC总线写1
*   入口参数:无
*   出口参数:无
************************************************************/
void Write_Bit1(void)                     
{
        RTC_SDA=1;
        DelayNus(1);
        RTC_SCL=1;
        DelayNus(5);
        RTC_SCL=0;
        DelayNus(2);
}



/************************************************************
*   函数名称:void Write_Byte(unsigned char Data)
*   功    能:IIC写一个字节子程序
*   入口参数:uchar Data
*   出口参数:无
************************************************************/
void Write_Byte(unsigned char Data)            
{
        unsigned char i;
        for(i=0;i<8;i++)
        {
                if((Data&0x80)>0) Write_Bit1();         
                elseWrite_Bit0();         
                Data=Data<<1;                        
        }
}



/************************************************************
*   函数名称:uchar Read_Byte(void)
*   功    能:从IIC总线读一字节数据
*   入口参数:无
*   出口参数:无 111111
************************************************************/
unsigned char Read_Byte(void)
{                     
        unsigned char nn=0xff;            
        unsigned char j;
        RTC_SDA=1;               /*置数据线为输入方式*/
        for (j=0;j<8;j++)
        {
                RTC_SCL=0;
                DelayNus(20);
                if(RTC_SDA==0)
                {
                        nn<<=1;
                        nn=(nn&0xfe);                  
                        RTC_SCL=0;
                        DelayNus(10);
                }
                else
                {
                        nn<<=1;
                        nn=(nn|0x01);                  
                        RTC_SCL=0;
                        DelayNus(10);
                }
        }
        RTC_SCL=0;
        DelayNus(1);
        return(nn);               
}



/************************************************************
*   函数名称:uint HEX2BCD(unsigned int hex_data)
*   功    能:HEX转为BCD子程序
*   入口参数:uint hex_data
*   出口参数:bcd_data
************************************************************/
unsigned int HEX2BCD(unsigned int hex_data)   
{            
unsigned int bcd_data,temp;
temp =hex_data%100;
bcd_data=((unsigned int)hex_data)/100<<8;
bcd_data=bcd_data|temp/10<<4;
bcd_data=bcd_data|temp%10;   
return(bcd_data);
}


/************************************************************
*   函数名称:uchar BCD2HEX(unsigned char bcd_data)
*   功    能:BCD转为HEX子程序
*   入口参数:uchar bcd_data
*   出口参数:uchar hex_data
************************************************************/
unsigned char BCD2HEX(unsigned char bcd_data)      
{
unsigned char hex_data;
hex_data=((bcd_data>>4)*10+(bcd_data & 0x0f));
return(hex_data);
}



/************************************************************
*   函数名称:void Rtc_Read_Nbyte(unsigned char Slave,unsigned char Address,unsigned char *Array,unsigned char n)
*   功    能:RTC读N个字节子程序
*   入口参数:Slave(IIC器件地址),Address(起始地址),Array(读数据存放的数组),Number(读取的字节数)
*   出口参数:无
************************************************************/
void Rtc_Read_Nbyte(unsigned char Slave,unsigned char Address,unsigned char *Array,unsigned char n)
{
unsigned char data0=0,i=0;
do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);
do{Write_Byte(Address);Check_Ack();}while(F_Flag==1);
do{Start();Write_Byte(Slave+1);Check_Ack();}while(F_Flag==1);
for(i=0;i<n;i++)
{
   data0=Read_Byte();Ack();
   Array=BCD2HEX(data0);
   time_rd_buf=Array;
}
Nack();
Stop();
}


/************************************************************
*   函数名称:void Rtc_Write_1byte()
*   功    能:RTC写一字节数据
*   入口参数:uchar Slave,unsigned char Address,unsigned char Data
*   出口参数:无
************************************************************/
void Rtc_Write_1byte(unsigned char Slave,unsigned char Address,unsigned char Data)
{
   do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);         
   do{Write_Byte(Address);Check_Ack();}while(F_Flag==1);
   do
{   
   Write_Byte(Data);
   Check_Ack();               //检查应答位
}while(F_Flag==1);
   Stop();
}



/************************************************************
*   函数名称:void Rtc_Write_Nbyte(unsigned char Slave,unsigned char Address,unsigned char *Array,unsigned char Number)
*   功    能:RTC写N个字节子程序
*   入口参数:uchar Slave,unsigned char Address,unsigned char *Array,unsigned char Number
*   出口参数:无
************************************************************/
void Rtc_Write_Nbyte(unsigned char Slave,unsigned char Address,unsigned char *Array,unsigned char Number)
{
   unsigned char i;
   //开始->写IIC器件地址->检查应答位
   do{Start();Write_Byte(Slave);Check_Ack();}while(F_Flag==1);
    //送起始地址->检查应答位            
   do{Write_Byte(Address);Check_Ack();}while(F_Flag==1);   
    //写Number个数据
   for(i=0;i<Number;i++)      
    {
do{Write_Byte(HEX2BCD(*Array));Check_Ack();}while(F_Flag==1);
   Array++;
    }            
   Stop();                  
}

void INT0_int (void) interrupt 0//启动按键中断脚
{
        SendByte(time_rd_buf);                  //年       
        SendByte(time_rd_buf);                  //月
        SendByte(time_rd_buf);                  //日
        SendByte(time_rd_buf);                  //星期
        SendByte(time_rd_buf);                  //时
        SendByte(time_rd_buf);               //分
        SendByte(time_rd_buf);                  //秒
        SendByte(time_rd_buf);                  //十分之一秒
}



/**********************************************/
void UART0_RCV (void) interrupt 4
{
        if(RI)
        {
                RI = 0;
                RX0_Buffer = SBUF;
                if(++uart0_wr >= BUF_LENTH)        uart0_wr = 0;
        }

        if(TI)
        {
                TI = 0;
                B_TI = 1;
        }
}
页: [1]
查看完整版本: 分享--调试成功的24c512和M41T81(RTC)的读写程序!