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.

[参考译文] MSP430G2452:USI 外设未正确初始化-无 I2C 通信

Guru**** 2514285 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/607704/msp430g2452-usi-peripheral-not-initialized-correctly---no-i2c-communication

器件型号:MSP430G2452

大家好、

我正在尝试与 Intersil 的 RTC IC 建立 I2C 通信。 在尝试对其进行故障排除之前、我想验证 I2C 通信是否正常。 我初始化器件并为 I2C 配置 USI 外设、但似乎外设未正确初始化。 至少、当我设置 USICNTx 时、不会发生任何情况。 我假设我设置了很多控制寄存器中的一个错误、但尽管已经查看了几个小时、但似乎没有任何变化。 这让我相信、我缺少一些重要的东西、比如时钟源或全局中断设置。

我出了什么问题?

我使用的是 Code Composer Studio 6.2.0。 代码编译正确、LED 按预期闪烁。 但是 SDA/SCL 上没有任何变化。

代码:

#include 
//#include "USI_I2CMaster.h"
//*
main.c
*//
时钟:DCOCLK 1MHz。 校准值被加载到 io_init()


void i2c_init (void){
__disable_interrupt ();//启用所有中断
//将 USI 外设设置为 I2C 模式
USICTL0 |= USISWRST;//在 CONFIG 期间将 USI 保持在 SW 复位状态
//USICTL0 &=~USILSB;//USILSB 被清零 [USICTL0.4]不在 TI 示例中
USICTL0 |= USIPE6; //USIPE6置1 [USICTL0.6]
USICTL0 |= USIPE7; //USIPE7置1 [USICTL0.7]
USICTL0 |= USIMST; //USIMST 置位 [USICTL0.3]
USICTL1 |= USII2C; //USII2C 置位 [USICTL1.6]
USICTL1 |= USIIE;//USIIE 设置[USICTL1.4?] 如果我设置此位、器件会崩溃/挂起。
//USICTL1 &=~USICKPH;//USICKPH 已清除[USICTL1.7]、TI 示例中未清除
USICKCTL |= USIDIV_7;//时钟分频器 X128 [USICKCTL567]
USICKCTL |= USISSEL_2;//clock = SMCLOCK [USICKCTL234]
USICKCTL |= USICKPL;//USICKPL 置1 [USICKCTL.1]
//USICNT &=~USI16B;//USI16B 被清零 [USICNT.6]不在 TI 示例中
USICNT |= USIIFGCC;//禁用自动清除控制
USISRL = 0x00;//清除 SR 低电平
USISRH = 0x00;//清除 SR 高电平
USICTL0 |=~USISWRST;//Config Done、释放 RESET
USICTL1 &=~USIIFG;//清除中断标志

__ENABLE_INTERRUPT ();//启用所有中断
}

void device_init (void){
WDTCTL = WDTPW + WDTHOLD; //如果
(CALBC1_1MHz=0xFF)则停止看门狗//如果校准常数被擦除
{
while (1); //不加载,陷阱 CPU!!
}
DCOCTL = 0; //选择最低 DCOx 和 MODx 设置
BCSCTL1 = CALBC1_1MHZ; //将出厂校准值加载到时钟配置寄存器
DCOCTL = CALDCO_1MHz;

//现在时钟的运行频率为1MHz +/- 0.5%典型值。 在3V 和0-85摄氏度

时、//设置 LED 和按钮的 I/O
P1OUT = 0xC1;
P1REN= 0xC0;
P1DIR |= BIT0;
P1IE |= BIT3;// P1.3中断被启用
P1IFG &=~BIT3;// P1.3 IFG 被清零
P1SEL |= 0xC0;
P1SEL2 &= 0x3F;

P2OUT = 0;
P2DIR = 0xFF;
}

void i2c_start (void){
//生成启动条件
USISRL = 0x00; //将 MSB 设置为零以将 SDA 拉低
USICTL0 |= USIGE;//make 输出锁存透明
USICTL0 |= USIOE;//make 输出锁存透明
USICTL0 &=~USIGE;//恢复时钟锁存功能并在 SDA 线上保持0
}

void i2c_stop (void){
//生成停止条件

USICTL0 |= USIOE; //使输出锁存透明
USISRL = 0x00;//清除移位寄存器
USICNT = 1; //发送一位

USISRL = 0xFF; //将移位寄存器设置为全1
USICTL0 |= USIGE; //使输出锁存透明
USICTL0 &=~(USIGE+USIOE);//恢复时钟锁存功能并在 SDA 线上保持1
}

void led_on (void){
P1OUT |= BIT0;
}

void led_off (void){
P1OUT &=~BIT0;
}

int SEND_BYTE (int data){
USISRL =数据; //加载字节以发送到 USISRL
USICTL0 |= USIOE; //通过设置 USIOE 启用输出
USICNT =(USICNT & 0xE0)+ 8; //将位数写入 USICNTx 时开始传输。 在全部8个位被发送后、USIIFG 被自动置位并且时钟被停止。
USICTL0 &=~USIOE; //USIOE 位必须用软件清零并且 USICNTx 被载入1。 这会自动清除 USIIFG 并且一个位被接收到 USISRL 中。
USICNT =(USICNT & 0xE0)+ 1;

return (USISRL & 0x01);
}

void main (void){
device_init();
i2c_init();

while (1){
LED_ON();

// MFRC522的从地址= 0x50
I2C_start();

if (!send_Byte (0x50)){
I2C_STOP();
}
LED_OFF ();
__DELAY_CYCLES (1000000);//等待1s
}
} 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Andrew:

    第27行应该使用&=而不是|=、否则 USI 被保持在一个复位状态。 确保 I2C 总线线路处于高电平无效、因为它们应该在内部上拉电阻器被启用的情况下处于高电平、并且还要查看代码示例 msp430g2xx2_USI_07.c 以更好地了解从 USI 外设发送一个字节所需的全部内容。

    此致、
    Ryan