|
/*******************************************/
/* 上海安深科技 */
/* 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);
} |
|