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

📄 i2c.c

📁 详细介绍M8两版间通讯
💻 C
字号:
#include<iom8v.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


#define EE_READ							0xf0
#define EE_READ_OK					0x50
#define EE_WRITE						0x0f
#define EE_WRITE_OK					0x05
#define EE_WRITE_OVER				0xa5

#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 TestAck() (TWSR&0xf8)
//TWSR--I2C状态寄存器,检查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_ms(unsigned int time);

unsigned char charData;//TWI中断中,传送的数据
unsigned char charAddr;//TWI中断中,数据所处的EEPROM地址
unsigned char charState;//TWI中断中,中断所处的状态

void TWI_init(void)
 {
	charState=EE_READ;
	TWBR=0x20;//波特率寄存器,正常情况下应不小于10
	TWSR=0x00;//TWI状态寄存器,时钟分频值1
 }
 
/**********************ATEEPROM读写过程*********************************
	字节写:Start→器件地址&W→应答→选ROM地址→应答→写数据→应答→Stop
中断过程	START→MT_SLA_ACK→MT_DATA_ACK(地址)→MT_DATA_ACK(数据)(STOP中止)

	页面写:Start→器件地址&W→应答→选ROM地址→应答→写数据→应答→写NEXT地址数据→应答→。。。写NEXT地址数据→应答→Stop
中断过程	START→MT_SLA_ACK→MT_DATA_ACK(地址)→MT_DATA_ACK(数据)→MT_DATA_ACK(数据)→。。。MT_DATA_ACK(数据)(STOP中止)
						 
	字节读:Start→器件地址&W→应答→选ROM地址→应答→Restart→器件地址&R→应答→读数据→无应答→Stop
中断过程	START→MT_SLA_ACK→MT_DATA_ACK(地址)→RE_START→MR_SLA_ACK→MR_DATA_NOACK(STOP中止)
				
	页面读:Start→器件地址&W→应答→选ROM地址→应答→Restart→器件地址&R→应答→读数据→应答→读NEXT地址数据→应答→。。。读NEXT地址数据→无应答→Stop
中断过程	START→MT_SLA_ACK→MT_DATA_ACK(地址)→RE_START→MR_SLA_ACK→MR_DATA_ACK→MR_DATA_ACK→。。。MR_DATA_NOACK(STOP中止)		
*************************************************************************/
						
#pragma interrupt_handler TWI_Ready:iv_TWI//TWI中断处理
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停止
	 }
 }

/*
常用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_ms(10);
 }
unsigned char i2c_read(unsigned char RomAddress)
 {
	charAddr=RomAddress;
	charState=EE_READ;
	Start();//I2C启动
	while(charState!=EE_READ_OK);
	return charData;
 }

⌨️ 快捷键说明

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