📄 avr256.c
字号:
#include<iom16v.h>
#include <macros.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 Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define Wait() {while(!(TWCR&(1<<TWINT)));}
#define TestAck() (TWSR&0xf8)
#define SetAck() (TWCR|=(1<<TWEA))
#define SetNoAck() (TWCR&=~(1<<TWEA))
#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN))
#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
#define rd_device_add 0xa1
#define wr_device_add 0xa0
union _my_int
{
uint IntV;
uchar i[2];
};
extern void delay_nms(unsigned int time);
/******************************************
置TWI管脚上拉
******************************************/
void Init_TWI(void)
{
TWI_PORT_DDR |= TWI_SCL |TWI_SDA;
TWI_PORT_PORT |= TWI_SCL |TWI_SDA;
TWSR=00; //设置TWI时钟50K
TWBR=0x16;
}
/******************************************
I2C总线写一个字节
返回0:写成功
返回非0:写失败
*******************************************/
unsigned char i2c_Write(unsigned char Wdata,unsigned int RomAddress)
{
unsigned char *P;
union _my_int k;
k.IntV=RomAddress;
P=&k.i[1];
Start();//I2C启动
Wait();
if(TestAck()!=START) return 1;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if(TestAck()!=MT_SLA_ACK) return 1;//ACK
P--;
Write8Bit(*P);//写24C02的ROM地址
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Write8Bit(*P);//写24C02的ROM地址
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Write8Bit(Wdata);//写数据到24C02的ROM
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Stop();//I2C停止
delay_nms(10);//延时等EEPROM写完
return 0;
}
/******************************************
I2C总线读一个字节
如果读失败也返回0
*******************************************/
unsigned char i2c_Read(unsigned int RomAddress)
{
unsigned char temp;
unsigned char *P;
union _my_int k;
k.IntV=RomAddress;
P=&k.i[1];
Start();//I2C启动
Wait();
if (TestAck()!=START) return 0;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if (TestAck()!=MT_SLA_ACK) return 0;//ACK
P--;
Write8Bit(*P);//写24C02的ROM地址
Wait();
if (TestAck()!=MT_DATA_ACK) return 0;
Write8Bit(*P);//写24C02的ROM地址
Wait();
if (TestAck()!=MT_DATA_ACK) return 0;
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_NOACK) return 0;//ACK
temp=TWDR;//读取I2C接收数据
Stop();//I2C停止
return temp;
}
//#define uchar unsigned char
//#define uint unsigned int
//page write
unsigned char PageWrTWI(unsigned char * Wdata,unsigned int RomAddress,unsigned char Num)
{
unsigned char *P;
union _my_int m;
m.IntV=RomAddress;
P=&m.i[1];
Start();//I2C启动
Wait();
if(TestAck()!=START) return 1;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if(TestAck()!=MT_SLA_ACK) return 1;//ACK
P--;
Write8Bit(*P);//写24C02的ROM地址
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Write8Bit(*P);//写24C02的ROM地址
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
for(;Num>0;Num--)
{
Write8Bit(*Wdata);//写数据到24C02的ROM
Wdata++;
Wait();
if(TestAck()!=MT_DATA_ACK)
return 1;//ACK
}
Stop();//I2C停止
delay_nms(10);//延时等EEPROM写完
return 0;
}
//page read
unsigned char PageRdTWI(uchar *RdBuf,unsigned int RomAddress,uchar Num)
{
//unsigned char temp;
unsigned char *P;
union _my_int n;
n.IntV=RomAddress;
P=&n.i[1];
Start();//I2C启动
Wait();
if (TestAck()!=START) return 0;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if (TestAck()!=MT_SLA_ACK) return 0;//ACK
P--;
Write8Bit(*P);//写24C02的ROM地址
Wait();
if (TestAck()!=MT_DATA_ACK) return 0;
Write8Bit(*P);//写24C02的ROM地址
Wait();
if (TestAck()!=MT_DATA_ACK) return 0;
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_NOACK) return 0;//ACK
for(;Num>0;Num--)
{
//temp=TWDR;//读取I2C接收数据
*RdBuf=TWDR;
SetAck()
RdBuf++;
}
Stop();//I2C停止
return 1;
}
void main()
{
Init_TWI(void);
...
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -