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

📄 新建 文本文档.txt

📁 ds3231与meg128模拟i2c总线通信
💻 TXT
字号:
/********************************** 
晶振: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[b]); 
 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[b]); 
 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[b]); 
 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[b]); 
 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[b]); 
 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[b]); 
 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) 
    { 

    }   
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -