#ifndef __IIC_H__
#define __IIC_H__
#include <avr/io.h>
#include "mytype.h"
//#define TWI
// Define I/O pins
#define IIC_PORT PORTC
#define IIC_DIR DDRC
#define IIC_IN PINC
#define IIC_SCL PC5//串行时钟线
#define IIC_SDA PC4 // 串行数据线
void IIC_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(void);
void IIC_Send_Ack(void);
void IIC_Send_Not_Ack(void);
void IIC_Clock(void);
uchar IIC_Send(uchar IIC_data) ;
uchar IIC_Receive(void);
#endif
#include <avr/io.h>
#include"IIC.h"
#include "mytype.h"
#include<util/delay.h>
//SDA SCL设置上拉,SDA输出为0,用方向寄存器实现0和1
//名称:void IIC_init(void);
//入口:无
//出口:无
//功能:I2C总线初始化。在main( void ) 函数中应首先调用本函数, 然后再调用其它函数
//描述:
void IIC_Init( void )
{
#ifdef TWI
PORTD&=~0x80;
DDRC|=(1<<6);
PORTC&=~(1<<6); //WP 使能
TWBR=0x0f ; //速率=16M/(16+2*16)=33.3k
TWAR=0x00;
TWSR=0x00 ; //分频因子=4
#else
Clr_Bit(IIC_PORT,IIC_SDA);//SDA PORT=0
Set_Bit(IIC_DIR,IIC_SCL);//SCL out
Clr_Bit(IIC_PORT,IIC_SCL);//SCL=0
IIC_Stop();
#endif
}
//名称:void IIC_start(void);
//入口:无
//出口:无
//功能:提供I2C总线工作时序中的起始位。
//描述:
void IIC_Start( void )
{
#ifdef TWI
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
#else
Clr_Bit(IIC_DIR,IIC_SDA);//SDA=1
_delay_us(4);
Set_Bit(IIC_PORT,IIC_SCL);//SCL=1
_delay_us(4);
Set_Bit(IIC_DIR,IIC_SDA);//输出为0 设定输出,SDA=0
_delay_us(4);
Clr_Bit(IIC_PORT,IIC_SCL);//SCL=0
_delay_us(4);
#endif
}
//名称:void IIC_Stop(void);
//入口:无
//出口:无
//功能:提供I2C总线工作时序中的停止位。
//描述:
void IIC_Stop( void )
{
#ifdef TWI
TWCR=0x94 ;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
#else
Set_Bit(IIC_DIR,IIC_SDA);//端口为0 设定输出,SDA=0
_delay_us(4);
Clr_Bit(IIC_PORT,IIC_SCL);//SCL=0
_delay_us(4);
Set_Bit(IIC_PORT,IIC_SCL);//SCL=1
_delay_us(4);
Clr_Bit(IIC_DIR,IIC_SDA);//端口为0 设定输入,SDA=1
_delay_us(4);
#endif
}
//名称:void IIC_Ack(void);
//入口:无
//出口:无
//功能:接受应答。
//描述:
void IIC_Ack(void)
{
#ifdef TWI
#else
unsigned char errtime=20;
Clr_Bit(IIC_DIR,IIC_SDA);//SDA=1
Set_Bit(IIC_PORT,IIC_SCL);//SCL=1
_delay_us(4);
while(Get_Bit(IIC_IN,IIC_SDA))
{
errtime--;
if(!errtime)
{
IIC_Stop() ;
Set_Bit(IIC_DIR,IIC_SDA);
}
}
Clr_Bit(IIC_PORT,IIC_SCL);//SCL=0
_delay_us(4);
Clr_Bit(IIC_DIR,IIC_SDA);//SDA=1
#endif
}
//名称:void IIC_Send_Ack( void ) ;
//入口:无
//出口:无
//功能:发送应答。
//描述:
void IIC_Send_Ack( void )
{
#ifdef TWI
#else
Set_Bit(IIC_DIR,IIC_SDA);//端口为0 设定输出,SDA=0
IIC_Clock() ;
Clr_Bit(IIC_DIR,IIC_SDA);
#endif
}
//名称:void SendNotAck_I2C( void ) ;
//入口:无
//出口:无
//功能:发送无应答。
//描述:
void IIC_Send_Not_Ack(void)
{
#ifdef TWI
#else
Clr_Bit(IIC_DIR,IIC_SDA);//数据线保持高,时钟线发生一次从高低的跳变 没有应答
IIC_Clock();
#endif
}
//名称:void IIC_Clock( void );
//入口:无
//出口:无
//功能:提供I2C总线的时钟信号, 并返回在时钟电平为高期间SDA 信号线上状态。本函数可用于数据发送, 也可用于数据接收。
//描述:
void IIC_Clock(void)
{
#ifdef TWI
#else
Set_Bit(IIC_PORT,IIC_SCL);//SCL=1
_delay_us(4);
Clr_Bit(IIC_PORT,IIC_SCL);//SCL=0
_delay_us(4);
#endif
}
//名称:uchar IIC_Send(uchar IIC_data);
//入口:无
//出口:无
//功能:向I2C总线发送8位数据, 并请求一个应答信号ACK。如果收到ACK应答则返回0, 否则返回1(方便后续判断)
//描述:
uchar IIC_Send( uchar IIC_data )
{
uchar i,ack=0;
#ifdef TWI
TWDR=(i2c_data);
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
#else
/* 发送8位数据 */
for ( i=0 ; i<8 ; i++ )
{
if(IIC_data & 0x80 ) Clr_Bit(IIC_DIR,IIC_SDA);//端口为0 设定输入,SDA=1
else Set_Bit(IIC_DIR,IIC_SDA);//端口为0 设定输出,SDA=0
IIC_data = IIC_data << 1 ;
IIC_Clock();
}
/* 请求应答信号ACK */
IIC_Ack();
Clr_Bit(IIC_DIR,IIC_SDA);//端口为0 设定输入,SDA=1
#endif
return ack;
}
//名称:uchar IIC_Receive(void);
//入口:无
//出口:无
//功能:从I2C总线上接收8位数据信号, 并将接收到8位数据作为一个字节返回, 不回送应答信号ACK。主函数在调用本函数之前应保证SDA信号线处于浮置状态。
//描述:
uchar IIC_Receive( void )
{
uchar i,dat = 0 ;
#ifdef TWI
#else
for(i=0;i<8;i++)
{
Set_Bit(IIC_PORT,IIC_SCL);//IIC总线在SCL上升沿读入数据 SCL=1
_delay_us(4);
dat<<=1;
if(Get_Bit(IIC_IN,IIC_SDA)) dat++;
Clr_Bit(IIC_PORT,IIC_SCL);//SCL=0
_delay_us(4);
}
//Clr_Bit(IIC_PORT,IIC_SCL);//SCL=0
#endif
return dat;
}