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

📄 i2c.c

📁 用ATMEGA 128L 单片机实现对温度传感器LM75的控制
💻 C
字号:
#include <avr/io.h>
#include <avr/twi.h>
#include <string.h>
#include <avr/signal.h>
#include "type.h"

#define TW_WRITE   0 
#define TW_READ    1 
#define max  3 


void TWI_init( void )   //i2c初始化
{  
	DDRD|=0X01;

	TWBR = 0x01; //设置波特率 
	TWSR &= 0xfc;//设置预分频因子为4,则SCL频率为409600Hz 
} 


uchar twi_write_byte(uchar sla,uchar address,uchar write_data ) 
{ 
   uchar twst,n=0x0,rv=0x01; 
   restart: 
      if(n++>=max) 
         goto error; 
   begin: 
      TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号 
      while((TWCR & _BV(TWINT))==0x0);//等待发送完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_REP_START://有可能出现 
         case   TW_START: 
               break; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWDR = sla | TW_WRITE;//发送SLA+W 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_SLA_ACK: 
               break; 
         case   TW_MT_SLA_NACK://器件忙,有可能处于内部写周期 
               goto   restart; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
     /* TWDR = address>>8;//传输地址高8位 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         case   TW_MT_DATA_NACK: 
               goto   quit; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } */
      TWDR = address;//传输地址低8位 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         case   TW_MT_DATA_NACK: 
               goto   quit; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWDR = write_data; 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         default: 
               goto   error; 
      } 
   quit: 
      TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号 
      return   rv; 
   error: 
      rv=0x00; 
   goto   quit;   
} 


uchar twi_write_str(uchar sla,uchar address,uchar *p,uchar len ) 
{ 
   uchar i,twst,n=0x0,rv=0x01; 
   restart: 
      if(n++>=max) 
         goto error; 
   begin: 
      TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号 
      while((TWCR & _BV(TWINT))==0x0);//等待发送完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_REP_START://有可能出现 
         case   TW_START: 
               break; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWDR = sla | TW_WRITE;//发送SLA+W 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_SLA_ACK: 
               break; 
         case   TW_MT_SLA_NACK://器件忙,有可能处于内部写周期 
               goto   restart; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
     /* TWDR = address>>8;//传输地址高8位 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         case   TW_MT_DATA_NACK: 
               goto   quit; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } */
      TWDR = address;//传输地址低8位 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         case   TW_MT_DATA_NACK: 
               goto   quit; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
	  for(i=0;i<len;i++)
	  {
		  TWDR = *p; 
		  p++;
		  TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
		  while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
		  switch((twst = TW_STATUS)) 
		  { 
			 case   TW_MT_DATA_ACK: 
				   break; 
			 default: 
				   goto   error; 
		  } 
	  }
   quit: 
      TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号 
      return   rv; 
   error: 
      rv=0x00; 
   goto   quit;   
} 


uchar twi_read_byte( uchar sla,uchar address) 
{ 
   uchar twst,n=0x0,rv=0x1; 
   restart: 
      if(n++>=max) 
         goto error; 
   begin: 
      TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号 
      while((TWCR & _BV(TWINT))==0x0);//等待发送完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_REP_START://有可能出现 
         case   TW_START: 
               break; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWDR = sla | TW_WRITE;//发送SLA+W 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_SLA_ACK: 
               break; 
         case   TW_MT_SLA_NACK://器件忙,有可能处于内部写周期 
               goto   restart; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
     /* TWDR = address>>8;//传输地址高8位 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         case   TW_MT_DATA_NACK: 
               goto   quit; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      }*/ 
      TWDR = address;//传输地址低8位 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         case   TW_MT_DATA_NACK: 
               goto   quit; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送(重新)开始信号 
      while((TWCR & _BV(TWINT))==0x0);//等待发送完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_REP_START://正确的状态 
               break; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWDR = sla | TW_READ;//发送SLA+R 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MR_SLA_ACK: 
               break; 
         case   TW_MR_SLA_NACK://器件忙,有可能处于内部写周期 
               goto   restart; 
         case   TW_MR_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWCR = _BV(TWINT) | _BV(TWEN) ;//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MR_DATA_NACK: 
               rv = TWDR; 
               break; 
         default: 
               goto   error; 
      } 
   quit: 
      TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号 
      return   rv; 
   error: 
      rv=0x00; 
   goto   quit; 
} 


uchar twi_read_str( uchar sla,uchar address,uchar *p,uchar len) 
{ 
   uchar i,twst,n=0x0,rv=0x1; 
   restart: 
      if(n++>=max) 
         goto error; 
   begin: 
      TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号 
      while((TWCR & _BV(TWINT))==0x0);//等待发送完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_REP_START://有可能出现 
         case   TW_START: 
               break; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWDR = sla | TW_WRITE;//发送SLA+W 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_SLA_ACK: 
               break; 
         case   TW_MT_SLA_NACK://器件忙,有可能处于内部写周期 
               goto   restart; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
     /* TWDR = address>>8;//传输地址高8位 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         case   TW_MT_DATA_NACK: 
               goto   quit; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      }*/ 
      TWDR = address;//传输地址低8位 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MT_DATA_ACK: 
               break; 
         case   TW_MT_DATA_NACK: 
               goto   quit; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送(重新)开始信号 
      while((TWCR & _BV(TWINT))==0x0);//等待发送完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_REP_START://正确的状态 
               break; 
         case   TW_MT_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
      TWDR = sla | TW_READ;//发送SLA+R 
      TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输 
      while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
      switch((twst = TW_STATUS)) 
      { 
         case   TW_MR_SLA_ACK: 
               break; 
         case   TW_MR_SLA_NACK://器件忙,有可能处于内部写周期 
               goto   restart; 
         case   TW_MR_ARB_LOST: 
               goto   begin; 
         default: 
               goto   error; 
      } 
       for(i=0;i<len;i++) 
      { 
         if(i==(len-1)) 
         { 
            TWCR = _BV(TWINT) | _BV(TWEN) ;//清TWINT,开始传输(无应答) 
         } 
         else 
         { 
            TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) ;//清TWINT,开始传输(有应答) 
         } 
         while((TWCR & _BV(TWINT))==0x0);//等待传输完毕 
         switch((twst = TW_STATUS)) 
         { 
            case   TW_MR_DATA_NACK: 
            case   TW_MR_DATA_ACK: 
                  *p = TWDR; 
                  p++; 
                  break; 
            default: 
                  goto   error; 
         } 
      } 
   quit: 
      TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号 
      return   rv; 
   error: 
      rv=0x00; 
   goto   quit; 
} 

⌨️ 快捷键说明

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