最近用MSP430F4152做一个项目,在调试其USCI的I2C发现个严重问题,就是:假若430作为主机,接收从机的数据,但该型号没有设置指定接收字节个数的寄存器,而主机又是自动应答,那么数据就是一直接收,而接受的BUFFER是8位的,那么我去读接收寄存器就会读到最新的一个数据而已。
但我现在需要读一开始的4个字节,这个怎么处理好呢?急急急啊,请大虾们赐教。
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
最近用MSP430F4152做一个项目,在调试其USCI的I2C发现个严重问题,就是:假若430作为主机,接收从机的数据,但该型号没有设置指定接收字节个数的寄存器,而主机又是自动应答,那么数据就是一直接收,而接受的BUFFER是8位的,那么我去读接收寄存器就会读到最新的一个数据而已。
但我现在需要读一开始的4个字节,这个怎么处理好呢?急急急啊,请大虾们赐教。
如果是这样的话那么完全没必要担心,lz可以设置一个char型的数组,用于接收从机发来的数据,只有你读了buffer里的数据,从机才会发送下一个数据。
先确定下楼主的意思:是想让工作在主机的MSP430固定从I2C从机读一定字节数的数据上来。而如果采样硬件I2C的话,由于时钟和应答(ACK)是由MSP430发出的,所以在接收到最后一个字节后,MSP430无法发出NACK信号,而MSP430还会继续发送CLK读下一个字节。
其实MSP430是支持在读到最后一位后发送N-ACK信号的。楼主需要用软件做个计数器,在接收到倒数一个字节数时,设置UCTXSTP=1,这样在接收完下一个数据后,MSP430会自动发送N-ACK信号,并且发送停止信号,并停止从从机读数上来.
另外关于BUFFER中的数据会不会被新的数据覆盖,不用担心,因为:
If UCBxRXBUF is not read the master holds the bus during reception of the last data bit and until the UCBxRXBUF is read.
UCBxRXBUF的数据不被读出,MSP430会拉住总线直到BUF的数被读走.
自认为硬件I2C都调试好了,但昨天又发现了奇怪的问题,下面是我读slave device数据的一小段代码(问题在代码注释中提到):
//简单的读EEPROM的程序,写地址有应答,用的等待读标志UCB0RXIFG来读取数据,没有用到中断
void Read_EEPROM(unsigned char row,unsigned char page)
{
unsigned char i=6,Rx_data[6];
while (UCB0CTL1 & UCTXSTP);
UCB0CTL1 |= UCTR + UCTXSTT;
UCB0I2CSA = 0x57;
while((IFG2&UCB0TXIFG)==0);
UCB0TXBUF = row;
while((IFG2&UCB0TXIFG)==0);//(1)?程序时常会在这句卡住不运行
UCB0TXBUF = page;
//上面部分是写EEPROM设备地址和读地址(page,row)
//下面部分是从指定的地址读6个字节
IFG2 &= ~UCB0TXIFG;
UCB0CTL1 &=~UCTR;
UCB0CTL1 |=UCTXSTT;
while((IFG2&UCTXSTT)==1); //等待从机地址是否应答
while(i--) //(2)?单步调试的时候,每运行一行程序, UCB0RXBUF的值都会发生变化,最后得到的值也乱七八糟
{
while((IFG2&UCB0RXIFG)==0);
if(i)
{
Rx_data[i] =UCB0RXBUF;
if(i==1)UCB0CTL1 |= UCTXSTP;
}
else Rx_data[i] =UCB0RXBUF;
}
}
请大虾指点一下啊,我现在在I2C上挂了3个不同片子,有时运行挺好的,但现在又不行了(单个测试也是),出现的问题也比较类似。应该是硬件MSP430的I2C配置问题,针对我程序我提出了两点疑问,请大神解释下why,多谢!!!