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

📄 twi.c

📁 C语言实现的基于AVR 8位单片机的TWI通讯! 通过中断服务程序中的状态机
💻 C
字号:
/*******************************************************************************/
//          主机、中断方式(读写24C02)     
//原作者:			ntzwq@wx88.net?   		  
//建立时间:		2003年3月25日         		  
//目标MCU:MEGA8   晶振:内部RC(INT) 8MHZ	  
//模块整理:		sam
//模块建立时间: 	2008-5-23
/********************************************************************************/

#include<iom128.h>
#include<AT24C02.h>
#include <global.h>
#ifdef Debug_I2C
	#include <Rs485.h>
#endif
#define RD_DEVICE_ADD 		0xA1
#define WR_DEVICE_ADD 		0xA0

//TWI中断处理(主机模式读和写,以访问AT24C02为例)
#define EE_READ   			0xF0
#define EE_READ_OK  			0x50
#define EE_WRITE    			0x0F
#define EE_WRITE_OK 		0x05
#define EE_WRITE_REG 		0xA5

unsigned char EE_STATE;								//EEPROM操作状态
unsigned char EE_DATA;								//写入的数据
unsigned char EE_ADD;								//写入的地址

unsigned char g_i2ceesave=0x1e;								//I2CEEPROM保存标志
#pragma vector=TWI_vect
__interrupt void TWI_ISR(void)                   			//I2C中断服务程序
{
	switch (TestAck())
	{
		case START:
		{
			Write8Bit(WR_DEVICE_ADD);				//写I2C从器件地址和写方式
			break;
		}
		case RE_START:
		{
			Write8Bit(RD_DEVICE_ADD);				//写I2C从器件地址和读方式
			break;
		}
		case MT_SLA_ACK:
		{
			Write8Bit(EE_ADD);						//写24C02的ROM地址
			break;
		}
		case MT_DATA_ACK:
		{               
			switch(EE_STATE)
			{
				case EE_WRITE:
				{
				 	Write8Bit(EE_DATA);				//写数据到24C02的ROM
				       EE_STATE=EE_WRITE_REG;
					break;
				}
				case EE_WRITE_REG:
				{
				      Stop();							//I2C停止
				   	EE_STATE=EE_WRITE_OK;
				      break;
				}
				case EE_READ:
				{
				     Start();							//I2C重新启动
				     break;
				}
			}                 
			break;
		}
		case MR_SLA_ACK:
		{
			Twi();									//启动主I2C读方式
			 break;
		}
		case MR_DATA_NOACK:
		{
			EE_DATA=TWDR;							//读取I2C接收数据
			Stop();									//I2C停止	
			EE_STATE=EE_READ_OK;       		   		   			   
			break;
		}
		default:	   
			Stop();									//I2C停止              
				      
	}
}
/********************************************************************************
功能:	I2C总线写一个字节
函数原型:unsigned char I2C_Write(unsigned char Wdata,unsigned char RomAddress) 
参数:    	unsigned char Wdata		写入的数据
		unsigned char RomAddress	写入数据的地址0-255
返回值: 	0:写成功
		非0:写失败
*********************************************************************************/
unsigned char I2C_Write(unsigned char Wdata,unsigned char RomAddress) 
{
	unsigned char n=0;
	EE_DATA=Wdata;
	EE_ADD=RomAddress;
	EE_STATE=EE_WRITE;
	Start();										//I2C启动		  
	while(EE_STATE!=EE_WRITE_OK)
	{
		Delay_100us();
		if( n++ >40)								//超时时间为2ms
			return 1;
	}
	Delay_ms(2);  
#ifdef Debug_I2C
	PC_putchar_D(n);
#endif
	return 0;
	/*以下是查询方式访问AT24C02的代码
	Start();//I2C启动	
	Wait();
	if(TestAck()!=START) return 1;//ACK
	Write8Bit(WR_DEVICE_ADD);//写I2C从器件地址和写方式
	Wait();
	if(TestAck()!=MT_SLA_ACK) return 1;//ACK
	Write8Bit(RomAddress);//写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_ms(10);//延时等EEPROM写完
	return 0;*/
}
/********************************************************************************
功能:	 I2C总线读一个字节
函数原型:unsigned char I2C_Read(unsigned char RomAddress)
参数:    	
		unsigned char RomAddress	读出数据的地址0-255
返回值: 	实际值, 如果读失败也返回0
*********************************************************************************/
unsigned char I2C_Read(unsigned char RomAddress) 
{	   
	unsigned char n=0;
	EE_ADD=RomAddress;
	EE_STATE=EE_READ;
	Start();//I2C启动
	while(EE_STATE!=EE_READ_OK)
	{
		Delay_100us();
		if( n++ >20)								//超时时间为2ms
			return 0;
	}
#ifdef Debug_I2C
	PC_putchar_D(n);
#endif
	return EE_DATA;
	//以下是查询方式访问AT24C02的代码
	/*
	unsigned char temp;
	Start();//I2C启动
	Wait();
	if (TestAck()!=START) return 0;//ACK	   
	Write8Bit(WR_DEVICE_ADD);//写I2C从器件地址和写方式
	Wait(); 
	if (TestAck()!=MT_SLA_ACK) return 0;//ACK
	Write8Bit(RomAddress);//写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;*/
}
/********************************************************************************
功能:	 初始化I2C收发器
函数原型:void I2C_Init(void)
参数:    	无
返回值: 	无
*********************************************************************************/
void I2C_Init(void)
{
	TWBR=0x08;							//时钟为clock/(16+2*8)
	TWSR=0x00;
}
/*unsigned char i2c_add,i2c_dat;//I2C地址/数据
unsigned char mode;//修改模式	  
void main(void)
{
 unsigned char i;
 unsigned char add_old,dat_old,mode_old;
 EE_STATE=EE_READ;
 asm("sei");
 TWBR=32;
 TWSR=00;
 mode=0xff;//mode=0修改数据,!=0修改地址
 i2c_add=0;
 i2c_dat=i2c_Read(i2c_add);
 add_old=i2c_add;
 dat_old=i2c_dat;
 mode_old=mode;
 while(1)
   {    
	if(add_old!=i2c_add)//如果地址修改刷新数据
	  {	   
	   add_old=i2c_add;
	   i2c_dat=i2c_Read(i2c_add);
	   dat_old=i2c_dat;
	  }    	    
	i=PIND&0x0c;//判断按键
    if(i!=0x0c)
      {
	   if(i==(PIND&0x0c))
	     {
		  if (i==0x08)//INT0键按下,递增
		    {
			 if (mode!=0)//修改地址
			    {
				 if(i2c_add<0xff)
				    i2c_add++;
				 else
				    i2c_add=0;	
				}
			 else //修改数据
			    {
				 if(i2c_dat<0xff)
				    i2c_dat++;
				 else
				    i2c_dat=0;	
				}
			}
		  if (i==0x04)//INT1键按下,递减
		    {
			 if (mode!=0)//修改地址
			    {
				 if(i2c_add>0)
				    i2c_add--;
				 else
				    i2c_add=0xff;	
				}
			 else //修改数据
			    {
				 if(i2c_dat>0)
				    i2c_dat--;
				 else
				    i2c_dat=0xff;	
				}
			}
		  i=0; 			  		     
	      while((PIND&0x0c)!=0x0c)//检查按键释放		 
		     {
			  while(((PIND&0x0c)==0)&(i==0))
			        {					
					i=0xff;	
					if (mode==0)
				      {
					   mode=0xff;
					   if (dat_old!=i2c_dat) 
					   	  {  
						  dat_old=i2c_dat;
					   	  i2c_Write(i2c_dat,i2c_add);
						  }
					   }
				 	else
				       {
					 	mode=0;
					    }	
					 }					 			  				
			 }
		 }	 
	  }		  		
   }
}
*/

/*end of at24c02.c*/

⌨️ 快捷键说明

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