搜索
bottom↓
回复: 28

新发布一个用模拟I2C操作的DS3231(时钟芯片)完整程序

[复制链接]

出0入0汤圆

发表于 2007-11-8 17:12:36 | 显示全部楼层 |阅读模式
自己花了两天的时间来调试一个时钟芯片:DS3231,刚开始参考高手写的用硬件I2C来操作DS3231较简单
然后自己模仿硬件I2C的工作原理写了一个用模拟I2C来操作的程序,经多次调试之后终于成功.
由于本网站的DS3231程序都不完整,现发布一个完整程序,希望对大家有用.


/**********************************
晶振:11.0592M
模拟I2C总线操作DS3231
2007/11/08
fjh
/**********************************/
#include <iom128v.h>
#include <macros.h>
#include "lcd.c"
#define uchar unsigned char
#define uint  unsigned int

#define SCL_H  PORTD|=(1<<0)
#define SCL_L  PORTD&=~(1<<0)

#define SDA_H  PORTD|=(1<<1)
#define SDA_L  PORTD&=~(1<<1)

uchar year,month,date,hour,minute,second;
/******************应用程序********************/
void timer1_init(void);
uchar BCD2HEX(uchar val);
uchar B_BCD(uchar val);
void delay(uchar us);
void Start(void);
void Stop(void);
void SendByte(uchar Dat);
uchar ReceiveByte(uchar b);
void I2cByteWrite(uchar device,uint addr,uchar bytedata);
uchar I2cByteRead(uchar device,uint addr);
void get_show_time(void);
/**********************************************/
void port_init(void)
{
PORTA = 0xff;
DDRA  = 0xff;

PORTB = 0xff;
DDRB  = 0xff;

PORTC = 0xff;
DDRC  = 0xff;

PORTD = 0x00;
DDRD  = 0xff;

PORTE = 0xff;
DDRE  = 0xff;

PORTF = 0xff;
DDRF  = 0xff;

PORTG = 0x00;
DDRG  = 0x00;
}

// actual value:  1.000Sec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xD5; //setup
TCNT1L = 0xD1;
OCR1AH = 0x2A;
OCR1AL = 0x2F;
OCR1BH = 0x2A;
OCR1BL = 0x2F;
OCR1CH = 0x2A;
OCR1CL = 0x2F;
ICR1H  = 0x2A;
ICR1L  = 0x2F;
TCCR1A = 0x00;
TCCR1B = 0x05; //start Timer
TIMSK  = 0x04; //timer interrupt sources
}

#pragma interrupt_handler timer1_ovf_isr:15
void timer1_ovf_isr(void)
{
  //TIMER1 has overflowed
  TCNT1H = 0xD5; //reload counter high value
  TCNT1L = 0xD1; //reload counter low value
  PORTF=~PORTF;
  get_show_time();
}

uchar BCD2HEX(uchar val)   //BCD转换为Byte
{
    unsigned char i;
    i= val&0x0f;
    val >>= 4;
    val &= 0x0f;
    val *= 10;
    i += val;
   
    return i;
}

uchar B_BCD(uchar val)//B码转换为BCD码
{
  uchar i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}

void delay(uchar us)
{
   while(us--);
}
/************************START***************************/
void Start(void)
{
  SDA_H;
  delay(5);
  SCL_H;
  delay(5);
  SDA_L;
  delay(5);
}
/********************************************************/
/************************STOP****************************/
void Stop(void)
{
  SDA_L;
  delay(5);
  SCL_H;
  delay(5);
  SDA_H;
  delay(5);
}
/********************************************************/
/***********向I2C总线发送一个字节+接收一个ACK************/
void SendByte(uchar Dat)
{
  uchar i=0;
  uchar T_Data=0;
  
  DDRD|=(1<<1);//输出
  SCL_L;
  delay(10);
  T_Data=Dat;
  for(i=0;i<8;i++)
    {           
  
          if(T_Data&0x80)
            SDA_H;
          else
            SDA_L;
          delay(5);
      SCL_L;
          delay(5);
          SCL_H;
          delay(5);
          T_Data=T_Data<<1;
          SCL_L;
          delay(5);
   }
  SDA_H;//释放总线
  delay(5);
  SCL_L;     /*********************/
  delay(5);//接收一个ACK,不做处理
  SCL_H;     /*********************/
  delay(5);

  SCL_L;
}
/********************************************************/
/**********从I2C总线上读取一个字节+发送一个ACK***********/
uchar ReceiveByte(uchar b)
{
  uchar i;
  uchar temp;
  uchar Dat=0;
/*
  SDA_H;
  delay(5);
  SCL_L;
  delay(5);
*/
  DDRD&=~(1<<1);//输入
  for(i=0;i<8;i++)
    {
          SCL_H;
      delay(5);

          Dat=Dat<<1;
          delay(5);
          temp=PIND;
          if(temp&0x02)
            Dat|=0x01;
          else
            Dat|=0x00;
         delay(5);
         SCL_L;
          delay(5);
    }
  DDRD|=(1<<1);//输出
  
  if(b)//每收一个数后发送ACK或nACK
    SDA_H;
  else
    SDA_L;
       
  delay(5);
  SCL_H;
  delay(5);
  SCL_L;
  delay(5);
  SDA_H;        //释放总线
  delay(100);
  return Dat;
}
/****************************************************/
/***********将一个字节写入DS3231指定的地址***********/
void I2cByteWrite(uchar device,uint addr,uchar bytedata)
{
  Start();
  delay(5);
  SendByte(device);
  delay(5);
  SendByte(addr);
  delay(5);
  SendByte(bytedata);
  delay(5);
  Stop();
}
/****************************************************/
/************从DS3231指定的地址读一个字节************/
uchar I2cByteRead(uchar device,uint addr)
{
  uchar Dat=0;
  
  Start();
  SendByte(device);
  delay(5);
  SendByte(addr);
  delay(5);
  Start();//Restart
  SendByte(0xd1);//读数
  delay(5);
  Dat=ReceiveByte(1);//只接收一个字节,所以发nACK
  Stop();
  return Dat;
}
/***************************************************/
/*********************读取时间**********************/
void Readtime(void)
{
  year=I2cByteRead(0xd0,0x06);  //年
  month=I2cByteRead(0xd0,0x05); //月
  date=I2cByteRead(0xd0,0x04);  //日
  hour=I2cByteRead(0xd0,0x02);  //时
  minute=I2cByteRead(0xd0,0x01);//分
  second=I2cByteRead(0xd0,0x00);//秒
}
/***************************************************/
/****************修改时间,BCD码输入*****************/
void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec)
{
  uchar temp=0;
  
  temp=B_BCD(yea);
  I2cByteWrite(0xD0,0x06,temp);//修改年
  
  temp=B_BCD(mon);
  I2cByteWrite(0xD0,0x05,temp);//修改月
   
  temp=B_BCD(da);
  I2cByteWrite(0xD0,0x04,temp);//修改日
  
  temp=B_BCD(hou);
  I2cByteWrite(0xD0,0x02,temp);//修改时
  
  temp=B_BCD(min);
  I2cByteWrite(0xD0,0x01,temp);//修改分
  
  temp=B_BCD(sec);
  I2cByteWrite(0xD0,0x00,temp);//修改秒
}
/****************************************************/
/****************读取时间 计算 并显示****************/
void get_show_time(void)
{
uchar temp1,temp2,a=0,b=0;

temp1=I2cByteRead(0xd0,0x06);  //年
temp2=BCD2HEX(temp1);
a=temp2/10;
b=temp2-a*10;
disp_two_char (0x81,tab[a],tab);
disp_one_word(0x82,"年");

temp1=I2cByteRead(0xd0,0x05);  //月
temp2=BCD2HEX(temp1);
a=temp2/10;
b=temp2-a*10;
disp_two_char (0x83,tab[a],tab);
disp_one_word(0x84,"月");

temp1=I2cByteRead(0xd0,0x04);  //日
temp2=BCD2HEX(temp1);
a=temp2/10;
b=temp2-a*10;
disp_two_char (0x85,tab[a],tab);
disp_one_word(0x86,"日");  

temp1=I2cByteRead(0xd0,0x02);  //时 24小时制
temp1&=0x3f;                  
temp2=BCD2HEX(temp1);
a=temp2/10;
b=temp2-a*10;
disp_two_char (0x91,tab[a],tab);
disp_one_word(0x92,"时");

temp1=I2cByteRead(0xd0,0x01);  //分
temp2=BCD2HEX(temp1);
a=temp2/10;
b=temp2-a*10;
disp_two_char (0x93,tab[a],tab);
disp_one_word(0x94,"分");  
  
temp1=I2cByteRead(0xd0,0x00);  //秒
temp2=BCD2HEX(temp1);
a=temp2/10;
b=temp2-a*10;
disp_two_char (0x95,tab[a],tab);
disp_one_word(0x96,"秒");  
}
/****************************************************/
/*******************MAIN函数*************************/
void main()
{
  CLI();
  port_init();
  init_lcd ();
  I2cByteWrite(0xD0,0x0e,0);
  I2cByteWrite(0xD0,0x0f,0);
  ModifyTime(7,11,20,12,59,00);//初始化时钟,2007/11/20,12/59/00
                               //小时采用24小时制
  timer1_init();
  SEI();
  lat_disp (0x00,0x00);//显示点阵
  while(1)
    {

    }  
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2007-11-10 11:46:16 | 显示全部楼层
请问有哪位大侠用过DS3231,给我指点一下,为什么我从温度寄存器里读出来的数值循环递增
我认为温度值应该是不变的才对啊.谢谢!

出0入0汤圆

发表于 2008-10-5 16:39:09 | 显示全部楼层
不错,先行用用,之前用CV编过一个,不管用

出0入0汤圆

发表于 2009-2-2 21:05:06 | 显示全部楼层
我移制到STM32&nbsp;出现不能读出的问题,大家看看那里的问题

#include&nbsp;"stm32f10x_lib.h"



extern&nbsp;void&nbsp;Delay(vu32&nbsp;nCount)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;&nbsp;//调用外部函数体函数

extern&nbsp;void&nbsp;&nbsp;ds3231_chang_OUT(void&nbsp;)&nbsp;&nbsp;&nbsp;;&nbsp;&nbsp;//&nbsp;&nbsp;

extern&nbsp;void&nbsp;&nbsp;ds3231_chang_IN(void&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;

extern&nbsp;void&nbsp;LCD_init(void)&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//调用外部函数体函数

extern&nbsp;void&nbsp;LCD_set_xy(unsigned&nbsp;char&nbsp;x,&nbsp;unsigned&nbsp;char&nbsp;y)&nbsp;;&nbsp;&nbsp;//调用外部函数体函数

extern&nbsp;void&nbsp;xianshishuzi(unsigned&nbsp;char&nbsp;X,unsigned&nbsp;char&nbsp;Y,&nbsp;unsigned&nbsp;int&nbsp;s)&nbsp;;&nbsp;&nbsp;//调用外部函数体函数

extern&nbsp;void&nbsp;xianshishuzi3(unsigned&nbsp;char&nbsp;X,unsigned&nbsp;char&nbsp;Y,&nbsp;unsigned&nbsp;int&nbsp;s)&nbsp;;&nbsp;&nbsp;//调用外部函数体函数

extern&nbsp;LCD_Write_char_string(unsigned&nbsp;char&nbsp;X,unsigned&nbsp;char&nbsp;Y,&nbsp;unsigned&nbsp;char&nbsp;*s)&nbsp;;//调用外部函数体函数





&nbsp;/********************************************************/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;



#define&nbsp;SCL_H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(GPIO_SetBits(GPIOA,&nbsp;GPIO_Pin_0))

#define&nbsp;SCL_L&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(GPIO_ResetBits(GPIOA,&nbsp;GPIO_Pin_0))

&nbsp;&nbsp;

#define&nbsp;SDA_H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(GPIO_SetBits(GPIOA,&nbsp;GPIO_Pin_1))

#define&nbsp;SDA_L&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(GPIO_ResetBits(GPIOA,&nbsp;GPIO_Pin_1))&nbsp;



unsigned&nbsp;char&nbsp;year,month,date,hour,minute,second;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//读取时间参数



unsigned&nbsp;char&nbsp;BCD2HEX(unsigned&nbsp;char&nbsp;val)&nbsp;&nbsp;&nbsp;//BCD转换为Byte&nbsp;

{&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;i=&nbsp;val&0x0f;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;val>>=&nbsp;4;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;&=&nbsp;0x0f;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;*=&nbsp;10;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;+=&nbsp;val;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;i;&nbsp;

}&nbsp;



unsigned&nbsp;char&nbsp;B_BCD(unsigned&nbsp;char&nbsp;val)//B码转换为BCD码&nbsp;

{&nbsp;

&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i,j,k;&nbsp;

&nbsp;&nbsp;i=val/10;&nbsp;

&nbsp;&nbsp;j=val%10;&nbsp;

&nbsp;&nbsp;k=j+(i&lt;&lt;4);&nbsp;

&nbsp;&nbsp;return&nbsp;k;&nbsp;

}&nbsp;



void&nbsp;delay1(unsigned&nbsp;char&nbsp;us)&nbsp;

{&nbsp;

&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;i=200;

&nbsp;&nbsp;&nbsp;while(us--)

&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(i)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i--;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;}

}

&nbsp;&nbsp;/************************START***************************/&nbsp;

void&nbsp;Start(void)&nbsp;

{&nbsp;

&nbsp;&nbsp;SCL_L;&nbsp;&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;SDA_H;&nbsp;

&nbsp;&nbsp;delay1(5);

&nbsp;&nbsp;SCL_H;&nbsp;

&nbsp;&nbsp;delay1(5);

&nbsp;&nbsp;SDA_L;&nbsp;

&nbsp;&nbsp;delay1(5);

&nbsp;

}&nbsp;&nbsp;

/********************************************************/&nbsp;

/************************STOP****************************/&nbsp;

void&nbsp;Stop(void)&nbsp;

{&nbsp;

&nbsp;&nbsp;SCL_L;&nbsp;&nbsp;

&nbsp;&nbsp;delay1(5);

&nbsp;&nbsp;SDA_L;&nbsp;

&nbsp;&nbsp;delay1(5);

&nbsp;&nbsp;SCL_H;&nbsp;

&nbsp;&nbsp;delay1(10);

&nbsp;&nbsp;SDA_H;&nbsp;

&nbsp;&nbsp;delay1(5);

}&nbsp;

/********************************************************/&nbsp;



/********************************************************/&nbsp;

/***********向I2C总线发送一个字节+接收一个ACK************/&nbsp;

void&nbsp;SendByte(unsigned&nbsp;char&nbsp;Dat)&nbsp;

{&nbsp;

&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i=0;&nbsp;

&nbsp;&nbsp;unsigned&nbsp;char&nbsp;T_Data=0;&nbsp;

&nbsp;&nbsp;SCL_L;&nbsp;&nbsp;

&nbsp;&nbsp;delay1(10);&nbsp;

&nbsp;&nbsp;T_Data=Dat;&nbsp;

&nbsp;&nbsp;for(i=0;i&lt;8;i++)&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(T_Data&0x80)&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDA_H;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDA_L;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_L;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_H;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T_Data=T_Data&lt;&lt;1;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_L;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;&nbsp;}&nbsp;

&nbsp;&nbsp;SDA_H;//释放总线&nbsp;&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;&nbsp;

&nbsp;&nbsp;SCL_L;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*********************/&nbsp;

&nbsp;&nbsp;delay1(5);//接收一个ACK,不做处理&nbsp;

&nbsp;&nbsp;SCL_H;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*********************/&nbsp;

&nbsp;&nbsp;delay1(5);

&nbsp;&nbsp;SCL_L;&nbsp;

}&nbsp;

&nbsp;&nbsp;/********************************************************/&nbsp;

/**********从I2C总线上读取一个字节+发送一个ACK***********/&nbsp;

unsigned&nbsp;char&nbsp;ReceiveByte(unsigned&nbsp;char&nbsp;b)&nbsp;

{&nbsp;

&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i;&nbsp;

&nbsp;&nbsp;unsigned&nbsp;char&nbsp;Dat=0;&nbsp;



&nbsp;&nbsp;ds3231_chang_IN();

&nbsp;&nbsp;SCL_L;&nbsp;&nbsp;

&nbsp;&nbsp;delay1(10);&nbsp;

&nbsp;&nbsp;for(i=0;i&lt;8;i++)&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_H;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dat=Dat&lt;&lt;1;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay1(5);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(GPIO_ReadInputDataBit(GPIOA,&nbsp;GPIO_Pin_1)==1)&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dat|=0x01;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dat|=0x00;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCL_L;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay1(5);&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;ds3231_chang_OUT();&nbsp;

&nbsp;&nbsp;if(b)//每收一个数后发送ACK或nACK&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;SDA_H;&nbsp;

&nbsp;&nbsp;else&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;SDA_L;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;SCL_H;&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;SCL_L;&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;SDA_H;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//释放总线&nbsp;

&nbsp;&nbsp;delay1(100);&nbsp;

&nbsp;&nbsp;return&nbsp;Dat;&nbsp;

}

&nbsp;/***********将一个字节写入DS3231指定的地址***********/&nbsp;

void&nbsp;I2cByteWrite(unsigned&nbsp;char&nbsp;device,unsigned&nbsp;int&nbsp;addr,unsigned&nbsp;char&nbsp;bytedata)&nbsp;

{&nbsp;

&nbsp;&nbsp;Start();&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;SendByte(device);&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;SendByte(addr);&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;SendByte(bytedata);&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;Stop();&nbsp;

}&nbsp;

/****************************************************/&nbsp;

/************从DS3231指定的地址读一个字节************/&nbsp;

unsigned&nbsp;char&nbsp;I2cByteRead(unsigned&nbsp;char&nbsp;device,unsigned&nbsp;int&nbsp;addr)&nbsp;

{&nbsp;

&nbsp;&nbsp;unsigned&nbsp;char&nbsp;Dat=0;&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;Start();&nbsp;

&nbsp;&nbsp;SendByte(device);&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;SendByte(addr);&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;Start();//Restart&nbsp;

&nbsp;&nbsp;SendByte(0xd1);//读数&nbsp;

&nbsp;&nbsp;delay1(5);&nbsp;

&nbsp;&nbsp;Dat=ReceiveByte(1);//只接收一个字节,所以发nACK&nbsp;

&nbsp;&nbsp;Stop();&nbsp;

&nbsp;&nbsp;return&nbsp;Dat;&nbsp;

}&nbsp;

/***************************************************/



/*********************读取时间**********************/&nbsp;

void&nbsp;Readtime(void)&nbsp;

{&nbsp;

&nbsp;&nbsp;year=I2cByteRead(0xd0,0x06);&nbsp;&nbsp;//年&nbsp;

&nbsp;&nbsp;month=I2cByteRead(0xd0,0x05);&nbsp;//月&nbsp;&nbsp;

&nbsp;&nbsp;date=I2cByteRead(0xd0,0x04);&nbsp;&nbsp;//日&nbsp;

&nbsp;&nbsp;hour=I2cByteRead(0xd0,0x02);&nbsp;&nbsp;//时&nbsp;

&nbsp;&nbsp;minute=I2cByteRead(0xd0,0x01);//分&nbsp;

&nbsp;&nbsp;second=I2cByteRead(0xd0,0x00);//秒&nbsp;

}&nbsp;

/***************************************************/

&nbsp;/***************************************************/&nbsp;

/****************修改时间,BCD码输入*****************/&nbsp;

void&nbsp;ModifyTime(unsigned&nbsp;char&nbsp;yea,unsigned&nbsp;char&nbsp;mon,unsigned&nbsp;char&nbsp;da,unsigned&nbsp;char&nbsp;hou,unsigned&nbsp;char&nbsp;min,unsigned&nbsp;char&nbsp;sec)&nbsp;

{&nbsp;

&nbsp;&nbsp;unsigned&nbsp;char&nbsp;temp=0;&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;temp=B_BCD(yea);&nbsp;

&nbsp;&nbsp;I2cByteWrite(0xD0,0x06,temp);//修改年&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;temp=B_BCD(mon);&nbsp;

&nbsp;&nbsp;I2cByteWrite(0xD0,0x05,temp);//修改月&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;temp=B_BCD(da);&nbsp;

&nbsp;&nbsp;I2cByteWrite(0xD0,0x04,temp);//修改日&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;temp=B_BCD(hou);&nbsp;

&nbsp;&nbsp;I2cByteWrite(0xD0,0x02,temp);//修改时&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;temp=B_BCD(min);&nbsp;

&nbsp;&nbsp;I2cByteWrite(0xD0,0x01,temp);//修改分&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;temp=B_BCD(sec);&nbsp;

&nbsp;&nbsp;I2cByteWrite(0xD0,0x00,temp);//修改秒&nbsp;

}&nbsp;

/****************************************************/&nbsp;



&nbsp;&nbsp;/****************读取时间&nbsp;计算&nbsp;并显示****************/&nbsp;

void&nbsp;get_show_time(void)&nbsp;

{&nbsp;

&nbsp;unsigned&nbsp;char&nbsp;temp1,temp2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;

&nbsp;&nbsp;

&nbsp;temp1=I2cByteRead(0xd0,0x06);&nbsp;&nbsp;//年&nbsp;

&nbsp;temp2=BCD2HEX(temp1);&nbsp;

&nbsp;xianshishuzi(2,0,temp2);&nbsp;

&nbsp;&nbsp;

&nbsp;/*temp1=I2cByteRead(0xd0,0x05);&nbsp;&nbsp;//月&nbsp;

&nbsp;temp2=BCD2HEX(temp1);&nbsp;

&nbsp;

&nbsp;&nbsp;

&nbsp;temp1=I2cByteRead(0xd0,0x04);&nbsp;&nbsp;//日&nbsp;

&nbsp;temp2=BCD2HEX(temp1);&nbsp;

&nbsp;&nbsp;

&nbsp;&nbsp;

&nbsp;temp1=I2cByteRead(0xd0,0x02);&nbsp;&nbsp;//时&nbsp;24小时制&nbsp;

&nbsp;temp1&=0x3f;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;temp2=BCD2HEX(temp1);&nbsp;

&nbsp;&nbsp;

&nbsp;temp1=I2cByteRead(0xd0,0x01);&nbsp;&nbsp;//分&nbsp;

&nbsp;temp2=BCD2HEX(temp1);&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;

&nbsp;temp1=I2cByteRead(0xd0,0x00);&nbsp;&nbsp;//秒&nbsp;

&nbsp;temp2=BCD2HEX(temp1);*/&nbsp;



&nbsp;&nbsp;&nbsp;&nbsp;

}&nbsp;

/****************************************************/&nbsp;

出0入0汤圆

发表于 2009-12-22 11:09:20 | 显示全部楼层
我有一个基于fpga的时钟程序,怎么让他来提取这个芯片的时间呢,谢谢

出0入0汤圆

发表于 2010-2-20 16:14:51 | 显示全部楼层
关于3231的闹钟如何用程序控制,那位DX能提供一下程序?

出0入0汤圆

发表于 2010-2-22 15:14:17 | 显示全部楼层
nuibility

出0入0汤圆

发表于 2010-3-9 16:53:07 | 显示全部楼层
我用的C8051的I2C例程,折腾了大半天没搞定,与SD2403API通讯,无耐也只好用模拟的I/O口操作,1个多小时就调通了。 例程的中断方式实在不适合有特殊要求的操作方式。

出0入0汤圆

发表于 2010-6-9 14:31:36 | 显示全部楼层
我想用单片机和ds3231进行通信,目前刚刚开始着手,大家多提供一些例程和电路图最好拉。

出0入0汤圆

发表于 2010-6-25 10:39:24 | 显示全部楼层
单片机与ds3231sn通信搞定,按照datasheet一步一步来,没问题

出0入0汤圆

发表于 2010-8-17 20:14:43 | 显示全部楼层
学习,我也在写ARM和DS3231的通讯程序

出0入0汤圆

发表于 2011-4-15 16:10:39 | 显示全部楼层
mark一下,正在调128+3231,

出0入0汤圆

发表于 2011-4-15 22:44:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-15 17:49:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-27 21:17:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-30 09:34:56 | 显示全部楼层
mark

出0入98汤圆

发表于 2011-12-17 20:41:46 | 显示全部楼层
MARK

出0入0汤圆

发表于 2012-2-21 18:56:47 | 显示全部楼层
回复【楼主位】fjh120  
-----------------------------------------------------------------------

mark

出0入0汤圆

发表于 2012-2-21 20:27:01 | 显示全部楼层
记号

出0入0汤圆

发表于 2012-2-21 20:58:53 | 显示全部楼层
楼主的3231计时准确吗?我以前也做过一个,但是时间走时误差很大,不知道是什么原因

出0入0汤圆

发表于 2012-5-25 16:52:48 | 显示全部楼层
正在研究这个,先收藏,慢慢研究下

出0入0汤圆

发表于 2012-7-14 16:04:34 | 显示全部楼层
哥们 stm32上有I2C总线可以不用模拟的I2C吧  是不是可以直接调用库里的函数来实现,不知道哥们有没有相关的程序可以参考一下。谢谢!!!予人玫瑰手有余香。

出0入0汤圆

发表于 2012-12-10 21:24:12 | 显示全部楼层
非常感谢,正需要!

出0入0汤圆

发表于 2012-12-18 20:51:02 | 显示全部楼层
你好,你这程序还是不完整啊,disp_two_char ()  lcd.c在哪里?

出0入0汤圆

发表于 2013-4-10 15:00:42 来自手机 | 显示全部楼层
学习一下....

出0入0汤圆

发表于 2014-9-29 13:47:33 | 显示全部楼层
参考下楼主程序,我用的STC单片机。。。

出0入0汤圆

发表于 2015-5-12 08:27:57 | 显示全部楼层
mark一下,正在调128+3231,

出0入0汤圆

发表于 2015-5-14 16:09:37 | 显示全部楼层
哎  用STM8没调通   不知楼主能帮忙指点下不呢         

出0入0汤圆

发表于 2015-5-24 14:06:29 | 显示全部楼层
哎  m8没调通   不知楼主能帮忙指点下不呢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-4 00:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表