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.

[参考译文] CC430F5137:在尝试通过 I2C 通信将微控制器与 EEPROM 连接时面临问题

Guru**** 2391325 points
Other Parts Discussed in Thread: CC430F5137

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/726528/cc430f5137-facing-the-problem-while-i-am-trying-to-interface-the-microcontroller-with-eeprom-via-i2c-communication

器件型号:CC430F5137

您好!

我正在使用基于 cc430f5137的项目。 在这里、我面临以下问题、实际上我正在尝试通过 I2C 协议将 EEPROM 与微控制器连接。

这里、我使用软件协议进行 I2C 通信、我使用以下位:P1.3用于 SDA、P1.2用于 SCL、P1.1用于 WP。  

首先、我尝试将地址发送到 EEPROM 以识别从器件、这里成功写入 add 指令、EEPROM 向主器件提供 ACK。

3之后,我尝试向其发送添加字,这里的 EEPROM 没有向主器件发送 ACK。  

这是实际面临的问题  

EEPROM 部件号为:AT24LC024

我在这里附上了我的固件详细信息。 请帮帮我。

/********* main.c ********* /

#include "cc430f5137.h"
#include "EEPROM.h"
#include
//#include "TI_USCI_I2C_MASTER.h"


unsigned int i=0;

void main (void)

WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

UCSCTL3 |= SELREF_2;//设置 DCO FLL 基准= REFO
UCSCTL4 |= SELA_2;//设置 ACLK = REFO

//将 DCO 初始化为8MHz
_bis_SR_register (SCG0);//禁用 FLL 控制循环
UCSCTL0 = 0x0000;//设置可能的最低 DCOx、MODx
UCSCTL1 = DCORSEL_5;//针对 DCO = 16MHz 设置 RSELx
UCSCTL2 = FLLD_1 + 249;//将 DCO 乘法器设置为8MHz
//(N + 1)* FLLRef = Fdco
//(74 + 1)* 32768 = 8MHz
//设置 FLL Div = fDCOCLK/2
_BIC_SR_register (SCG0);//启用 FLL 控制环路
_DELAY_CYCLES (250000);

register_write1();
register_read();

/ /

/******** EEPROM.c ********* /

#include "cc430f5137.h"
#include "EEPROM.h"

#define EEPROM_PAGE_SIZE 128 //64 // AT24C256具有64字节的页大小
unsigned char UART_buffer[35]、rart_buffer[35]、rbuffer[40]、Internal_Flash_Values[40]={'1'、'2'、'3'、'4'、'5'、'6'、'7'、'8'、'9'、'0'};


//TI_CC_WAIT (35);DCO 以8MHz 运行时的延迟时间为5.6uS
//TI_CC_WAIT (70);DCO 以8MHz 运行时的延迟时间为11.2uS
void TI_CC_WAIT (无符号 int 周期)

while (cycles >15)//开销占用的15个周期
周期=周期- 6;//每次迭代消耗6个周期

空起始(空)

sdaout();
EEPROM_OUT |= SDA_EEPROM;
EEPROM_OUT |= SCL_EEPROM;
EEPROM_OUT &=~SDA_EEPROM;
TI_CC_WAIT (35);//delay 5.6uS
EEPROM_OUT &=~SCL_EEPROM;

void stop (void)(空)

sdaout();
EEPROM_OUT &=~SDA_EEPROM;
EEPROM_OUT &=~SCL_EEPROM;
EEPROM_OUT |= SCL_EEPROM;
TI_CC_WAIT (35);//delay 5.6uS
EEPROM_OUT |= SDA_EEPROM;

void sendb (无符号字符 c)

unsigned char i;
for (i=0;i<8;i++)

if (c&0x80)

EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT |=SDA_EEPROM;//SDA=1
TI_CC_WAIT (35);//delay 5.6uS

其他

EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT&&=~SDA_EEPROM;//SDA=0;
TI_CC_WAIT (35);//delay 5.6uS

C=c<<1;

EEPROM_DIR |=SCL_EEPROM;
EEPROM_OUT |=SCL_EEPROM;// SCL=1;
TI_CC_WAIT (35);//delay 5.6uS

EEPROM_DIR |=SCL_EEPROM;
EEPROM_OUT&&=~SCL_EEPROM;//SCL=0;
TI_CC_WAIT (35);//delay 5.6uS

unsigned char getack_ee (空)

unsigned char ack=0;

EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT |=SDA_EEPROM;//SDA=1
TI_CC_WAIT (10);//延迟1.6uS

EEPROM_DIR |= SCL_EEPROM;
EEPROM_OUT &=~SCL_EEPROM;//SCL=0;
TI_CC_WAIT (35);//delay 5.6uS

EEPROM_DIR &=~(SDA_EEPROM);//
EEPROM_DIR |= SCL_EEPROM;
EEPROM_OUT |= SCL_EEPROM;// SCL=1;
TI_CC_WAIT (35);//delay 5.6uS

ACK=(char)(EEPROM_IN 和 SDA_EEPROM);
EEPROM_DIR |= SCL_EEPROM;
EEPROM_OUT &=~SCL_EEPROM;//SCL=0;
TI_CC_WAIT (35);//delay 5.6uS

返回(ACK 和 SDA_EEPROM);

void Registers_write1 (void)

int i;
EEPROM_DIR |= 0x0E;//0x07;
EEPROM_OUT &=~EEPROM_WP;
TI_CC_WAIT (35);
对于(i=0;i<10;i++)

EEPROM_w_BYTE (I、Internal_Flash_Values[i]);
TI_CC_WAIT (35);

EEPROM_OUT |= EEPROM_WP;
TI_CC_WAIT (35);

void EEPROM_w_BYTE (无符号字符添加、无符号字符值)

start();//开始 i2c 通信
sendb (0xA0);//发送器件地址
if (getack_ee ())

stop();

sendb (add);//发送地址字的高位字节
if (getack_ee ())

stop();

sendb (value);//发送数组数据
if (getack_ee ())

stop();

stop();// i2c 通信的停止条件

void Registers_read (void)

int i;
EEPROM_DIR |= 0x0E;//0x07;
TI_CC_WAIT (35);
对于(i=0;i<10;i++)

EEPROM_r_BYTE (i、&ruart_buffer[i]);
TI_CC_WAIT (35);

TI_CC_WAIT (35);

void EEPROM_r_BYTE (unsigned char add、unsigned char * buffer)

start();//开始 i2c 通信
sendb (0xA0);//发送器件地址
if (getack_ee ())

stop();

sendb (add);//发送地址字的高位字节
if (getack_ee ())

stop();

start();//开始 i2c 通信
sendb (0xA1);//发送数组数据
if (getack_ee ())

stop();

*buffer = read();//从 EEPROM 读取一个字节
putack_i2c (0);
stop();// i2c 通信的停止条件

void putack_i2c (无符号字符 ACK)

if (ack=0)

EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT&&=~SDA_EEPROM;//SDA=0;
TI_CC_WAIT (10);

其他

EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT |=SDA_EEPROM;//SDA=1
TI_CC_WAIT (10);


EEPROM_DIR |=SCL_EEPROM;
EEPROM_OUT |=SCL_EEPROM;// SCL=1;
TI_CC_WAIT (10);

EEPROM_DIR |=SCL_EEPROM;
EEPROM_OUT&&=~SCL_EEPROM;//SCL=0;
TI_CC_WAIT (10);

/ /

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这不是设置 CPU 频率的正确方法;您必须检查故障标志。 (有关详细信息、请参阅示例代码文件。)

    为什么不使用硬件 I²C?

    很难看到此代码的作用。 请显示示波器或逻辑分析仪迹线。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我还愿意使用硬件 i2c、但我找不到它支持的库文件。 如果您有、可以给我发送吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的回复 Clemens Ladisch、请继续帮助我。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    示例代码包中的 cc430x513x_uscib0_i2c_xx.c 文件展示了如何使用 μ I²C 模块。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢你。
    我找到了它并处理它。 我将向您提供最新信息。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您的折返。 我正在使用硬件 i2c 协议、我正在使用以下源代码、在此代码中、我调用了从器件的以下函数是否存在(TI_USCI_I2C_SLAVE_Present (0xA0))。 现在、我得到了正结果、表示呈现了从器件(I = 1)。 之后、我调用以下函数将5个字节写入 EEPROM (TI_USCI_I2C_Transmit (5、TxData);)、在这里、我已将第一个字节从主器件发送到从器件、并等待从器件发送 ACK 以完成第一个字节、但从器件给出了 NACK。 这是我的实际问题


    源代码:

    #include "cc430x613x.h"
    #include"main.h"

    unsigned char * PTxData;//指向 TX 数据的指针
    unsigned char TXByteCtr;
    unsigned char * PRxData;//指向 RX 数据的指针
    unsigned char RXByteCtr;

    extern signed char byteCtr;
    extern unsigned char * TI_receive_field;
    extern unsigned char * TI_transmit 字段;
    volatile unsigned char RxBuffer[10];//分配128字节 RAM
    unsigned int i=0、j=0;
    无符号字符 TxData[]={'A'、'B'、'C'、'D'、'E'};

    int main (空)

    WDTCTL = WDTPW + WDTHOLD;//停止 WDT

    PMAPPWD = 0x02D52;//获取对端口映射寄存器的写入访问
    P1MAP3 = PM_UCB0SDA;//将 UCB0SDA 输出映射到 P1.3
    P1MAP2 = PM_UCB.S;//将 UCB.S 输出映射到 P1.2
    PMAPPWD = 0;//锁定端口映射寄存器

    P1SEL |= BIT2 + BIT3;//选择 P1.2和 P1.3以使用 I2C 功能


    TI_USCI_I2C_NO迎宾();
    TI_USCI_I2C_transmitinit (0xa0、0x12);
    TI_USCI_I2C_NO迎宾();
    I = TI_USCI_I2C_SLAVE_Present (0xA0);
    TI_USCI_I2C_NO迎宾();
    TI_USCI_I2C_transmitinit (0xa0、0x12);
    TI_USCI_I2C_Transmit (5、TxData);
    TI_USCI_I2C_NO迎宾();
    TI_USCI_I2C_receiveinit (0xa1、0x12);
    TI_USCI_I2C_Receive (5、PRxData);
    TI_USCI_I2C_NO迎宾();
    for (j=0;j<5;j++)
    RxBuffer[j]= PRxData[j];


    返回0;

    ///----------------------------------
    // void TI_USCI_I2C_transmitinit (unsigned char slave_address、
    // unsigned char 预分频)
    //
    //此函数初始化 USCI 模块以进行主器件发送操作。
    //
    //输入:unsigned char slave_address =>从地址
    // unsigned char 预分频=> SCL 时钟调整
    ///----------------------------------
    void TI_USCI_I2C_transmitinit (unsigned char slave_address、unsigned char prescale)

    P1SEL |= SDA_PIN + SCL_PIN;//将 I2C 引脚分配给 USCI_B0
    UCB0CTL1 = UCSWRST;//启用 SW 复位
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式
    UCB0CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持软件复位
    UCB0BR0 =预分频;//设置预分频器
    UCB0BR1 = 0;
    UCB0I2CSA = SLAVE_ADDRESS;//设置从器件地址
    UCB0CTL1 &=~UCSWRST;//清除 SW 复位,恢复运行
    UCB0IE = UCNACKIE | UCTXIE;//启用 TX 就绪中断




    ///----------------------------------
    // void TI_USCI_I2C_transmit (unsigned char byteCount、unsigned char *字段)
    //
    //此函数用于在主机传输模式下启动 I2C 通信。
    //
    //输入:unsigned char 字节 Count =>应传输的字节数
    // unsigned char *字段=>数组变量。 其内容将被发送。
    ///----------------------------------
    void TI_USCI_I2C_Transmit (unsigned char 字节计数、unsigned char *字段)

    TI_Transmit 字段=字段;
    byteCtr = byteCount;
    UCB0CTL1 |= UCTR + UCTXSTT;// I2C TX、启动条件


    #pragma vector = USCI_B0_vector
    _interrupt void USCI_B0_ISR (void)


    switch (__evo_in_range (UCB0IV、12))

    情况0:中断;//向量0:无中断
    情况2:中断;//向量2:ALIFG
    案例4:
    if (UCNACKIFG)//如果从器件发送 NACK 则发送 STOP

    UCB0CTL1 |= UCTXSTP;
    UCB0STAT &=~UCNACKIFG;

    中断;//向量4:NACKIFG
    情况6:中断;//向量6:STTIFG
    情况8:中断;//向量8:STPIFG
    情况10://向量10:RXIFG
    byteCtr --;//减量 RX 字节计数器
    if (字节中心)

    * TI_Receive_field++= UCB0RXBUF;//将 RX 数据移动到地址 PRxData
    if (byteCtr = 1)//只剩下一个字节?
    UCB0CTL1 |= UCTXSTP;//生成 I2C 停止条件

    其他

    * TI_Receive_field = UCB0RXBUF;//将最终 RX 数据移动到 PRxData
    _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出活动 CPU

    中断;
    情况12://向量12:TXIFG
    if (byteCtr)//检查 TX 字节计数器

    UCB0TXBUF =* TI_transmit 字段++;//加载 TX 缓冲区
    byteCtr --;//减量 TX 字节计数器
    _delay_cycles (60000);

    其他

    UCB0CTL1 |= UCTXSTP;// I2C 停止条件
    UCB0IFG &=~UCTXIFG;//清除 USCI_B0 TX 内部标志
    _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0

    中断;
    默认值:break;






    请帮助我是否使用正确的方式?

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

    将代码发布到论坛时、请单击"插入代码、附加文件等..."使用高级编辑器 回复框右下角的链接。 进入此视图后、要插入代码、请使用 框中。 这会将代码格式化为可读格式。

    有关调试 I2C 通信的帮助、请参阅以下应用手册:
    http://www.ti.com/lit/slaa734

    此外、请参阅以下代码示例。 它专为类似器件而设计、因此需要进行一些移植、但它是一个完整的 I2C 示例。
    请参阅以下链接中的:
    MSP430F55xx_USCI_i2c_standard_master.c
    MSP430F55xx_USCI_i2c_standard_slave.c
    dev.ti.com/.../