大家好!
我正在尝试为我的MSP430F2618构建自定义I2C驱动程序。 该驱动程序用于在没有ISR的情况下运行,并且具有大量错误检查/处理。 我已经尝试让它运行几个星期了,我成功地捕获了一些错误,但它总是在发送设备地址后挂起,即使接收设备将地址加密。 以下是相关代码。 所有引脚,端口,时钟速率等的初始化都以另一种方法处理。 已根据MSP430系列用户指南和TI的I2C代码示例对这些代码进行了检查,因此我认为问题不存在。 如果需要,我可以提供,但我不想让读者对整个文件的代码感到不知所措。 此外,提及"主要"是指此代码旨在与F2618中内置的两个I2C接口之一配合使用。 下面仅是“主要”(USCIB0)的代码,因为“辅助”的代码只是一个精确的副本。
提前感谢您!
John
void i2cSendMessage(I2CMessage* messageStrut){//errors needed to be handled
//local variables
char nackCount =0;
int i =0;
char singleByteRXFlag =0;
//错误检查
(!messageStrut){//Null指针
OSUnprotect();
return;
}
IF (messageStrut->isInitialized != is_initialized){//message has not been initialized'
messageStruct -> error = I2CERR_struct_NOT_initialized;
OSUnprotect();
return;
}//Lessgo
如果(!Get_primary_is_active){//界面未激活
messageStruct -> error = I2CERR_INTERFACE_NOT_ACTIVE;
返回;//必须手动激活
}
//初始化
UCB0I2CSA =消息结构->地址;//设置地址
如果(messageStruct -> messageLength > 0){//如果没有TX,则我们要直接转到RX部分
start_primary_I2C;//设置启动条件
}
I = 0;
while (I < messageStrut->messageLength ){//仅处理RX的情况:如果消息为空,而循环永远不会运行
如果(!GET_PRIMARY_TX_READY){
如果(primary_Get_nack){//如果从属设备传输了nack,则再次发送同一字节
nackCount++;
如果(nackCount >= MAX_nack){//Slave unreachable,中止以防止操作系统停止
STOP_PRIMARY_I2C;
disable_primary_I2C;//从属设备问题,因此关闭接口以防止未定义的行为(但不确定是什么行为)
messageStruct -> error = I2CERR_nack_limit_reached;
返回;
}
start_primary_I2C;//重复启动
}
继续;
} 否则{
UCB0TXBUF =消息结构->消息[I];
nackCount = 0;//字节已通过,从属设备可访问。
I++;
}
}
//接收
如果(messageStrut->txrxMode == RX_mode){
int j =0;
UCB0CTL1 &=~UCTR;//设置为接收模式
start_primary_I2C;//(重复)启动条件
IFG2 &=~UCB0TXIFG;//清除TX标志(数据表告诉我)
同时(j < messageStrut->respLen){
如果(!GET_PRIMARY_RX_READY){
如果(primary_Get_nack){//未确认地址(仅在输入循环时才可能发生)
start_primary_I2C;//重复启动
继续;
}
如果(messageStrut->respLen ==1)&& primary_Get_STT_CLr){//发送停止条件。如果只接收一个字节(来自数据表),则只要清除STT就会立即停止条件
STOP_PRIMARY_I2C;//根据I2C规范的要求自动发送最终nack。
singleByteRXFlag = 1;
继续;
}
}其他{
messageStrut->Response[j]= UCB0RXBUF;
J++;
}
}
//全部完成(非常确定...)
}
//停止通信
如果(!singleByteRXFlag){//阻止重复停止(不知道这是否是问题)
STOP_PRIMARY_I2C;
}
messageStruct -> error = I2CERR_NO_ERROR;
返回;
}