工具/软件:Code Composer Studio
我正在MSP430F5529LP评估板(默认时钟速率)上编写通用的,基于轮询的I2C主RX/TX驱动程序。 我有一个Adafruit metro微型(基于Arduino)板,它作为从变送器在我请求读取时发送"Hello"。
我的写功能工作正常,但当我尝试阅读时,我会遇到奇怪的行为。 从XBUF读取的第一个字节是垃圾,但整个消息以连续读取的方式接收。 如果我逐步执行代码,第一个字节不再是垃圾,我可以正确地接收整个消息。 这让我觉得我没有检查启动条件后是否正确设置了某些IFG/CCL标志,因此出现了计时问题。 令人困惑的是,如果我在发出启动条件之前阅读了RXBUF,则所有字节数都可以正确读取。 我在用户指南中没有看到任何明显的内容,让我认为这是正确的(似乎更像是黑客),所以我希望你们看到我的问题。
I2C::i2c (I2C_Type端口,uint8_t clkDiv)
{
SWITCH((Int16_t)port)
{
CASE USCIB0:
UCxxCTL1 = &UCB0CTL1;
UCxxCTL0 =&UCB0CTL0;
UCxxBR0 =&UCB0BR0;
UCxxBR1 =&UCB0BR1 = UCBI0CSA;
UC2I
UCxxIFG =&UCB0IFG;
UCxxRXBUF =&UCB0RXBUF;
UCxxTXBUF =&UCB0TXBUF;
Break;
Case USCIB1:
UCxxCTL1 =&UCB1CTL1;
UCxxCTL0 =&UCB1CTL0;
UCxxBR0 = CBI1BR1
=
UCxxIFG =&UCB1IFG;
UCxxRXBUF =&UCB1RXBUF;
UCxxTXBUF =&UCB1TXBUF;
中断;
默认:
返回
;}
pinSetup();
*UCxxCTL1 || UCSWRST; //启用软件重置
*UCxxCTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C主控,同步模式
*UCxxCTL1 = UCSSEL_2 + UCSSWRST; //使用SMCLK,保持软件重置
// *UCxxI2CSA = 0x04;
*UCxxBR0 = clkDiv; //将时钟分配器应用到SMCLK
*UCxxBR1 =0;
*UCxxCTL1 &=~UCSWRST; //清除软件重置,恢复操作
*UCxxIE =0;
*UCxxIFG =0; //清除中断标志
}
bool i2c::start(bool isRead)
{//
设置I2C r/w位,发送启动条件
if (isRead == false)
{
*UCxxCTL1 |= UCCTR|UCTXSTT;
}
else
{
*UCxxCTL1 || UCTXSTT;
*UCxxCTL1 &= UCCM= UIFG;~
UCNIFG}}
bool i2c::stop(void){//
等待停止条件被接受
uint16_t count =5000;
*UCxxCTL1 || UCTXSTP;
while (*UCxxCTL1 & UCTXSTP)=UCTXSTP)
{
COUNT--;
IF (count <= 0)
return false; STP
return true;
}
uINT8_t i2c::read(uint8_t address, uint8_t* data, uint8_t length, bool endered)
{//
保留读
uint8_t的字节数br =0;//
分配从属地址
*UCxxI2CSA =地址;
{//
如果我不清除RXBUF=xxUXbf
,将读取一个垃圾字节
//发出启动请求
if (start(true)== false)
{//
无论状态是否重复,都发出stop和terminate
stop();
返回br
;}
for (uint8_t idx =0;idx <长度;idx++)
{
Int16_t
计数=10;//等待上一个Rx完成。while (!(*UCxxIFG & UCRXIFG){- delay;_100);
如果(计数<= 0)
{//
无论状态是否重复,发出stop和terminate
stop();
返回0;
}
data[br+]=
*UCxxRXBUF;
}//
调用函数将发出重复启动,如果
(REPLUSTED == false)
stop(),则不要发出stop;
返回br;
}