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/MSP430F5529:在 LCD 1602上显示一些字符

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/907530/ccs-msp430f5529-displaying-some-characters-on-lcd-1602

器件型号:MSP430F5529
主题中讨论的其他器件:PCF8574PCF8574A

工具/软件:Code Composer Studio

大家好、我在使用 I2C 通信协议的 LCD 1602上显示一些字符时遇到了一些问题、例如拼写错误"Hello World"。 我认为这个问题与 I2C 的 ISR 有关、因为当我逐步执行代码时、它会阻止代码并显示此消息(我不知道它的真正含义):

我还粘贴了我的代码、以确保如果有人看到任何其他问题、可能会导致我将来出现另一个问题或优化想法。 所有这些都将得到它。 非常感谢!

#include
#include
#include

// LCD 的变量:

typedef unsigned char 字节;
#define Enable_LCD 0x04
#define iluminacion_LCD 0x08
#define comando_LCD 0x00
#define Dato_LCD 0x01
#define LCD_PCF8574_address 0x3F

uint8_t * PTxData;//指针 TX
uint8_t TXByteCtr;//发送的字节计数器

uint16_t volatile contador_milisegundos;//针对 delay_ms 对 ms 进行计数  

void Inicializacion_Relojes (void)

_bis_SR_register (SCG0);//禁用 FLL 控制循环
UCSCTL0 = 0x0000;  
UCSCTL1 = DCORSEL_5;//范围 DE 16MHz
UCSCTL2 = FLLD_0 | 487;  
//(N + 1)*(FLLRef/n)= Fdcomsp430
//(487 + 1)*(32768/1)= 16MHz
UCSCTL3 = 0;// FLL SELREF = XT1CLK y 除数 de FLL = 1 (FLLREFDIV = FLLREFCLK/1)
UCSCTL4 |= SELA 0 | SELS _4 | SELM_4;  
// UCSCTL5 |= DIV_0 | DIVS_0;  
_BIC_SR_register (SCG0);//启用 FLL 控制环路

空 USCIB1_init (字节从器件地址)

P4SEL |= BIT2 | BIT1;// P4.1 --> UCB1SDA
// P4.2 --> UCB.S.
UCB1CTL1 |= UCSWRST;
UCB1CTL0 |=(UCMST | UCMODE_3 | UCSYNC);// UCMST:主器件;UCMODE_3:模块化 USCI COMO I2C;UCSYNC:MODO Sroninco
UCB1CTL1 |=(UCSSEL_2 | UCSWRST);// UCSSEL_2:SMCLK;UCSWRST:USCI Σ-Δ 复位
UCB1BR0 = 160;// fSCL = SMCLK (16MHz)/160 = 100kHz
UCB1BR1 = 0;
UCB1I2CSA = SLAVE_ADDRESS;  
UCB1CTL1 &=~UCSWRST;
UCB1IE |= UCTXIE;  

void delay_ms (uint16_t tiempo_milisegundos)

contador_milisegundos = 0;
TA1CTL |= MC_1;// 向上计数模式
TA1CCTL0 |= CCIE;
while (contader_milisegundos < tiempo_milisegundos);
TA1CTL |= MC_0;//停止模式

void init_TimerA1_ms (void)//计时器、用于每 ms 进行一次计数
{  
TA1CCR0 = 16000-1;  
TA1CTL |= tassel_2 | MC_0;// Reloj SMCLK、Frecuencia:16MHz。 MODO 停止。

void I2C_send (字节 addr、字节*缓冲区、字节 numero_datos)

UCB1I2CSA = addr;
PTxData =缓冲器;
TXByteCtr = numero_datos;
UCB1CTL1 |=(UCTR | UCTXSTT);
_bis_SR_register (LPM0_bits + GIE);
__no_operation();
while (UCB1CTL1 & UCTXSTP);

void lcd_send_nibble_cmd (字节 Dato)

字节缓冲区[2];
字节 Dato_I2C_H;
Dato_I2C_H = Dato & 0xF0;
Buffer[0]= Dato_I2C_H | Luminacion_LCD | Enable_LCD | comando_LCD;
Buffer[1]= Dato_I2C_H | Luminacion_LCD | comando_LCD;
I2C_SEND (LCD_PCF8574_ADDRESS、缓冲器、2);

void lcd_send_Byte_data (字节 Dato)  

字节缓冲器[4];
字节 Dato_I2C_H、Dato_I2C_L;
Dato_I2C_H = Dato & 0xF0;
Dato_I2C_L =(Dato << 4)& 0xF0;  
Buffer[0]= Dato_I2C_H | Luminacion_LCD | Enable_LCD | Dato_LCD;
Buffer[1]= Dato_I2C_H | Luminacion_LCD | Dato_LCD;
Buffer[2]= Dato_I2C_L | Luminacion_LCD | Enable_LCD | Dato_LCD;
Buffer[3]= Dato_I2C_L | Luminacion_LCD | Dato_LCD;
I2C_SEND (LCD_PCF8574_ADDRESS、缓冲区、4);

void lcd_send_Byte_cmd (字节 Dato)

字节缓冲器[4];
字节 Dato_I2C_H、Dato_I2C_L;
Dato_I2C_H = Dato & 0xF0;  
Dato_I2C_L =(Dato << 4)& 0xF0;  
Buffer[0]= Dato_I2C_H | Luminacion_LCD | Enable_LCD | comando_LCD;
Buffer[1]= Dato_I2C_H | Luminacion_LCD | comando_LCD;
Buffer[2]= Dato_I2C_L | Luminacion_LCD | Enable_LCD | comando_LCD;
Buffer[3]= Dato_I2C_L | Luminacion_LCD | comando_LCD;
I2C_SEND (LCD_PCF8574_ADDRESS、缓冲区、4);

void init_lcd_PCF8574 (void)

delay_ms (20);
LCD_SEND_NibbLE_cmd (0x30);
DELAY_ms (5);
LCD_SEND_NibbLE_cmd (0x30);
delay_ms (1);
LCD_SEND_NibbLE_cmd (0x30);
DELAY_ms (5);
LCD_SEND_NibbLE_cmd (0x20);//具有4位的 LCD 数据总线
delay_ms (1);
LCD_SEND_BYTE_cmd (0x28);// N=1:2 Filas;F=0:5x8 puntos
delay_ms (1);
LCD_SEND_BYTE_cmd (0x08);//显示关闭、光标关闭、闪烁关闭
delay_ms (1);
LCD_SEND_BYTE_cmd (0x01);//清除屏幕、光标主页
delay_ms (2);
LCD_SEND_BYTE_cmd (0x07);//输入模式设置;I/D=1:递增;S=1:滚动显示
delay_ms (10);
LCD_SEND_BYTE_cmd (0x0C);//显示打开、光标关闭、光标闪烁
DELAY_ms (10);//  

void LCD_setCursor (字节 Fila、字节列)

字节地址;

if (Fila =0){//第一行
地址= 0;

否则地址= 0x40;//段行

地址|=列;//段号0x00 +列号(Fila1)
// Para tener 0x40 + Columna (Fila2)

LCD_SEND_BYTE_DATA (0x80 |地址);//设置 DDRAM 地址
delay_ms (2);

void LCD_print (字节*字符串、uint8_t Fila、uint8_t 列)

uint8_t tamaño;//可用于计算字符数的变量
LCD_setCursor (Fila、colna);

while (*字符串!='\0')  

lcd_send_Byte_data (*字符串++);  
tamaño ++;
if (tamaño >(16列))

LCD_SEND_BYTE_cmd (0x18);//显示向左移位


delay_ms (2);

void main (void)

WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
Inicializacion_Relojes();
USCIB1_INIT (LCD_PCF8574_ADDRESS);
init_TimerA1_ms ();
_enable_interrupt ();  
init_lcd_pcF8574 ();
LCD_PRINT ("Hello World!"、0、0);  

#pragma vector=Timer1_A0_vector
_interrupt void Timer1_A0_ISR (void){  
contador _milisegundos ++;//递增变量 ms
TA1CCTL0 &=~CCIFG;

#pragma vector = USCI_B1_Vector
_interrupt void USCI_B1_ISR (void)

switch (__evo_in_range (UCB1IV、12))

情况0:中断;//向量0:无中断
情况2:中断;//向量2:ALIFG
情况4:中断;//向量4:NACKIFG
情况6:中断;//向量6:STTIFG
情况8:中断;//向量8:STPIFG
情况10:中断;//向量10:RXIFG
情况12://向量12:TXIFG
if (TXByteCtr)//检查 TX 字节计数器

UCB1TXBUF =* PTxData++;//加载 TX 缓冲区
TXByteCtr -;//减量 TX 字节计数器

其他

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

默认值:break;

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

    我的第一个猜测是、你会得到一个否定

    > #define LCD_PCF8574_address 0x3F

    这不是 PCF8574的有效地址(0x20-0x27)。 它将是 PCF8574A (0x38-3F)的有效地址、但仅当 A0-A2引脚全部连接高电平时。 是这样吗?

    如果您有原理图、则发布该原理图将非常有用。

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

    你是对的、我把它与从器件地址弄乱了、我现在修复了它。 之前出现的与0x380地址相关的这种消息似乎已根据您的建议消失(是的、我在从地址上犯了错误。 很难说)、但无论如何我看不到我在 LCD 显示屏上布置'Hello Wolrd'的文本。 您可能还看到函数的其他问题吗? 谢谢 dude!