我想学学430单片机自带的IIC模块使用,现在编了段小程序,可是运行不正确,程序如下,问题在最后面。
//初始化IIC模块
UCB0CTL1 |= UCSWRST;
UCB0CTL0 |=UCMST+UCMODE1+UCMODE0+UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCMODE1+UCMODE0+UCSWRST; // Use SMCLK, keep software reset
P3SEL |=0x06; //p3.1为UCB0SDA,P3.2为UCB0SCL
UCB0CTL1 = UCSSEL_3+UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 =10; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST; // Clear software reset, resume operation
//写函数
UCB0CTL0 |=UCMST+UCMODE_3+UCSYNC; // I2C Master, synchronous mode
//UCB0CTL1 = UCMODE1+UCMODE0+UCSWRST; // Use SMCLK, keep software reset
UCB0I2CSA = 0x3a; //这个地址是真实地址后面加读/写位组成
UCB0CTL0 &=~UCSLA10; //从机地址为7位
UCB0CTL1 |= UCTR;//transmitter mode 发送模式
UCB0CTL1 |= UCTXSTT; //start condition,
while((IFG2 & UCB0TXIFG) != UCB0TXIFG);//检测UCB0TXBUF是否为空,为空则UCB0TXIFG为1.
for(i=0;i<1;i++)
{
UCB0TXBUF = 0x0d;//IIC设备中寄存器的地址
while((UCB0CTL1 & UCTXSTT) == UCTXSTT);//检测从机ACK信号,有ACK信号,则UCTXSTT自动清零//以上顺序不能改变
while((IFG2 & UCB0TXIFG) != UCB0TXIFG);//检测UCB0TXBUF是否为空,
}
UCB0CTL1 |= UCTXSTP;//发送STOP信号
我的问题是 :
1. UCB0CTL1 |= UCTXSTT; 也就是发送START后示波器上显示的IIC从设备的地址信息不对;
2. UCB0TXBUF = 0x0d,运行后,示波器没反应更谈不上有ACK信号,可是却通过了while((UCB0CTL1 & UCTXSTT) == UCTXSTT判断是否有确认信号的这句话;
3. 程序停在了倒数第二句话while((IFG2 & UCB0TXIFG) != UCB0TXIFG);//检测UCB0TXBUF是否为空,既然已经把数据0x0d送到发送缓冲中去,就应该有输出,而且UCB0TXBUF为空才对啊?
向大家请教了!!
我解释一下出现的问题,我要发送的IIC从设备的地址是0x3A如图中所示示波器的波形。
其中最开始的是START位,之后是011101001
首先,正确的地址应该是0011 1010才对
我分析:
1. 也许IIC从设备的MSB位基本上都是0,被舍去一个,所以变成了011 1010
2. 至于011 1010后面的两位01,我想可以把图中用红色粗线标出的0当做ACK信号,可是后面的1是什么意思呢?
3.关键问题在于发送IIC从设备的地址后,我就当取得了ACK信号,之后编辑了一条指令UCB0TXBUF = 0x0d想通过它发送IIC从设备中寄存器的地址,也就是sub-address,为什么没有输出?这个问题挺困扰我的。如果有了输出,我就可以看看进一步输出正确数据后是否还有ACK信号。结果由于没有输出调试就停滞不前了
有没有调试过430自带IIC模块的人,帮忙说两句,提个醒儿。
如何才能发送出去数据,想通过UCB0TXBUF = 0x0d发出数据对吗?为什么没有输出呢?
[ 本帖最后由 wqy 于 2013-3-20 20:37 编辑 ]
根据手册的描述:
The address is right-justified. In 7-bit slave addressing mode, bit 6 is the MSB, and bits 9-7 are ignored.
[ 本帖最后由 wstt 于 2013-3-21 13:19 编辑 ]
据此:
数据为0111010 (RW)
回复 4楼 wstt 的帖子
可能是网络不好,刚刚回复了一个,结果白写那么多了。呵呵
您的回答非常专业,能看出来您对我调试的这款芯片非常了解,首先谢谢您的热心回复!
确实,我也看到The address is right-justified. In 7-bit slave addressing mode, bit 6 is the MSB, and bits 9-7 are ignored,所以推测我发送的地址00111010被去掉了首位,可是从示波器监测结果看收到的0111010 01 是否可以把倒数第二位当做ACK呢?那最后一位又代表什么意思呢?
我仔细看了datasheet,其中给出了IIC主设备发送时候的图,按照图中给的信息,我仔细对照了所有相关的寄存器,发送IIC从设备地址后,寄存器值显示是有ACK信号的。可是在我把IIC从设备的sub-address送人UCB0TXBUF之后,总线上并没有相应的数据出现,这是为什么呢?
还有个问题,就是在示波器中显示的这一串数据,并不是连续的,前一部分发的是01110过了有150ms才又发出1 0 01 ,这种情况不知道您遇到过没有。我觉得这个间歇时间过长了,不知道是什么引起的。
期待专家的进一步答疑解惑,另外为了表示感谢我想把所有的积分都给您,怎么给?
[ 本帖最后由 wqy 于 2013-3-21 15:31 编辑 ]
- //******************************************************************************
- // MSP430G2xx3 Demo - USCI_B0 I2C Master Interface to DAC8571, Write
- //
- // Description: Using UCB0TXIE, a continuous sine wave is output to the
- // external DAC using a 16-point look-up table. Only one start condition
- // is executed. Data is handled by the ISR and the CPU is normally in LPM0.
- // ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.2MHz
- //
- // MSP430G2xx3 DAC8571
- // ------------------ ------------
- // -|XIN P1.7/UCB0SDA|<--------------->|SDA |
- // | P1.6/UCB0SCL|---------------->|SCL I2C |
- // -|XOUT | | SLAVE |
- // | I2C MASTER | GND|A0 |
- //
- //
- // DAC8571 I2C address = 0x4C (A0 = GND)
- //
- // D. Dang
- // Texas Instruments Inc.
- // February 2011
- // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
- //******************************************************************************
- #include "msp430g2553.h"
- const unsigned char Sine_Tab[] = // 16 Point 16-bit Sine Table
- {
- 0xFF, // MSB Word 0
- 0xFF, // LSB
- 0xF6, // MSB Word 1
- 0x40, // LSB
- 0xDA, // MSB Word 2
- 0x81, // LSB
- 0xB0, // MSB Word 3
- 0xFA, // LSB
- 0x7F, // MSB Word 4
- 0xFF, // LSB
- 0x4F, // MSB Word 5
- 0x03, // LSB
- 0x25, // MSB Word 6
- 0x7C, // LSB
- 0x09, // MSB Word 7
- 0xBD, // LSB
- 0x00, // MSB Word 8
- 0x00, // LSB
- 0x09, // MSB Word 9
- 0xBD, // LSB
- 0x25, // MSB Word 10
- 0x7C, // LSB
- 0x4F, // MSB Word 11
- 0x03, // LSB
- 0x7F, // MSB Word 12
- 0xFE, // LSB
- 0xB0, // MSB Word 13
- 0xFA, // LSB
- 0xDA, // MSB Word 14
- 0x81, // LSB
- 0xF6, // MSB Word 15
- 0x40 // LSB
- };
- void main(void)
- {
- WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer
- P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
- P1SEL2|= BIT6 + BIT7; // 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 = 12; // fSCL = SMCLK/12 = ~100kHz
- UCB0BR1 = 0;
- UCB0I2CSA = 0x4c; // Set slave address
- UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
- IE2 |= UCB0TXIE; // Enable TX ready interrupt
- UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
- UCB0TXBUF = 0x010; // Write DAC control byte
- __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
- }
- // USCI_B0 Data ISR
- #pragma vector = USCIAB0TX_VECTOR
- __interrupt void USCIAB0TX_ISR(void)
- {
- static unsigned char ByteCtr;
- UCB0TXBUF = Sine_Tab[ByteCtr++]; // Transmit data byte
- ByteCtr &= 0x1f; // Do not exceed table
- }
“把IIC从设备的sub-address送人UCB0TXBUF之后”,看到这句话,我猜测可能操作流程上有些小问题。
观察上面这段示例代码,其实写从地址的操作不需要你发到TXBUF中,这个过程会由MSP430自动完成。
回复 6楼 wstt 的帖子
我用没有意义的数据当地址试了试,结果示波器上显示的除了要输出的没有意义的数据外后面都跟着01。即使我发真实的IIC从设备的地址一样在后面跟个01,也就是说发正确的地址也没有获得IIC从设备的确认信号。
还有,实在是不好意思,我没有太看懂您给我粘贴的程序哪里是发送从地址的语句,麻烦您给我简单解释一下行吗?急死了。
我觉得我表述的不对,现在更正一下:
我所说的IIC从设备的地址是address;我所说的从地址是IIC从设备内部的寄存器的地址sub-address
我先把IIC从设备地址给了UCB0I2CSA = 0x1d;
在我想配置IIC从设备内部寄存器的时候就把寄存器地址给了缓冲区UCB0TXBUF = CTRL_REG3;(#define CTRL_REG3 0x23)
拜谢了!
[ 本帖最后由 wqy 于 2013-3-21 22:04 编辑 ]
UCB0I2CSA = 0x4c; // Set slave address
这个就是从设备地址。
回复 8楼 wstt 的帖子
版主你人最好了哈哈哈哈
话说怎么用示波器来看波形,然后怎么去看那个捕捉到的波形?一上一下是不是就是1跟0啊