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]