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.

[参考译文] MSP430FR6928:PCF8563与 MSP430FR6928连接

Guru**** 2378650 points
Other Parts Discussed in Thread: MSP430FR6928
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1393377/msp430fr6928-pcf8563-interfacing-with-msp430fr6928

器件型号:MSP430FR6928

工具与软件:

我们使用 I2C 通信将 PCF8563与 msp430fr6928连接、但不会生成 I2C 中断。 此处附上代码片段以供参考、请更正我以继续。

void fnInitRTC()

// RTCCTL0_H = RTCKEY_H;//解锁 RTC_C 模块
P3SEL0 |=位1 |位2;
P3SEL1 &=~Ω(BIT1 | BIT2);
P3DIR |=BIT0;
P3OUT &=~Ω(BIT0);
PM5CTL0 &=~μ H LOCKLPM5;

UCB1CTLW0 = UCSWRST;//启用软件复位
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC;// I2C 主模式、SMCLK
UCB1BRW = 160;// fSCL = SMCLK/160 =~100kHz
UCB1I2CSA = 0xA2;//从器件地址
UCB1CTLW0 &=~μ s UCSWRST;//清除软件复位、恢复操作
UCB1IE |= UCNACKIE;
数据= 0x00;
I2C_4.54 Master_Write (RTC_WR_ADDR、CTRL1、&DATA、1);
//__delay_cycles (5500);
DATA=0x12;
I2C_4.54 Master_Write (RTC_WR_ADDR、CTRL2、和 DATA、1);
//_delay_cycles (5500);
数据= 0x01;
I2C_4.54 Master_Write (RTC_WR_ADDR,MINA,&DATA ,1);
//__delay_cycles (5500);
数据= 0x80;
I2C_4.54 Master_Write (RTC_WR_ADDR、HRSA、&DATA、1);
//__delay_cycles (5500);
数据= 0x80;
I2C_4.54 Master_Write (RTC_WR_ADDR、Daya、&DATA、1);
//_delay_cycles (5500);
数据= 0x80;
I2C_4.54 Master_Write (RTC_WR_ADDR、Weka、&DATA、1);
__delay_cycles (5500);
DATA=0x82;
I2C_4.54 Master_Write (RTC_WR_ADDR、CLK、&DATA、1);
__delay_cycles (5500);
数据= 0x00;
I2C_4.54 Master_Write (RTC_WR_ADDR、TIMER、&DATA、1);
__delay_cycles (5500);
数据= 0x01;
I2C_4.54 Master_Write (RTC_WR_ADDR、TIMERV、&DATA、1);
__delay_cycles (5500);

}

void I2C_54 Master_Write (unsigned char dev_addr、unsigned int reg_addr、unsigned char * reg_data、unsigned char count)
//I2C_Mode I2C_LaunchPad Master_Write (uint8_t dev_addr、uint8_t reg_addr、uint8_t * reg_data、uint8_t count)


UCB1I2CSA = dev_addr;
UCB1IFG 并且=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断
UCB1IE &&~μ P UCRXIE;//禁用 RX 中断
UCB1IE |= UCTXIE;//启用 TX 中断
UCB1CTLW0 |= UCTR + UCTXSTT;// I2C TX、启动条件
___ enable_interrupt ();
__bis_SR_register (LPM0_bits + GIE);
___ no_operation();

}

void I2C_ECG Master_Read (unsigned char dev_addr、unsigned char reg_addr、unsigned char 计数)

/*初始化从机地址和中断*/
UCB1I2CSA = dev_addr;
UCB1IFG 并且=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断
UCB1IE &&~μ P UCRXIE;//禁用 RX 中断
UCB1IE |= UCTXIE;//启用 TX 中断

UCB1CTLW0 |= UCTR + UCTXSTT;// I2C TX、启动条件
___ enable_interrupt ();
__bis_SR_register (LPM0_bits /*+ GIE*/);

}

#if defined (__TI_Compiler_version__)|| defined (__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B1_VECTOR
_interrupt void USCI_B1_ISR (void)
#elif defined (_GNUC__)
void __attribute__(((interrupt (USCI_B0_vector))) USCI_B1_ISR (void)
#else
错误编译器不受支持!
#endif
必须从 UCB2RXBUF 读取

//putch ('B');
unsigned char rx_val = 0;
开关(__EVEN_IN_RANGE (UCB1IV、USCI_I2C_UCBIT9IFG))

case USCI_NONE:break;//向量0:无中断
case USCI_I2C_UCALIFG:break;// Vector 2:ALIFG
case USCI_I2C_UCNACKIFG:// Vector 4:NACKIFG
// UCB1CTLW0 |= UCTXSTT;//如果无应答、则重新发送启动
休息;
case USCI_I2C_UCSTTIFG:break;// Vector 6:STTIFG
case USCI_I2C_UCSTPIFG:break;// Vector 8:STPIFG
case USCI_I2C_UCRXIFG3:break;// Vector 10:RXIFG3
case USCI_I2C_UCTXIFG3:break;// Vector 12:TXIFG3
case USCI_I2C_UCRXIFG2:break;// Vector 14:RXIFG2
case USCI_I2C_UCTXIFG2:break;// Vector 16:TXIFG2
case USCI_I2C_UCRXIFG1:break;// Vector 18:RXIFG1
case USCI_I2C_UCTXIFG1:break;// Vector 20:TXIFG1
案例 USCI_I2C_UCRXIFG0:
// Vector 22:RXIFG0
Rx_val = UCB1RXBUF;

IF (RXByteCtr)

ReceiveBuffer[ReceiveIndex++]= Rx_val;

RXByteCtr --;
}

if (RXByteCtr =1)

UCB1CTLW0 |= UCTXSTP;
}
否则为(RXByteCtr =0)

UCB1IE &=~UCRXIE;
MasterMode = IDLE_MODE;
_BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0
}
休息;

案例 USCI_I2C_UCTXIFG0:

if (TXByteCtr)//检查 TX 字节计数器

UCB1TXBUF = TransmitBuffer[TransmitIndex++];// TXData[SlaveFlag];//加载 TX 缓冲区
TXByteCtr --;//递减 TX 字节计数器
}
设计

UCB1CTLW0 |= UCTXSTP;// I2C 停止条件
UCB1IFG 并且=~UCTXIFG;//清除 USCI_B0 TX int 标志
_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0
}

休息;

默认值:中断;
}
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    UCB1I2CSA = 0xA2;//从地址

    I2C 从器件地址只有7位、因此不能正确(即使数据表重复地告诉您这一点)。 实际地址显示在数据表(版本11)中、图17:0x51。

    更笼统地说:该地址不包括 R/W 位。 如果数据表引用"读取地址"和"写入地址"、则可以通过将(其中之一)向右移动1位来找到实际地址。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    虽然我将从器件地址更改为0x51、但它仍然无法正常工作。

    此致

    Namita

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Namita、

    如果您从 SDK 中下载示例代码后运行、是否可以正确传输数据?  

    对于 I2C 传输、在硬件上、应记住在 SCL 和 SDA 上添加上拉电阻。 在软件方面、Bruce 提到的设备地址是一个要点。 我认为解决此问题的最佳方法 可能 是使用示波器来捕获 SCL 和 SDA 上的任何电压信息、并进入调试模式以分步执行调试。  

    此致、

    Janz Bai

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您如何判断它不起作用? ISR 中的断点? RTC 寄存器回读? 示波器跟踪?

    对于 TXIFG0、字节是从 TransmitBuffer[]写入的、但我看不到任何用于在其中放置任何内容的代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好  

    根据硬件要求,我们将外部 RTC 芯片更改为 PCF8583,因此我编写的代码如下所示,但不会产生 I2C 中断,请在代码中更正我。

    #define SlaveAddress  0x51

    void InitI2C (unsigned char EEPROM_i2c_address)


    // I2C 引脚

    UCB1CTLW0 = UCSWRST;//启用软件复位
    UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC;// I2C 主模式、SMCLK
    UCB1BRW = 10;//160;// fSCL = SMCLK/160 =~100kHz
    UCB1I2CSA = SLAVE_ADDR;//从地址
    UCB1CTLW0 &=~μ s UCSWRST;//清除软件复位、恢复操作
    UCB1IE |= UCNACKIE;

    }

    unsigned char I2C_addr Master_Write (unsigned char dev_addr、unsigned int reg_addr、unsigned char * reg_data、unsigned char count)
    //I2C_Mode I2C_LaunchPad Master_Write (uint8_t dev_addr、uint8_t reg_addr、uint8_t * reg_data、uint8_t count)


    while (UCB1STAT & UCBUSY);//等待总线不忙
    UCB1CTLW0 |= UCSWRST;//将 I2C 置于复位状态
    UCB1I2CSA = dev_addr;//设置 I2C 从地址
    UCB1CTL1 |= UCTXACK;//发送启动条件
    UCB1CTL1 |= UCTR;//设置为发送器模式
    UCB1CTL0 |= UCMODE_3 | UCSYNC;// I2C mode、SYNC
    UCB1CTL1 &=~μ s UCSWRST;//从复位中释放 I2C
    UCB1TXBUF = reg_addr& 0xFF;//发送寄存器地址
    UCB1IE &&~μ P UCRXIE;//禁用 RX 中断
    UCB1IE |= UCTXIE;//启用 TX 中断
    while (! (UCB1IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
    UCB1TXBUF =* reg_data;//发送数据
    while (! (UCB1IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
    UCB1CTL1 |= UCTXSTP;//发送停止条件
    while (UCB1CTL1 & UCTXSTP);//等待停止条件完成
    返回1;
    }

    void fnInitRTC()

    I2C_4.54 Master_Write (0x51、CTRL1、&DATA、1);
    __delay_cycles (80000);
    }

    int main (void)

    WDTCTL = WDTPW | WDTHOLD;//停止 WDT
    PJSEL0 |=位4 |位5;

    //禁用 GPIO 上电默认高阻抗模式以激活
    //先前配置的端口设置
    PM5CTL0 &=~μ H LOCKLPM5;

    // XT1 Setup (XT1设置)
    CSCTL0_H = CSKEY >> 8;//解锁 CS 寄存器
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;//设置所有分频器
    CSCTL4 &=~LFXTOFF;
    应执行的操作

    CSCTL5并且=~LFXTOFFG;//清除 XT1故障标志
    SFRIFG1 &=~OFIFG;
    —while (SFRIFG1&OFIFG);//测试振荡器故障标志
    CSCTL0_H = 0;
    PM5CTL0 &=~μ H LOCKLPM5;
    P3SEL0 |=位1 |位2;
    P3SEL1 &=~Ω(BIT1 | BIT2);

    PM5CTL0 &=~μ H LOCKLPM5;
    InitI2C (SlaveAddress);
    #if RTC_PCF8583
    fnInitRTC();
    gostDate.ucDate = 5;
    gostDate.ucMonth = 11;
    gostDate.ucYear = 12;
    gostTime.ucHour = 19;
    gostTime.ucMin = 16;
    gostTime.ucSec = 26;
    ucSetDate (&gostDate);
    #endif //RTC_PCF8583
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    当您运行此脚本时会出现什么情况?

    -------

    1) >  I2C_CTRL2 Master_Write (0x51、CTRL1、&DATA、1);

    A0引脚是如何连接的? 如果它连接到 GND (例如 MikroE 分线板)、则地址为0x50 [请参阅 PCF8583数据表(r 06)表5]。  

    2)> UCB1CTL1 |= UCTXACK;//发送启动条件

    这不会发送启动(我认为它不会在主设备上执行任何操作)。 您需要的是以下内容:

    > UCB1CTL1 |= UCTXSTT;//发送起始条件

    也就是说、(a)如果您在 UCSWRST = 1时设置此位、会发生什么情况(b)您需要首先设置 UCTR。

    3) 3)我不知道你在哪里启用中断(GIE)。 添加位置:

    >____ enable_interrupt ();  // GIE=1

    [编辑:我之前错过了这个:

    4)> UCB1IE |= UCTXIE;//启用 TX 中断

    这将启用 TXIFG、但我看不到 ISR (根据其他代码、你不需要一个 ISR)。 直接删除此行。

    ]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、我修改了但没有 生成 I2C 中断、是否有任何与 PF8583相关 的没有 I2C 中断的示例代码?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    由于您已经删除了所有 UCB1IE 设置、我不希望您看到任何 I2C 中断(ISR 调用)。 由于您要进行轮询、因此您不需要它们。

    我不知道 PCF8583和 MSP430的任何示例代码。 论坛搜索结果显示20次点击,但我没有调查它们。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我也尝试了轮询,但它 卡在 I2C_Write 函数,while 循环,请参考下面的代码

    //开始 I2C 通信
    void I2C_Start (void){
    // UCB1CTLW0 |= USIIFG;//设置启动条件
    UCB1CTLW0 |= UCTR + UCTXSTT;
    }

    //停止 I2C 通信
    void I2C_Stop (void){
    UCB0CTLW0 |= UCTXSTP;//设置停止条件
    }

    //将数据写入 I2C
    void I2C_Write (unsigned char data){
    UCB1TXBUF = data;// Load data
    UCB1CTLW0 |= UCTR + UCTXSTT;//开始传输
    while (! (UCB1IFG & UCTXIFG));//等待传输完成
    }

    //从 I2C 读取数据
    unsigned char I2C_read (void)

    unsigned char retVal;
    UCB1CTLW0 |= UCTR + UCTXSTT;//开始接收
    while (! (UCB0IFG & UCRXIFG0);//等待接收完成
    retval = UCB0RXBUF;
    return retVal;//返回接收的数据
    }
    void fnInitRTC()

    I2C_Start();
    I2C_Write (0xA0);// PCF8583地址(根据地址引脚进行调整)
    I2C_Write (RTC_ADDR_Year_DATE);//开始写入的寄存器(时间寄存器)
    I2C_Write (0);
    }
    unsigned char ucSetDate (tdstDate * stRTC_Date)

    I2C_Start();
    I2C_Write (0xA0);// PCF8583地址(根据地址引脚进行调整)
    I2C_Write (RTC_ADDR_Year_DATE);//开始写入的寄存器(时间寄存器)
    I2C_Write (stRTC_Date->ucDate);//设置小时数
    // I2C_Write (stRTC_Date->ucMin);//设置分钟
    // I2C_Write (stRTC_Date->ucSec);//设置秒数

    I2C_Stop();
    }
    unsigned char ucGetDate (tdstDate * stRTC_Date)

    I2C_Start();
    I2C_Write (0xA0);// PCF8583地址(根据地址引脚进行调整)
    I2C_Write (0x00);//要读取的寄存器(时间寄存器)

    I2C_Start();//重复启动
    I2C_Write (0xA1);// PCF8583地址、带读取位
    strtc_Date->ucDate = I2C_Read ();//读取小时数
    // stRTC_DAT->ucMin = I2C_READ ();//读取分钟
    //stRTC_Date->ucSec = I2C_Read ();//读取秒数

    I2C_Stop();}