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.

[参考译文] CCS/MSP430FR6047:UCB1 (P5.5和 P5.6)上的 I2C 不工作

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/897976/ccs-msp430fr6047-i2c-on-ucb1-p5-5-and-p5-6-not-working

器件型号:MSP430FR6047
主题中讨论的其他器件:MSP-TS430PZ100EMSP-FET

工具/软件:Code Composer Studio

您好!

我使用以下代码通过 I2C 与 TDC1000-TDC7200 EVM (MS430F5528)成功地使用了纽黑文的 LCD。

我最近购买 了 MSP-TS430PZ100E、并尝试使用 P5.5和 P5.6实现相同的效果。 但它不起作用。 通过示波器测试时、LCD 不显示任何内容、引脚也不显示任何生命体征。 我缺少什么或做了什么错? 这是代码。 (我也使用 TI 的示例代码尝试了相同的方法、但似乎没有任何结果。)

/*
* lcd.c
*
*创建日期:2015年。 12. 9.
*作者:用户
*
#include
#include
#include "lcd.h"


uint8_t firstLiny[20];
uint8_t 第二行[20];

#define LCD_I2C_PxOUT P5OUT //Port5
#define LCD_I2C_Px_IN P5IN //Port5
#define LCD_I2C_PxDIR P5DIR //Port4
#define LCD_I2C_SDA_PIN BIT5 //P5.5
#define LCD_I2C_SCL_PIN BIT6 //P5.6

/********
* ST7036i 的初始化*
(三 /

unsigned int Slave= 0x78;
unsigned int Comsend = 0x00;
unsigned int Datasend=0x40;

/*粗延迟函数。 通过更改计数器值进行调优。 *
void delay( unsigned int n ){
volatile int i;

for (; n; n-){
for (i = 0;i < 50;i++);


void data_read (void){
LCD_I2C_PxDIR &=~LCD_I2C_SDA_PIN;//悬空以准备读取

void data_high (void){

LCD_I2C_PxDIR &=~LCD_I2C_SDA_PIN;//浮点引脚变为高电平
延迟(5);

void data_low (void){

LCD_I2C_PxOUT &=~LCD_I2C_SDA_PIN;//将低电平置为有效
LCD_I2C_PxDIR |= LCD_I2C_SDA_PIN;
延迟(5);

void clk_high (void){

LCD_I2C_PxDIR &=~LCD_I2C_SCL_PIN;//浮点引脚变为高电平
delay(10);

void clk_low (void){

LCD_I2C_PxOUT &=~LCD_I2C_SCL_PIN;//将低电平置为有效
LCD_I2C_PxDIR |= LCD_I2C_SCL_PIN;
延迟(5);

/********* /
/********
* I2C 开始*
(三 /
void I2C_Start (void)

_BIC_SR_register (GIE);

P5SEL0 &=~(BIT5 | BIT6);
P5SEL1 |= BIT5 | BIT6;
CLK_HIGH ();
DATA_HIGH ();
data_low ();
clk_low ();
_bis_SR_register (GIE);

/********* /
/********
* I2C 停止*
(三 /
void I2C_Stop (void)

_BIC_SR_register (GIE);

data_low ();
clk_low ();
CLK_HIGH ();
DATA_HIGH ();
_bis_SR_register (GIE);

/********* /
/********
*通过 I2C 输出命令或数据*
(三 /
void I2C_out (unsigned char d)//I2C 输出

_BIC_SR_register (GIE);

int n;

for (n = 0;n < 8;n++)

if (d & 0x80)

DATA_HIGH ();

其他

data_low ();

CLK_HIGH ();
clk_low ();

D <<= 1;//将下一个位移入位。

DATA_READ();//将数据线设置为接收。
CLK_HIGH ();//时钟变为高电平等待应答。

//从机将拉低数据线以进行应答。
//while (P1IN & I2C_SDA)
while (LCD_I2C_Px_IN 和 LCD_I2C_SDA_PIN)

//否则切换时钟线并再次检查
clk_low ();
DATA_HIGH ();

clk_low ();
_bis_SR_register (GIE);

void init_lcd()

I2C_Start();

I2C_OUT (0x78);// LCD 面板的从器件地址。
I2C_OUT (0x00);//控制字节:所有以下字节都是命令。
I2C_OUT (0x38);// 8位总线,2行显示,正常指令模式。
delay(10);

I2C_OUT (0x39);// 8位总线,2行显示,扩展指令模式。
delay(10);

I2C_OUT (0x14);//偏置设置为1/5。
I2C_OUT (0x78);//对比度设置。
I2C_OUT (0x5E);//图标显示在上,BOOSTER 打开,对比度设置。
I2C_OUT (0x6D);//跟随器电路打开,放大器=1?
I2C_OUT (0x0F);//显示打开,光标关闭。
I2C_OUT (0x01);//清除显示。
I2C_OUT (0x06);//进入模式设置为光标向右移动。
delay(10);

I2C_Stop ();

/*向 LCD 发送“清除显示”命令。 *
void clear_display (void)

I2C_Start();

I2C_OUT (0x78);//面板的从器件地址。
I2C_OUT (0x00);//控制字节:所有以下字节都是命令。
I2C_OUT (0x01);//清除显示。

I2C_Stop ();

/********* /
/********
*将 ASCII 数据字符串发送到 LCD *
(三 /
이건 내가 만든 것 μ s
空 *** (无符号字符*文本)

_BIC_SR_register (GIE);

I2C_Start();
I2C_OUT (0x78);
I2C_OUT (0x40);
I2C_OUT (*文本);
I2C_Stop ();
_BIC_SR_register (GIE);


空显示(无符号字符*文本)

//_BIC_SR_register (GIE);

int n;

I2C_Start();

I2C_OUT (0x78);//面板的从器件地址。
I2C_OUT (0x40);//控制字节:后跟数据字节,数据为 RAM 数据。

for (n = 0;n < 20;n++){
I2C_OUT (*文本);
text++;

I2C_Stop ();
//_BIC_SR_register (GIE);

void MoveCursor (uint8_t NPO)

//_BIC_SR_register (GIE);

I2C_Start();

I2C_OUT (0x78);//面板的从器件地址。
I2C_OUT (0x00);//控制字节:所有以下字节都是命令。
I2C_OUT (0x80 + NPO);
I2C_Stop ();
//_bis_SR_register (GIE);

void ShowBothLines (空 ShowBothLines)

//_BIC_SR_register (GIE);

MoveCursor (0x00);
show (firstLine);
MoveCursor (0x40);
show (secondline);
//_bis_SR_register (GIE);

//__delay_cycles (2500);

/********* /
/********* /
/********* /

请帮帮我。  

Sukho

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

    我怀疑您在某处需要"PM5CTL0 &=~LOCKLPM5;"。 F5系列不需要(通常情况下)这种方法、而是 FR6系列。

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

    尊敬的麦肯尼先生:

    我当然是这样。 主代码如下所示(此外、时钟设置为8MHz。 I2C 是否正常工作)。

    int main (空)

    WDTCTL = WDTPW | WDTHOLD;//停止 WDT

    //配置 GPIO
    P1OUT &=~(BIT0|BIT1 |BIT2 |BIT3|BIT4 |BIT5|BIT6|BIT7);//清除 P1.0输出锁存器以实现定义的加电状态
    P1DIR |=(BIT0|BIT1 |BIT2 |BIT3 |BIT4 |BIT5|BIT6|BIT7);//将 P1.0设置为输出方向

    Set_Clock();

    init_lcd();
    show ("MaxiFlo 热量计");

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

    while (1)

    P1OUT ^=(BIT0|BIT1 |BIT2 |BIT3|BIT4 |BIT5|BIT6|BIT7);//切换 LED

    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    _DELAY_CYCLES (100000);
    //Show ("MaxiFlo 热量计");

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

    那么、既然您已经添加了该程序、那么您的程序会执行什么操作呢?

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

    我的意思是、当我问这个问题时、我已经在代码中使用了该部分。

    我还尝试了示例代码"msp430fr60x7_eusci_i2c_standard_master.c"。 但它似乎没有通过 P5.5和 P5.6输出任何内容。

    我做了什么错???

    请帮帮我。 我正在用大脑拉一个半周以上。

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

    >P5SEL0 &=~(BIT5 | BIT6);
    >P5SEL1 |= BIT5|BIT6;

    很抱歉、我以前没收到这些内容。 这些引脚置于硬件 I2C 的控制之下。 要执行软件 I2C (通过 GPIO)、您不应执行此操作。 (即删除这些行。)

    ----------

    msp430fr60x7_eusci_i2c_standard_master.c 似乎使用引脚 P1.6-7、而不是 P5.5-6。

    http://dev.ti.com/tirex/explore/node?node=AG5STm.qMws-eKOuCPgqbA__IOGqZri__LATEST

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

    麦肯尼先生;

    哦、我明白了。 谢谢。 该方法没有利用 I2C 功能。 它使用他们所谓的"位拆裂"、对吧?

    无论如何、我现在从 P5.5和 P5.6获得输出、但不知怎么说、MCU 和 LCD 不会相互通信。 我认为 MCU 没有以正确的格式发送消息。 我捕获了示波器屏幕。 SCL 和 SDA 的波形看起来不正确。 他们看起来有点歪了,我的眼睛很初级。 您建议我立即尝试解决这个问题吗? 请再帮帮我。

    关于 TI 的示例代码、是的。 它们使用 P1.6-7。 但我无法使用它、因为目标板将它们用于 JTAG (MSP-FET)。 因此、我选择了 UCB1 P5.5-6。 我相信我修订了示例代码其余部分中的相关元素、以与该更改保持一致。

    您应该知道、您的帮助使我能够继续... 我对此表示感谢、并再次等待您的帮助。

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

    缓慢(上升)边沿的常见原因是上拉电阻器太弱。 通过降低 I2C 时钟的速度,软件可以在一定程度上适应--在原始代码中,这就是 delay()函数。 [未经请求:我不建议使用 for ()循环执行延迟。 我建议改用__delay_cycles ()。]

    除非您对这种位拆裂实现非常有信心、否则我建议使用硬件 I2C。 我记得的更改是(1)端口引脚(如您所述)、(2) UCB0->UCB1、(3) USCI_B0_Vector->USCI_B1_Vector。

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

    谢谢你。 很抱歉耽误你的操作。

    在您的指导下获得一些良好的波形后、 意识到引脚顺序是另一种方法。 我多么愚蠢。 我设法在 LCD 上显示字母。 太棒了! 但并非如此。

    还有一件奇怪的事情。 就是这样。 连接 MSP-FET 的 USB 电缆时。 LCD 不会唤醒。 "while"循环中的 LED 不闪烁。  

    仅当我短暂地短接 SDA 和 SCL 时、while 环路才开始工作。 只有在我再次初始化 LCD 之后、我才开始看到 LCD 工作。 从这一刻起、直到拔下 MSB-FET 电缆、无论我在闪存上调试和加载程序多少次、LCD 都能保持工作。 但是、拔下电缆后、必须将 SDA 和 SCL 短接(P5.5和 P5.6以及 P5.3和 P5.4的工作方式相同)。

    为什么必须短接 SDA 和 SCL? 我出了什么问题? 有什么方法、我可以不短接 SDA 和 SCL 引脚?

    我尝试了硬件方法、但看不到引脚的任何输出。 当我越过障碍时、我会尝试更多。

    请再帮我…

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

    我注意到的一件事是、您清除 LOCKLPM5的时间很晚。 清零 LOCKLPM5会清除 GPIO 的(锁定)启动状态、因此在您这么做之前、它们不会完全起作用。

    INIT_LCD 尤其取决于是否具有功能齐全的 GPIO。

    在很早的时间内、甚至在一开始、清零 LOCKLPM5通常没有特别的伤害。 我建议您尝试在您的 P1配置之后进行设置。

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

    麦肯尼先生;

    哦、那... 明天我一定会这样做。 但是、让我告诉您、在初始化 LCD 之前、我设法通过长时间延迟使其正常工作。 但这可能不是正确的方法。 我会听从你的建议!!!

    谢谢你。 人很好!