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

📄 i2c.c.bak

📁 详细介绍M8两版间通讯
💻 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 + -