调试完了FAST GPIO,开始进入I2C接口调试,主要实现对PCF8574的控制,整个程序是个状态机,I2C 中断服务程序根据不同的状态确定下一步要做的事情。首先确定8574的地址,由于原理图上我接的是A1,A2,A3为0,故地址为0x40. 在调试时发现一个令人很迷茫的问题。每当程序复位后开始运行,发送I2C的Start 位后,也能进入I2C中断,就是在进入switch case 语句时,只要对STA(起始位),SI(中断位)清零都会导致整个积存器被清零。郁闷的不行,manual 来来回回看了N遍觉得没错啊,就是不知问题出在那里。
最后实在是没辙了,在SI清除指令后,再清除一次,居然行了,I2C可以正常的发送数据了,然后我把多余的指令删掉,放一条__nop_operation; 发现也是可以的,可能是因为位清除的操作指令执行的太快了的缘故。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
下面是I2C 发送数据给8574的程序:
我用了中断处理加环型对列的结构,pTx 只指向发送缓冲区, pRx指向接收缓冲区。
void I2C0_ISR(void)
{
INT8U bus_state;
queue * pTx;
queue * pRx;
pTx = & TxBuffer;
pRx = & RxBuffer;
bus_state = Get_I2CState();
switch (bus_state & 0xF8)
{
//-----------------------------------------------------------------------------
//I2C interrupt Status int the Master Tranceiver mode
//-----------------------------------------------------------------------------
case 0x0:
I2C_BusPend;
break;
case 0x08: //bus is initiate
I2C_SendAddr(ADDR8574, rw);
I2C_StartClr;
break;
case 0x18: //control logic receive the Ack for address
if(pTx->s==1)
I2C0DAT = Queue_DataOut(pTx);
else
I2C_BusPend;
break;
case 0x20: //doesn't get the ACK pluse
I2C_BusPend;
I2C_BusStart;
break;
case 0x28: //ACK inform the master get the data
if(pTx->s==0)
I2C_BusPend;
break;
case 0x10:
I2C_StartClr;
I2C_SendAddr(ADDR8574, rw);
break;
case 0x30: //Send data error
I2C_BusPend;
break;
//-----------------------------------------------------------------------------
//I2C interrupt Status int the Master receiver mode
//Add code here for the I2C bus in the Master receiver mode
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//I2C interrupt Status int the Slave Tranceiver mode
//Add code here for the I2C bus in the Slave Tranceiver mode
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//I2C interrupt Status int the Slave receiver mode
//Add code here for the I2C bus in the Slave receiver mode
//-----------------------------------------------------------------------------
default: break;
}
I2C_ISRClr;
}
文章评论(0条评论)
登录后参与讨论