📄 i2c.c.bak
字号:
#include<iom8v.h>
#include <macros.h>
/* AT2402C地址
1 0 1 0 A2 A1 A0 R/W
前4位为AT240X系列的特征字
后3位为可编程位
最后一位为读写位
*/
#define rd_device_add 0xa1 //读地址:0b10100001
#define wr_device_add 0xa0 //写地址:0b10100000
/*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
//SR-从机方式接收 ST-从机方式传输 ALL-广播 NOCTRL-主机丢失控制权
#define SR_SLA_ACK 0x60
#define SR_SLA_ACK_NOCTRL 0x68
#define SR_ALL_ACK 0x70
#define SR_ALL_ACK_NOCTRL 0x78
#define SR_DATA_ACK 0X80
#define SR_DATA_NOACK 0X88
#define SR_ALL_DATA_ACK 0x90
#define SR_ALL_DATA_NOACK 0x98
#define SR_STOP_RESTART 0xa0
#define ST_SLA_ACK 0xa8
#define ST_SLA_ACK_NOCTRL 0xb0
#define ST_DATA_ACK 0xb8
#define ST_DATA_NOACK 0xc0
#define ST_LAST_DATA_ACK 0xc8
///////////////////////////////////////////////////////////
#define EE_READ 0xf0
#define EE_READ_OK 0x50
#define EE_WRITE 0x0f
#define EE_WRITE_OK 0x05
#define EE_WRITE_OVER 0xa5
#define TestAck() (TWSR&0xf8)
//TWSR--I2C状态寄存器,检查TWI状态,应该将预分频位屏蔽(第三位是保留位)
#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE))
//清除中断标志位,在总线上发出起始信号,激活TWI功能,开放TWI中断
#define Stop() (TWCR=((1<<TWINT)|(1<<TWSTO)|(1<<TWEN))&(~(1<<TWIE)))
//清除中断标志位,在总线上发出终止信号,激活TWI功能,关闭TWI中断
#define MT_NACK (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE))
//清除中断标志位,使能TWI功能,开放TWI中断,在主控接收状态下不对SDA线作应答
#define MT_ACK (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA))
//清除中断标志位,使能TWI功能,开放TWI中断,在主控接收状态下对SDA线作应答
#define TWItransmit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE);}
//写入8位数据到数据寄存器中,同时清除中断标志位,使能TWI功能,开放TWI中断
extern void Delay(unsigned int time);
extern char cDataBuff[];
extern unsigned char StartShow;
unsigned char charData;//TWI中断中,传送的数据
unsigned char charAddr;//TWI中断中,数据所处的EEPROM地址
unsigned char charState;//TWI中断中,中断所处的状态
void TWI_init(void)
{
charState=EE_READ;
TWBR=0x00;//波特率寄存器,主机正常情况下应不小于10
TWSR=0x00;//TWI状态寄存器,时钟分频值1
TWAR=0xa0;/*被控器地址寄存器。0xa0为AT2402的地址,可以用ATMEGA8来模拟AT2402。
作为从机,应该将被控器的地址写入。注意不要和其他器件相同*/
TWCR=(TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA));//清除中断标志位,使能TWI功能,开放TWI中断
}
#pragma interrupt_handler TWI_Ready:iv_TWI//TWI中断处理
void TWI_Ready(void)
{
static unsigned char charIndex=0;
unsigned char charTemp;
PORTC^=(0b00001000);//进入中断后,闪亮LED
NOP();
NOP();
NOP();
NOP();
NOP();
switch (TestAck())//检查状态标志字
{
case SR_SLA_ACK:
{
MT_ACK;
cDataBuff[charIndex++]=0x01;
cDataBuff[charIndex++]=0x01;
cDataBuff[charIndex++]=0xa0;
cDataBuff[charIndex++]=0xa0;
StartShow=0xff;
break;
}
case SR_DATA_ACK:
{
switch (charState)
{
case EE_READ:
{
charAddr=TWDR;
MT_ACK;
cDataBuff[charIndex++]=0x02;
cDataBuff[charIndex++]=0x02;
cDataBuff[charIndex++]=0xa0;
cDataBuff[charIndex++]=0xa0;
StartShow=0xff;
charState=EE_READ_OK;
break;
}
case EE_READ_OK:
{
charData=TWDR;
MT_ACK;
cDataBuff[charIndex++]=0x03;
cDataBuff[charIndex++]=0x03;
cDataBuff[charIndex++]=0xa0;
cDataBuff[charIndex]=0xa0;
StartShow=0xff;
charState=EE_READ;
charIndex+=4;
cDataBuff[charIndex--]=0xa0;
charTemp=charAddr%10;
cDataBuff[charIndex--]=charTemp;
charAddr/=10;
charTemp=charAddr%10;
cDataBuff[charIndex--]=charTemp;
charAddr/=10;
cDataBuff[charIndex]=charAddr;
charIndex+=7;
cDataBuff[charIndex--]=0xa0;
charTemp=charData%10;
cDataBuff[charIndex--]=charTemp;
charData/=10;
charTemp=charData%10;
cDataBuff[charIndex--]=charTemp;
charData/=10;
cDataBuff[charIndex]=charData;
StartShow=0xff;
if(charIndex>12) charIndex=0;
}
}
}
default:
{
}
}
}
/*
常用TWI操作(主模式写和主模式读)
*/
void i2c_write(unsigned char Wdata,unsigned char RomAddress)
{
charData=Wdata;//I2C总线写一个字节
charAddr=RomAddress;//返回0:写成功
charState=EE_WRITE;//返回非0:写失败
Start();//I2C启动(TWI中断启动)
while(charState!=EE_WRITE_OK);
Delay(10);
}
unsigned char i2c_read(unsigned char RomAddress)
{
charAddr=RomAddress;
charState=EE_READ;
Start();//I2C启动
while(charState!=EE_READ_OK);
return charData;
}
/*********************备份**************************
void TWI_Ready(void)
{
switch (TestAck())//检查状态标志字
{
case START:
{
TWItransmit(wr_device_add);
//选取I2C从器件地址,进行主控写模式
break;
}
case RE_START:
{
TWItransmit(rd_device_add);
//选取I2C从器件地址,进行主控读模式
break;
}
case MT_SLA_ACK:
//Slave器件被识别并产生应答
{
TWItransmit(charAddr);
//写24C02ROM的字地址
break;
}
case MT_DATA_ACK:
//主控发送数据,并得到响应
{
switch(charState)
{
case EE_WRITE://写数据到24C02的ROM
{
TWItransmit(charData);
charState=EE_WRITE_OVER;
break;
}
case EE_WRITE_OVER://I2C停止
{
Stop();
charState=EE_WRITE_OK;
break;
}
case EE_READ:
{
Start();
break;
}
//I2C重新启动
}
break;
}
case MR_SLA_ACK:
{
MT_NACK;
break;
}
//启动主I2C读方式
case MR_DATA_NOACK:
{
charData=TWDR;
Stop();
charState=EE_READ_OK;
break;
}
//读取I2C接收数据,I2C停止
default:
Stop();//I2C停止
}
}
***************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -