搜索
bottom↓
回复: 8

M64 TWI 读写时钟芯片8583 范例

[复制链接]

出0入0汤圆

发表于 2007-11-12 11:34:30 | 显示全部楼层 |阅读模式
/*******************************************/
/*            上海安深科技                      */
/*           tdlhsh@sian.com.cn                  */
/*             8583时钟芯片twi总线演示程序        */
/*           tdlhsh@sian.com.cn                  */
/*                2007年11月12日                 */
/* 文件名: TWI6.H                              */
/*   目标MCU:MEGA64   晶振:外部 20MHZ           */
/*******************************************/

#ifndef _AVR_TWI_H_
#define _AVR_TWI_H_ 1

#define rd_device_add 0xa1
#define wr_device_add 0xa0
/* TWSR values (not bits) */
/* Master主机发送模式的状态码 */
#define START                0x08//START 已发送
#define REP_START                0x10//重复START 已发送
/* Master Transmitter */
#define MT_SLA_ACK                  0x18//SLA+W 已发送;接收到ACK

#define MT_SLA_NACK                0x20//SLA+W 已发送接收到NOT ACK
#define MT_DATA_ACK                0x28//数据已发送接收到ACK
#define MT_DATA_NACK                0x30//数据已发送接收到NOT ACK

/* Master Receiver主机接收模式的状态码 */
#define MR_ARB_LOST                0x38//SLA+W 或数据的仲裁失败
#define MR_SLA_ACK                0x40//SLA+R 已发送接收到ACK
#define MR_SLA_NACK                0x48//SLA+R 已发送接收到NOT ACK
#define MR_DATA_ACK                0x50//接收到数据ACK 已返回
#define MR_DATA_NACK                0x58//接收到数据NOT ACK 已返回
/* Slave Receiver */
#define SR_SLA_ACK                0x60//自己的SLA+W 已经被接收ACK 已返回
#define SR_ARB_LOST_SLA_ACK        0x68//SLA+R/W 作为主机的仲裁失败;自己的SLA+W 已经被接收ACK 已返回
#define SR_GCALL_ACK                0x70//接收到广播地址ACK 已返回
#define SR_ARB_LOST_GCALL_ACK 0x78//SLA+R/W 作为主机的仲裁失败;接收到广播地址ACK 已返回
#define SR_DATA_ACK                0x80//以前以自己的 SLA+W 被寻址;数据已经被接收ACK 已返回
#define SR_DATA_NACK                0x88//以前以自己的 SLA+W 被寻址;数据已经被接收NOT ACK 已返回
#define SR_GCALL_DATA_ACK        0x90//以前以广播方式被寻址;数据已经被接收ACK 已返回
#define SR_GCALL_DATA_NACK        0x98//以前以广播方式被寻址;数据已经被接收NOT ACK 已返回
#define SR_STOP                        0xA0//在以从机工作时接收到STOP或重复START
/* Slave Transmitter */
#define ST_SLA_ACK                0xA8//自己的SLA+R 已经被接收ACK 已返回
#define ST_ARB_LOST_SLA_ACK        0xB0//SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收ACK 已返回
#define ST_DATA_ACK                0xB8//TWDR 里数据已经发送接收到ACK
#define ST_DATA_NACK                0xC0//TWDR 里数据已经发送接收到NOT ACK
#define ST_LAST_DATA                0xC8//TWDR 的一字节数据已经发送(TWAE = “0”);接收到ACK
/* Misc */
#define NO_INFO                0xF8//没有相关的状态信息;TWINT = “0”
#define BUS_ERROR                0x00//由于非法的START 或STOP 引起的总线错误
/*
* The lower 3 bits of TWSR are reserved on the ATmega163.
* The 2 LSB carry the prescaler bits on the newer ATmegas.
*/
#define STATUS_MASK                0xf8
                               
#define STATUS                (TWSR & STATUS_MASK)

/*
* R/~W bit in SLA+R/W address field.
*/
#define READ                1
#define WRITE        0

#endif  /* _AVR_TWI_H_ */

//TWI状态定义
//MT 主方式传输  MR 主方式接收

#define START 0x08
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_SLA_NOACK 0x20
#define MT_DATA_ACK  0x28
#define MT_DATA_NOACK 0x30
#define MR_SLA_ACK  0x40
#define MR_SLA_NOACK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NOACK 0x58/**/
//常用TWI操作(主模式写和主模式读)
#define Start()              TWCR =(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
#define Re_Start()         TWCR =(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
#define Wait()                     while(!(TWCR&(1<<TWINT)))
#define TestAck()           TWSR&0xf8
#define SetAck()          TWCR=1<<TWEA
#define Set_No_Ack()          TWCR&=~(1<<TWEA)
#define Twi()                    (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA))

#define SetNoAck()    TWCR&=~(1<<TWEA)
#define Write8Bit(x)  {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
#define Stop()               TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)
#define close_twi()       TWCR =0
/*******************************************/
/*            上海安深科技                      */
/*           tdlhsh@sian.com.cn                  */
/*             8583时钟芯片twi总线演示程序        */
/*           tdlhsh@sian.com.cn            */
/*                2007年11月12日            */
/* 文件名: TWI6.C         */
/*   目标MCU:MEGA64   晶振:外部 20MHZ */
/*******************************************/
//本演示程序不作超时处理,用户可自行加入超时处理代码
//使用说明:
#include <ioavr.h>
#include"TWI6.H"
#include "void_main.h"
#define rd_device_add 0xa1
#define wr_device_add 0xa0
//extern const unsigned char seg_table[16];
//extern unsigned char led_buff[4];
//extern void delay_ms(unsigned int time);
//extern void display(void);
/******************************************
               I2C总线写一个字节
                            返回0:写成功
                                返回非0:写失败
*******************************************/
unsigned char wr_ram(unsigned char address, unsigned char  num, unsigned char *ppc)
//unsigned char i2c_Write(unsigned char *Wdata,unsigned char RomAddress ,unsigned char twx)
{         char i;
          Start();//I2C启动
          Wait();
          if(TestAck()!=START) return 1;//ACK
          Write8Bit(wr_device_add);//写I2C从器件地址和写方式
          Wait();
          if(TestAck()!=MT_SLA_ACK) return 1;//ACK
          Write8Bit(address);//写24C02的ROM地址
          Wait();
          if(TestAck()!=MT_DATA_ACK) return 1;//ACK
          for(i=0;i<num;i++)
            {
             Write8Bit(ppc);//写数据到24C02的ROM
             Wait();
             if(TestAck()!=MT_DATA_ACK) return 1;//ACK       
            }
          Stop();//I2C停止
         // delay_ms(10);//延时等EEPROM写完
           close_twi();
          return 0;
}
unsigned char wr_ram_one(unsigned char address, unsigned char ppc)
//unsigned char i2c_Write(unsigned char *Wdata,unsigned char RomAddress ,unsigned char twx)
{
          Start();//I2C启动
          Wait();
          if(TestAck()!=START) return 1;//ACK
          Write8Bit(wr_device_add);//写I2C从器件地址和写方式
          Wait();
          if(TestAck()!=MT_SLA_ACK) return 1;//ACK
          Write8Bit(address);//写24C02的ROM地址
          Wait();
          if(TestAck()!=MT_DATA_ACK) return 1;//ACK
             Write8Bit(ppc);//写数据到24C02的ROM
             Wait();
          if(TestAck()!=MT_DATA_ACK) return 1;//ACK       
          Stop();//I2C停止
         // delay_ms(10);//延时等EEPROM写完
           close_twi();
          return 0;
}
/******************************************
               I2C总线读一个字节
                           如果读失败也返回0
*******************************************/
unsigned char readram(   unsigned char address, unsigned char  num, unsigned char *ppc)
//unsigned char i2c_Read(unsigned char *Wdata,unsigned char RomAddress ,unsigned char twx)
      {
         char i;
           unsigned char temp=1;
           Start();//I2C启动
           Wait();
           if (TestAck()!=START) return 0;//ACK       
           Write8Bit(wr_device_add);//写I2C从器件地址和写方式
           Wait();
           if (TestAck()!=MT_SLA_ACK) return 0;//ACK
           Write8Bit(address);//写24C02的ROM地址
           Wait();
           if (TestAck()!=MT_DATA_ACK) return 0;
            Re_Start();//I2C重新启动
           Wait();
           if (TestAck()!=RE_START)  return 0;
           Write8Bit(rd_device_add);//写I2C从器件地址和读方式
           Wait();
           if(TestAck()!=MR_SLA_ACK)  return 0;//ACK
          // SetAck();
           for(i=0;i<num;i++)
            {
              Twi();//启动主I2C读方式
              Wait();
              if(TestAck()!=MR_DATA_ACK) return 0;//        NOACK
               ppc=TWDR;//读取I2C接收数据
            }
          // SetNoAck();
           Stop();//I2C停止
           close_twi();//I2C关
           return temp;
      }
/******************************************
               I2C总线读一个字节
                           如果读失败也返回0
*******************************************/
unsigned char readram_one(   unsigned char address)
//unsigned char i2c_Read(unsigned char *Wdata,unsigned char RomAddress ,unsigned char twx)
      {
        //  if( TestAck()!=NO_INFO)
           //  Stop();
           unsigned char temp=1;
           Start();//I2C启动
           Wait();
           if (TestAck()!=START) return 0;//ACK       
           Write8Bit(wr_device_add);//写I2C从器件地址和写方式
           Wait();
           if (TestAck()!=MT_SLA_ACK) return 0;//ACK
           Write8Bit(address);//写24C02的ROM地址
           Wait();
           if (TestAck()!=MT_DATA_ACK) return 0;
            Re_Start();//I2C重新启动
           Wait();
           if (TestAck()!=RE_START)  return 0;
           Write8Bit(rd_device_add);//写I2C从器件地址和读方式
           Wait();
           if(TestAck()!=MR_SLA_ACK)  return 0;//ACK
             Twi();//启动主I2C读方式
           Wait();
           if(TestAck()!=MR_DATA_ACK) return 0;//        NOACK
               temp=TWDR;//读取I2C接收数据
              //return temp;
          // SetNoAck();
           Stop();//I2C停止
           close_twi();
           return temp;
      }
extern struct
  {
    struct
      {
        char year;
        char  month;
        char day;
      }data;
    struct
      {
       char hour;
       char Minute;
       char Second;
      }time;
  }dat_time;//,dat_time1
extern unsigned char table [16];
unsigned char tablea [16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
__root unsigned  __eeprom char tabled[16];
unsigned char readram_eep(   unsigned char address, unsigned char  num, unsigned  char  __eeprom *ppc)
//unsigned char i2c_Read(unsigned char *Wdata,unsigned char RomAddress ,unsigned char twx)
      {
         char i;
           unsigned char temp=1;
           Start();//I2C启动
           Wait();
           if (TestAck()!=START) return 0;//ACK       
           Write8Bit(wr_device_add);//写I2C从器件地址和写方式
           Wait();
           if (TestAck()!=MT_SLA_ACK) return 0;//ACK
           Write8Bit(address);//写24C02的ROM地址
           Wait();
           if (TestAck()!=MT_DATA_ACK) return 0;
            Re_Start();//I2C重新启动
           Wait();
           if (TestAck()!=RE_START)  return 0;
           Write8Bit(rd_device_add);//写I2C从器件地址和读方式
           Wait();
           if(TestAck()!=MR_SLA_ACK)  return 0;//ACK
           SetAck();
           for(i=0;i<num;i++)
            {
              Twi();//启动主I2C读方式
              Wait();
              if(TestAck()!=MR_DATA_NOACK) return 0;//ACK       
               ppc=TWDR;//读取I2C接收数据
            }
           SetNoAck();
           Stop();//I2C停止
            close_twi();
           return temp;
      }
void read_dat_time(void)
  {
     readram( 0, 12,table);
   // char n;
   // for(n=0;n<12;n++) readram_one(   unsigned char address)
    // table[2]= readram_one(2);
     if(table[2]!=0xff)
      {
        char a=table[2]&0x0f,b=((table[2]&0x70)>>4)*10;
        dat_time.time.Second=a+b;//
      }
    if(table[3]!=0xff)
      {
        char a=table[3]&0x0f,b=((table[3]&0x70)>>4)*10;
        dat_time.time.Minute=a+b;//
      }
    if(table[4]!=0xff)
      {
        char a=table[4]&0x0f,b=((table[4]&0x30)>>4)*10;
         dat_time.time.hour=a+b;//
      }
    if(table[5]!=0xff)
      {
        char a=table[5]&0x0f,b=((table[5]&0x30)>>4)*10;
         dat_time.data.day=a+b;//
      }
    if(table[6]!=0xff)
      {
       char a=table[6]&0x0f,b=((table[6]&0x10)>>4)*10;
       dat_time.data.month=a+b;//
       dat_time.data.year=table[5]>>6;
      }
     //table[11]=test_slaveadd();
  }

void write_dat_time(void)
  {
   // twi_cushihua();
//   while( i2c_Write(0,0 ));
  //  while (i2c_Write(10,3 ));
#if cpu_clok_8M
    TWBR=2;
#elif cpu_clok_20M

    TWBR=6;
   // TWSR=4;
#endif
    delay_ms(10);
    //table[2]= readram_one(2);
    wr_ram(0, 16,tablea);
  //  table[11]=test_slaveadd();
  //  delay_ms(1);
  //  readram_eep( 0, 12,tabled);
  }

出0入0汤圆

发表于 2007-11-12 23:15:46 | 显示全部楼层
楼主真是强人……
可能很少人用这个器件吧,没大虾回啊!
我有一个,但不知道什么用,平时就玩得动DS1302而已,见笑了……
大概浏览了一下程序,似乎缺了点呢?            #include"TWI6.H"
                                              #include "void_main.h"
楼主……能不能把所有的都帖出来啊?或者发一份给我学习学习啊……
QQ:464466045   E—mail:lonely84@163.com     不胜感激啊!

出0入0汤圆

 楼主| 发表于 2007-11-14 10:24:15 | 显示全部楼层
不好意思#include"TWI6.H" 这个文件在顶部  #include "void_main.h"是函数声明

出0入0汤圆

 楼主| 发表于 2007-11-15 10:12:45 | 显示全部楼层
我自己顶一下

出0入0汤圆

 楼主| 发表于 2007-11-15 11:03:20 | 显示全部楼层
看来很少人用这个器件再 顶顶

出0入0汤圆

 楼主| 发表于 2007-12-5 13:26:40 | 显示全部楼层
看来很少人用这个器件再 顶顶

出0入0汤圆

发表于 2008-7-2 01:39:29 | 显示全部楼层
可以参考

出0入0汤圆

发表于 2009-5-5 16:21:29 | 显示全部楼层
mark

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-3 03:27

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

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