Talsinpo 发表于 2012-8-17 21:24:42

STC模拟I2C主,HolTek单片机从,为何得不到应答?

STC模拟I2C主,HolTek单片机从,为何得不到应答?

程序是从HolTek官网上下的应用范例,网址:http://www.holtek.com.cn/china/tech/appnote/appnote.htm,例程代号:HA0286S
例程:
我根据例程修改了代码,把主器件换成STC51单片机,从器件用的是同系列HT66F20(例程中用HT66F40)数据手册:主器件接收从器件发送的数据0xAA
主器件代码如下:
//---------------------------------------------------------------------------------------
void N_nop_(u16 i)
{
    do
    {
      _nop_();
    }
    while(i--);
}

void I2C_Init(void)
{
    SCL = 1; N_nop_(60);
    SDA = 1; N_nop_(60);
}

void I2C_Start(void)
{
    SDA = 1; N_nop_(60);
    SCL = 1; N_nop_(60);
    SDA = 0; N_nop_(60);
    SCL = 0; N_nop_(60);   
}

void I2C_Ask(void)
{
    SDA = 0; N_nop_(60);
    SCL = 1; N_nop_(60);
    SCL = 0; N_nop_(60);
    SDA = 1; N_nop_(60);
}

void I2C_NoAsk(void)
{
    SDA = 1; N_nop_(60);
    SCL = 1; N_nop_(60);
    SCL = 0; N_nop_(60);
}

bit I2C_GetAck(void)
{
    bit ack_bit;
    SCL = 1;      N_nop_(60);
    ack_bit = SDA;N_nop_(60);
    SCL = 0;      N_nop_(60);
    return ack_bit;
}

void I2C_Stop(void)
{
    SDA = 0; N_nop_(60);
    SCL = 1; N_nop_(60);
    SDA = 1; N_nop_(60);
    SCL = 0; N_nop_(60);   
}

void I2C_WriteByte(u8 dat)
{
    u8 i, temp;
    temp = dat;
    for(i = 0; i < 8; i++)
    {
      temp = temp << 1;
      SDA = CY; N_nop_(60);
      SCL = 1;N_nop_(60);
      SCL = 0;N_nop_(60);      
    }
    SCL = 0;N_nop_(60);
}

u8 I2C_ReadByte(void)
{
    u8 i, dat;
    for(i = 0; i < 8; i++)
    {
      SCL = 1; N_nop_(60);
      dat = (dat << 1) | ( (u8)(SDA) );
      SCL = 0;
    }
    return dat;
}
//--------------------------------------
void send_data(u8 addr, u8 dat)
{
        I2C_Start();
        I2C_WriteByte(addr);
        while(I2C_GetAck());
    I2C_WriteByte(dat);       
    while(I2C_GetAck());
        I2C_Stop();
}

u8 receve_data(u8 addr)
{
        u8 dat=0;      
        I2C_Start();
        I2C_WriteByte(addr + 1);
        if(I2C_GetAck())
    {
        dat=I2C_ReadByte();
        I2C_NoAsk();
    }
        I2C_Stop();
        return dat;       
}

int main()
{
    u8 temp;
    InitFIFOBuffer(&uart_buffer);
    UARTInit();

    while(1)
    {
          Delay(5000);
          temp = receve_data(0x14);
          UARTSendChar(temp);
   }
    return 0;
}

从器件代码如下:
#include <ht66f20.h>


#define I2C_ADRESS0x14
#pragmavectorI2C_Interrupt @0x20
unsigned char rx_data;
unsigned char tx_data;

void Init_IO(void)
{
    _pac = 0xC0;
    _papu = 0x00;
    _pawu = 0x00;
   
        _adcr1 = 0;
        _adoff = 1;                                                //close AD       
        _acerl = 0;


        _cp0c = 0;
        _cp1c = 0;                                                //close cp
       
        _hlclk = 1;                                                //system clock=fH
       
        _intc0 = 0;
        _intc1 = 0;
        _intc2 = 0;                                                //close interrupt          
}

void Init_I2C(void)               //initial I2C
{
    //_simps0 = 0;
    //_simps1 = 0;                  //simps0:simps1=00: SDA on PA6,SCL on PA7
    _emi = 1;
    _mf2e = 1;
    _sime = 1;                      //enable sim interrupt
    _sima = I2C_ADRESS;                   //set i2c slave address 0x14
    _simc0 = 0xc2;                        //enable i2c,i2c slave mode
}



void I2C_Interrupt(void)
{
//秸刚絏-----------------       
//unsigned int i;
//i = 100;
//while(i--)
//{
//    _pa = 0x00;
//    _delay(1000);
//    _pa = 0xFF;
//    _delay(1000);
//}
//祇瞷êㄇ絏⊿Τ磅︽弧い耞⊿Τ磅︽
//--------------------------
    if(_haas)
    {
      //_haas=1,address match trig interrupt
      if(_srw)
      {
            //srw=1:slave in transfer mode
            _htx = 1;
            _simd = tx_data;
            _txak = 0;
      }
      else
      {
            //srw=0:slave in receive mode
            _htx = 0;
            _txak = 0;
            _acc = _simd;                   //dummy read from simd to release scl line
      }
    }
    else
    {
      //_haas=0,data trig interrupt
      if(_htx)
      {
            //htx=1:slave in write state;
            if(_rxak)
            {
                //rxak=1:master stop receiving next byte,master releases scl bus
                _htx = 0;
                _txak = 0;
                _acc = _simd;       //dummy read from simd to release scl line
            }
            else
            {
                //rxak=0:master wants to receive next byte;
                _simd = tx_data;
            }
      }
      else
      {
            //htx=0:slave in read state
            rx_data = _simd;
//          _pc = rx_data;          //receive data show by pc port
            _txak = 0;
      }
    }
    _simf = 0;                      //clr i2c interrupt flag
}

void main(void)
{
    Init_IO();
    Init_I2C();
    while(1)
    {
                tx_data = 0xAA;
    }
    //return 0;       
}
页: [1]
查看完整版本: STC模拟I2C主,HolTek单片机从,为何得不到应答?