主题中讨论的其他器件:PCF8574、 PCF8574A
工具/软件: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;
}
}