Beispiel #1
0
/*----------------------------------------------------------------
                 字节数据传送函数               
函数原型: void  SendByte(unsigned char c);
功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
     此状态位进行操作.(不应答或非应答都使ack=0 假)     
     发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
------------------------------------------------------------------*/
void  I2C_SendByte(unsigned char c)
{
    unsigned char BitCnt;

    for(BitCnt = 0; BitCnt < 8; BitCnt++)   //要传送的数据长度为8位
    {
        if(( c << BitCnt) & 0x80)           //判断发送位
        {
            SDA(1);
        }
        else
        {
            SDA(0);
        }
        _delay_us(10);
        SCL(1);             //置时钟线为高,通知被控器开始接收数据位
        _delay_us(15);      //保证时钟高电平周期大于4μ        
        SCL(0); 
    }
    //SDA(1);                   //8位发送完后释放数据线,准备接收应答位
    DDRF  &= ~(1 << PF7);       // 变为输入
    PORTF |=  (1 << PF7);
    _delay_us(30);              // without this wait read unstable value.
    SCL(1);
   _delay_us(15);
    if(Read_SDA())
        ack = 0;     
    else
        ack = 1;            //判断是否接收到应答信号
    SCL(0);
    SDA(0);                 // 变为输出
    _delay_us(10);
}
Beispiel #2
0
/*------------------------------------------------
                    结束总线
------------------------------------------------*/
void I2C_Stop(void)
{
    SDA(0);    	//发送结束条件的数据信号
    _delay_us(10); //发送结束条件的时钟信号
    SCL(1);    //结束条件建立时间大于4μ
    _delay_us(10);
    SDA(1);    //发送I2C总线结束信号
    _delay_us(10);
}
Beispiel #3
0
/*------------------------------------------------
                    启动总线
------------------------------------------------*/
void I2C_Start(void)
{
    SDA(1);     //发送起始条件的数据信号
    _delay_us(5);
    SCL(1);
    _delay_us(10);     //起始条件建立时间大于4.7us,延时
    SDA(0);     //发送起始信号
    _delay_us(10);     //起始条件锁定时间大于4μ
    SCL(0);     //钳住I2C总线,准备发送或接收数据
    _delay_us(10);
}
Beispiel #4
0
/*----------------------------------------------------------------
                 字节数据传送函数               
函数原型: unsigned char  I2C_RcvByte();
功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
     发完后请用应答函数。  
------------------------------------------------------------------*/	
unsigned char  I2C_RcvByte(void)
{
    unsigned char retc;
    unsigned char BitCnt;

    retc=0; 
    SDA(1);             //置数据线为输入方式
    for(BitCnt = 0; BitCnt < 8; BitCnt++)
    {
        _Nop();           
        SCL(0);       //置时钟线为低,准备接收数据位
        _Nop();
        _Nop();      //时钟低电平周期大于4.7us
        _Nop();
        _Nop();
        _Nop();
        SCL(1);       //置时钟线为高使数据线上数据有效
        _Nop();
        _Nop();
        retc = retc << 1;
        if(Read_SDA())
            retc = retc + 1; //读数据位,接收的数据位放入retc中
        _Nop();
        _Nop(); 
    }
    SCL(0);    
    _Nop();
    _Nop();
    return(retc);
}
Beispiel #5
0
static void i2c_soft_stop(void)
{
    SCL1();
    waitSomeTimeInUs(2);
    SDA(1);
    waitSomeTimeInUs(1);
}
Beispiel #6
0
static uint8_t i2c_soft_receive_bit(void)
{
    // SDA = 1
    // SCL = 1
    // wait SCL low
    // bit = SDA
    // SCL = 0
    
    uint8_t bit;
    
    SDA(1);
    waitSomeTimeInUs(1);
    
    SCL1();
    waitSomeTimeInUs(1);
    while( GET_SCL() == 0);
    
    bit = GET_SDA();
    
    SCL0();
    SDA_OUTPUT();
    waitSomeTimeInUs(1);
    
    return bit;
}
Beispiel #7
0
static void i2c_soft_send_bit(uint8_t bit)
{
    // set bit on SDA
    // NOP
    // SCL = 1
    // wait SCL low
    // then SCL = 0

    SDA((bit&0x1));
    waitSomeTimeInUs(1);
    SCL1();
    waitSomeTimeInUs(2);
    
    SCL0();
    waitSomeTimeInUs(1);
}
Beispiel #8
0
/*----------------------------------------------------------------
                     非应答子函数
原型:  void NoAck_I2c(void);
 
----------------------------------------------------------------*/
void NoAck_I2c(void)
{
  
    SDA(1);
    _Nop();
    _Nop();
    _Nop();      
    SCL(1);
    _Nop();
    _Nop();              //时钟低电平周期大于4μ
    _Nop();
    _Nop();
    _Nop();  
    SCL(0);                //清时钟线,钳住I2C总线以便继续接收
    _Nop();
    _Nop();    
}
Beispiel #9
0
static void i2c_soft_start(void)
{
    SDA(0);
    SCL0();
    waitSomeTimeInUs(1);
}
Beispiel #10
0
unsigned char read_SDA(void) // Set SDA as input and return current level of line, 0 or 1
{
	SDA_IN();
	return !!SDA();
}