MSP430247 硬件I2C程序

楼主
MSP430247 硬件I2C程序
各位,新年好!祝大家新年工作愉快!
谁能给我个硬件I2C操作AT24C02的程序?
我老是卡住,有时通有时不通,谁能帮帮忙啊,郁闷了很久!
下面是我的程序,哪位有空帮看下:

void I2CInit(unsigned char SA)
{
  P3SEL |= 0x06;                            // Assign I2C pins to USCI_B0
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
  UCB0BR0 = 80;                             // fSCL = SMCLK/80 = ~100kHz
  UCB0BR1 = 0;
  UCB0I2CSA = SA;                         // Slave Address is 2ch
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
}
uint16 NVMRead(uint16 addr)
{
    unsigned char data;
    I2CInit(0x50);
    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent
    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
    while((IFG2 & UCB0TXIFG)==0);
    UCB0TXBUF = (unsigned char) (addr&0x00ff);////eeprom low addr
    while((IFG2 & UCB0TXIFG)==0); //老是卡在这个位置,而且断电重来都不行.但是有时候通,只要不通了断电也没用。
    IFG2 &= ~UCB0TXIFG;                                      

    UCB0CTL1 &= ~UCTR;             // I2C RX,
    while (UCB0CTL1 & UCTXSTP);               // 判断总线是否被释放
    UCB0CTL1 |= UCTXSTT;           // Start condition
    while((UCB0CTL1&UCTXSTT)==1);
    while((IFG2&UCB0RXIFG)==0);
    data = UCB0RXBUF;
    delay100us();
    UCB0CTL1 |= UCTXSTP + UCTXNACK;
    while((UCB0CTL1 & UCTXSTP)==1);  
    return data;
}
 
uint8 NVMWrite(uint16 addr, uint8 data)
{
    I2CInit(0x50);
    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent
    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
    while((IFG2 & UCB0TXIFG)==0);
    UCB0TXBUF = (unsigned char) (addr&0x00ff);
    while((IFG2 & UCB0TXIFG)==0);
    UCB0TXBUF = data;
    while((IFG2 & UCB0TXIFG)==0);
    UCB0CTL1 |= UCTXSTP + UCTXNACK;                    // I2C stop condition    
    while((UCB0CTL1 & UCTXSTP)==1);
    delayms(10);
    return 1;
}
 
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  BCSCTL1=CALBC1_16MHZ;  
  DCOCTL=CALDCO_16MHZ;        //DCOCLK设置16M
  BCSCTL2 = DIVM0 | DIVS0;  //16M DCOCLK经2分频得到8M MCLK和8M SMCLK
 
  NVMRead(0);
 
}
 
1楼
楼主新年好!
“有时通有时不通”这样可以推断出你的软件设置、操作流程基本上没啥问题了。否则不会出现“通”的时候呢。
请问一下楼主你是如何认定为“通”呢?你读出的数据是不是早已写入EERPOM了?如果是,你的写操作程序是上面的程序吗?
我不知道楼主的外部连线是如何连接的,你可否将IIC模块的时钟频率再降到20-50K试试呢。
你的main()程序中,在读与写之间可以加一个10ms级以上的延时;同样,读操作重复的话建议后也增加一个大延时。在main中建议增加一个loop在里做控制,否则程序会跑掉或重启。

关于说到MSP430的IIC模块,我的感觉是TI写的模块子程序很多配合中断方式进行,极少见到过有查询方式的。同时,我所接触的网友,很多都反映TI的IIC模块不太好利,就以你上面的查询标志为例;在调步调试时极容易出错。或在标志查询时难以通过。
在实际的应用中,我觉得用查询方式比较灵活使用;没必要样样都使用配合中断来使用。这样极为不便。可惜在这查询控制IIC读写方面的例子基本上没有。
另外,MSP430的系列较多,模块的例子使用好似都有不同。比如F16的和F24的及F5系列的及部分F4系列新型号中,同样的程序移植过后在很多新的型号中都难以调通。或感觉有bug...。
总之我过往的感受是MSP430的IIC很多问题,难以使用;相对其他公司的IIC很少有这样的难用情况。看来我说了很多IIC不满...;不知一些用过IIC模块的网友是不是有这样的同感呢。欢迎讨论。
2楼
感谢版主的关注!
问题已经解决了,解决办法:在每次I2C操作之间需要留一点时间!我留了1ms。
我之前的Main里面有连续调用导致Stop和下一个Start时序上挨的太近,所以出错,只是出错了以后不知道是MSCU原因还是外设的原因,I2C会很久没有响应,在这种情况下我开贴的Main也是不通的。
具体是什么导致长时间不通,首先MCU程序能跑,波形可以看到。所以我估计还是外设对于错误时序没有响应,类似进入死机状态。
TI的I2C用查询不是很安全,万一不通全死了,我想中断会更合理,后续还是要改中断方式。
3楼
正如我所说“你的main()程序中,在读与写之间可以加一个10ms级以上的延时;”。
我可以利用这段代码用在微控的开发板上测试一下;正实一下查询可靠性如何...。
我觉得查询还是比较方便,当外部的IIC器件挂得较多时,如果都在IIC的中断服务程序处做这么多的接收或发送很多操作时那就很不方便。
我觉得更不方便的就是当用程序写成公共函数时就相当不方便了,如果用查询方式那么可以很大方便将其封装成函数不依赖中断服务程序。在移植或打包极为方便。
正是这样,TI的例子就往往没有提供到样的参考例子...。难理解为什么不出这样的例子。
4楼
版主,借帖子咨询下,我现在有个库文件是针对430F2xx系列编译的,后续我想用430F5xx系列,是否可以通用呢?还是必须重新编译,环境为IAR。
5楼
是否支持要看你所使用工具软件的版本号是否>4.11或以上;旧版本有些器件未加入器件列表中。

电脑版 Page created in 0.2031 seconds width 5 queries.