主题中讨论的其他器件:MSP430FR2355
您好!
在 I2C 传输中、我似乎无法读取多个完整字节。 我使用的是一个主器件和一个从器件。 MSP430FR2355是主器件、而 Maxim 的 DS1307实时时钟是从器件。
如何正确读取多个字节? 我有什么问题吗?
DS1307的数据表: cdn.sparkfun.com/.../DS1307.pdf
读取1个字节
这是读取一个字节时发生的情况(看起来是正确的):
图1:
以下是读取数据后的存储器转储:
(mspdebug) MD 0x0540 00540:C0 0f 08 00 00 08 00 01 00 00 00 00 00 00 |.......... | 00550:00 00 00 00 00 00 00 00 00 00 00 00 68 00 ff 03 | H..| 00560:68 00 00 00 00 00 00 00 00 00 00 61 00 08 40 00 |小时 A..@ 00570:FF 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f |???????????| (mspdebug) MD 0x056C 0056c:08 40 00 00 ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f |@…………………………………………………………………………………………… 0057c:FF 3f ff 3f 01 00 03 00 00 00 00 00 00 00 00 00 00 00 |..?.......... | 0058c:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.......... | 0059c:02 00 00 00 00 ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ?????????|
读取2个字节
当我读取两个字节时、数据线在第三个帧的第7个字节(要读取的第二个字节)之后挂起低电平:
图2:
它在大约15ms 内保持低电平:
图3:
这些是尝试读取两个字节后的内存转储:
(mspdebug) MD 0x0540 00540:C0 0f 08 00 00 08 00 00 02 00 10 00 00 00 |.......... | 00550:00 00 00 00 00 00 00 00 00 00 00 00 68 00 ff 03 | H..| 00560:68 00 00 00 00 00 00 00 00 00 00 61 00 08 40 00 |小时 A..@ 00570:FF 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f |???????????| (mspdebug) MD 0x056C 0056c:08 40 00 00 ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f |@…………………………………………………………………………………………… 0057c:FF 3f ff 3f 01 00 03 00 00 00 00 00 00 00 00 00 00 00 |..?.......... | 0058c:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.......... | 0059c:02 00 00 00 00 ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 3f ?????????|
读取5个字节
当尝试读取5个字节时、SDA 线路挂起低电平、这与读取2个字节时类似:
图4:
但是、在 SDA 和 SCL 再次释放之前、似乎有人尝试在130ms 的时间范围内再次开始传输:
图5:
代码
这是我读取1个字节的代码。 读取2个字节和读取5个字节只是由于 NNBytes = 2和 NNBytes = 5而有所不同。
#include
#include
void Init_gpio();
const int NNBytes = 1;
volatile uint8_t RXData;
int main (void)
{
WDTCTL = WDTPW | WDTHOLD;
//配置 GPIO */
Init_gpio ();
PM5CTL0 &&=~
~LOCKLPM5;//将 P2.3配置为输入开关以发送 I2C;
= P2IT3 |= 3 | BITS= 3 | BIT23;= BIT23;= BIT3 | BIT23;= BIT23;= BIT23;= BIT23;= BIT23;= BIT23;= BIT23;=
P2IFG = 0;
P2IE |= BIT3;
//配置 I2C */
P1OUT &=~BIT0; //清除 P1.0输出锁存
器 P6OUT &=~BIT6; //清除 P6.6输出锁存
器 P1DIR |= BIT0; //对于 LED
P6DIR |= BIT6; //对于 LED
P1SEL0 |= BIT2 | BIT3; // I2C 引脚:SDA | SCL
//为 I2C 模式配置 USCI_B0
UCB0CTLW0 |= UCSWRST; //软件复位使能
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC;// I2C 模式、主控模式、SYNC
UCB0CTLW1 |= UCASTP_2; //生成自动停止
//到达 UCB0TBCNT 后
UCB0BRW = 0x0008; //波特率= SMCLK / 8
UCB0TBCNT = NNBytes; //要接收的字节数
UCB0I2CSA = 0x0068; //从地址
UCB0CTL1 &=~UCSWRST;
UCB0IE |= UCRXIE | UCBCNTIE;
__bis_SR_register (LPM0_bits|GIE);//输入 LPM0,带中断
}
#if defined (__TI_COMPIAR VERSION_VERSION__);__bis_void
PORT_2 (#_IAR COMPONENTS_EXTER_NOT_VERSIONENT_
)(#_INTER_NOTI_NOTI_NOTIF_INSION_NOT_INTRIBU_INSION_IN_INTRIBU_NOT_IN_INTRIBU_NOT_INTRIBU_INGS_)(#COMPIAR)(#COMPLETE_INTRIBU_INTR
#endif
{
//_delay_cycles (2000);
if (P2IFG 和 BIT3){
P1OUT |= BIT0; //在 P1.0上切换 LED
while (UCB0CTL1 & UCTXSTP); //确保发送了停止条件
//if (UCB0BCNT!=无核武器国家)
UCB0CTL1 |= UCTXSTT; // I2C 启动条件
UART_PUs ("start");
UART_putc (0x0A);//新行
P2IFG &=~BIT3;
}
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = USCI_B0_Vector
__interrupt void USCIB0_ISR (void)
#Elif defined (__GSCSIR__)
#_attribute_(UIB0_) NOT_ERROR
(UIB0 COMPONIE)(void)(UIB0_COMPONIE) NOT_ERROR (UIB0_COMPONENT!
#endif
{
switch (__even_in_range (UCB0IV、USCI_I2C_UCBIT9IFG))
}
USCI_NONE 案例:中断; //向量0:无中断
USCI_I2C_UCALIFG 案例:中断; //向量2:ALIFG
USCI_I2C_UCNACKIFG 案例: //向量4:NACKIFG
UCB0CTL1 |= UCTXSTT; // I2C 启动条件
中断;
案例 USCI_I2C_UCSTTIFG:中断; //向量6:STTIFG
案例 USCI_I2C_UCSTPIFG:中断; //向量8:STPIFG
USCI_I2C_UCRXIFG3案例:中断; //向量10:RXIFG3
USCI_I2C_UCTXIFG3案例:中断; //向量14:TXIFG3
USCI_I2C_UCRXIFG2案例:中断; //向量16:RXIFG2
USCI_I2C_UCTXIFG2案例:中断; //向量18:TXIFG2
USCI_I2C_UCRXIFG1案例:中断; //向量20:RXIFG1
USCI_I2C_UCTXIFG1案例:中断; //向量22:TXIFG1
USCI_I2C_UCRXIFG0案例: //向量24:RXIFG0
RXData = UCB0RXBUF; //获取 RX 数据
//_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0
中断;
案例 USCI_I2C_UCTXIFG0:中断; //向量26:TXIFG0
USCI_I2C_UCBCNTIFG 案例: //向量28:BCNTIFG
P1OUT ^= BIT0; //在 P1.0上切换 LED
中断;
USCI_I2C_UCCLTOIFG 案例:中断; //向量30:时钟低电平超时
USCI_I2C_UCBIT9IFG 案例:中断; //向量32:第9位
默认值:break;
}
}
void Init_GPIO()
{
P1DIR = 0xFF;P2DIR = 0xFF;
P1REN = 0xFF;P2REN = 0xFF;
P1OUT = 0x00; P2OUT = 0x00;
}






