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

📄 twi.c

📁 使用IO口模拟I2C功能 读写I2C设备。
💻 C
字号:
/********************************
  AVR单片机I/O口模拟I2C操作程序 
  文件名:twi.c
  编译:WinAVR-20070122

  硬件:CA-M8X  
      配置:外部4MHz
      打开:S7(1,2,3) - EEPROM连接
            S6(1,2)   - 4MHz晶振连接
            S5(5,6)   - UART连接
      注:PC5模拟SCL,PC4模拟SDA,PC3连接写保护引脚
  
  芯艺设计室 2004-2007  版权所有 
  转载请保留本注释在内的全部内容
  WEB: http://www.chipart.cn
  Email: changfutong@sina.com
*******************************/

#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

/*注:
AVR单片机I/O口模拟I2C总线时建议在外部连接上拉电阻
这样可通过改变I/O口输入输出方向的方式来设置高低
输出口保持不变(0)
此时如DDRX寄存器为1则变成输出0
若DDRX为0,则I/O口程高阻,但因外部的上拉电阻,总线相当于设置高
即通过设置DDRX的方式控制总线的高低
*/
#define SET_SCL DDRB&=~_BV(PB2)
#define CLR_SCL DDRB|=_BV(PB2)
#define SET_SDA DDRB&=~_BV(PB3)
#define CLR_SDA DDRB|=_BV(PB3)

#define SDA_PIN  (PINB&_BV(PB3))

static void twi_delay_bus(void)
{
  _delay_loop_2(10);
}

static void twi_ack(uint8_t ack)
{
  if(!ack)  //非应答
    SET_SDA;            
  else    //应答
    CLR_SDA;
  twi_delay_bus();
  SET_SCL;
  twi_delay_bus();                  
  CLR_SCL;                     
  twi_delay_bus();
}

/*********以下为外部可调用的接口函数***********/
//初始化本模块
void TwiInit(void)
{
  PORTB&=~(_BV(PB2)|_BV(PB3));

  DDRB&=~(_BV(PB2)|_BV(PB3));
}
//产生启动信号
uint8_t TwiStart(void)
{
  twi_delay_bus();
  SET_SDA;       
  twi_delay_bus();  
  SET_SCL;
  twi_delay_bus();
  CLR_SDA;           
  twi_delay_bus();
  CLR_SCL;         
  twi_delay_bus();  
  return 1;
}
//产生停止信号
void TwiStop(void)
{
  twi_delay_bus();
  CLR_SDA;    
  twi_delay_bus();  
  SET_SCL;
  twi_delay_bus();
  SET_SDA;    
  twi_delay_bus();  
}

//向总线写一字节,并返回有无应答
uint8_t TwiWriteByte(uint8_t c)
{
  uint8_t i,ack;

  for(i=0;i<8;i++)  
  {
    if(c&0x80)
      SET_SDA;   
    else  
      CLR_SDA;                
    SET_SCL;       
    twi_delay_bus();        
    CLR_SCL; 
    c<<=1;
    twi_delay_bus();
  }
  twi_delay_bus();

  SET_SDA;                
  twi_delay_bus();
  SET_SCL;
  twi_delay_bus();
  if(SDA_PIN)
    ack=0;     //失败
  else 
    ack=1;        
  CLR_SCL;
  twi_delay_bus();
  return ack;  
}

//读一字节 ack: 1时应答,0时不应答
uint8_t TwiReadByte(uint8_t *c, uint8_t ack)
{
  uint8_t i,ret;

  ret=0; 
  SET_SDA;
  for(i=0;i<8;i++)
  {
    twi_delay_bus();          
    CLR_SCL;                  
    twi_delay_bus();
    SET_SCL;                
    twi_delay_bus();
    ret<<=1;
    if(SDA_PIN)
      ret++;  
  }
  CLR_SCL;    
  twi_delay_bus();
  twi_ack(ack);
  *c=ret;
  return(ret);  
}

⌨️ 快捷键说明

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