用MSP430G2553芯片和LCD1602显示温度数据,运行程序后,LCD显示满屏方块,是怎么回事,要怎么改呢?
下面是连接图片与运行后LCD的显示结果。


LCD用I2C引脚和芯片直接相连,LCD的VCC接芯片的VCC;LCD的GND接芯片的GND;LCD的SDA接芯片的P1.7引脚;LCD的SCL接了芯片的P1.6引脚。
如果是硬件连接出了问题,我没有电位器,手上现在只有10KΩ,220Ω,1KΩ的电阻,因为时间原因也不能买到其他元件了。
下面是程序的代码(是豆包生成的,修改过)
#include <msp430.h>
#include <stdint.h>
#include <stdio.h>
// I2C相关定义(使用P1.6和P1.7引脚)
#define I2C_ADDRESS 0x3F // I2C LCD地址,常见为0x27或0x3F
#define SDA BIT7 // P1.7 数据线
#define SCL BIT6 // P1.6 时钟线
#define I2C_PORT P1OUT
#define I2C_DIR P1DIR
// LCD控制位定义
#define LCD_RS 0x01 // 寄存器选择位
#define LCD_EN 0x04 // 使能位
#define LCD_BACKLIGHT 0x08 // 背光控制位
// 温度校准值定义(使用头文件中的校准数据)
#define CALADC10_15V_30C (*((unsigned int *)0x1A1A))
#define CALADC10_15V_85C (*((unsigned int *)0x1A1C))
// 延时函数
void delay_ms(uint16_t ms) {
while (ms--) __delay_cycles(1000); // 假设系统时钟为1MHz
}
// I2C起始信号
void i2c_start(void) {
I2C_DIR |= SDA; // SDA设为输出
I2C_PORT |= SDA | SCL; // SDA和SCL置高
delay_ms(1);
I2C_PORT &= ~SDA; // SDA下降沿,起始信号
delay_ms(1);
I2C_PORT &= ~SCL; // SCL下降沿,准备发送数据
}
// I2C停止信号
void i2c_stop(void) {
I2C_DIR |= SDA; // SDA设为输出
I2C_PORT &= ~SDA; // SDA置低
I2C_PORT &= ~SCL; // SCL置低
delay_ms(1);
I2C_PORT |= SCL; // SCL置高
delay_ms(1);
I2C_PORT |= SDA; // SDA置高,停止信号
}
// I2C发送一个字节,返回0表示成功,1表示失败
unsigned char i2c_send_byte(uint8_t byte) {
unsigned char i, ack;
I2C_DIR |= SDA; // SDA设为输出
for (i = 0; i < 8; i++) {
if (byte & 0x80)
I2C_PORT |= SDA;
else
I2C_PORT &= ~SDA;
I2C_PORT |= SCL; // SCL置高,发送位
delay_ms(1);
I2C_PORT &= ~SCL; // SCL置低
byte <<= 1;
}
// 接收ACK信号
I2C_DIR &= ~SDA; // SDA设为输入
I2C_PORT |= SCL; // SCL置高
delay_ms(1);
ack = (P1IN & SDA) ? 1 : 0; // 读取ACK状态
I2C_PORT &= ~SCL; // SCL置低
return ack; // 返回ACK状态
}
// 向LCD发送命令
void lcd_command(uint8_t cmd) {
uint8_t high_nibble = cmd & 0xF0;
uint8_t low_nibble = (cmd << 4) & 0xF0;
i2c_start();
if (i2c_send_byte(I2C_ADDRESS << 1)) {
i2c_stop();
return; // 发送设备地址失败
}
// 发送高4位
i2c_send_byte(high_nibble | LCD_BACKLIGHT); // 发送高4位数据,RS=0(命令)
i2c_send_byte(high_nibble | LCD_EN | LCD_BACKLIGHT); // 使能信号高电平
delay_ms(1);
i2c_send_byte(high_nibble | LCD_BACKLIGHT); // 使能信号低电平
// 发送低4位
i2c_send_byte(low_nibble | LCD_BACKLIGHT); // 发送低4位数据,RS=0(命令)
i2c_send_byte(low_nibble | LCD_EN | LCD_BACKLIGHT); // 使能信号高电平
delay_ms(1);
i2c_send_byte(low_nibble | LCD_BACKLIGHT); // 使能信号低电平
i2c_stop();
delay_ms(5); // 命令执行需要时间
}
// 向LCD发送数据
void lcd_data(uint8_t data) {
uint8_t high_nibble = data & 0xF0;
uint8_t low_nibble = (data << 4) & 0xF0;
i2c_start();
if (i2c_send_byte(I2C_ADDRESS << 1)) {
i2c_stop();
return; // 发送设备地址失败
}
// 发送高4位
i2c_send_byte(high_nibble | LCD_RS | LCD_BACKLIGHT); // 发送高4位数据,RS=1(数据)
i2c_send_byte(high_nibble | LCD_RS | LCD_EN | LCD_BACKLIGHT); // 使能信号高电平
delay_ms(1);
i2c_send_byte(high_nibble | LCD_RS | LCD_BACKLIGHT); // 使能信号低电平
// 发送低4位
i2c_send_byte(low_nibble | LCD_RS | LCD_BACKLIGHT); // 发送低4位数据,RS=1(数据)
i2c_send_byte(low_nibble | LCD_RS | LCD_EN | LCD_BACKLIGHT); // 使能信号高电平
delay_ms(1);
i2c_send_byte(low_nibble | LCD_RS | LCD_BACKLIGHT); // 使能信号低电平
i2c_stop();
delay_ms(1); // 数据写入需要时间
}
// 初始化LCD
void lcd_init(void) {
// 配置I2C引脚为输出
I2C_DIR |= SCL | SDA;
I2C_PORT |= SCL | SDA;
delay_ms(50); // 上电延时,等待LCD稳定
// 4位模式初始化序列
lcd_command(0x03); // 复位LCD
delay_ms(5);
lcd_command(0x03); // 再次复位
delay_ms(1);
lcd_command(0x03); // 第三次复位
delay_ms(1);
lcd_command(0x02); // 切换到4位模式
// 配置LCD基本参数
lcd_command(0x28); // 4位数据,2行显示,5x7点阵
lcd_command(0x0C); // 显示开,光标关
lcd_command(0x06); // 文字不动,地址自动加1
lcd_command(0x01); // 清屏
delay_ms(2);
}
// 设置LCD光标位置
void lcd_set_cursor(uint8_t row, uint8_t col) {
uint8_t address = (row == 0) ? 0x80 + col : 0xC0 + col;
lcd_command(address);
}
// 在LCD上显示字符串
void lcd_print(char *str) {
while (*str) lcd_data(*str++);
}
// 初始化ADC10模块
void adc_init(void) {
ADC10CTL0 = ADC10SHT_3 + ADC10ON + REFON + REF2_5V;
ADC10CTL1 = ADC10SSEL_1; // 选择ACLK作为时钟源
ADC10AE0 |= BITA; // 使能温度传感器通道(P1.0)
ADC10CTL0 |= ADC10IE; // 使能ADC转换
}
// 读取温度并转换为摄氏度
float read_temperature(void) {
// 启动ADC转换
ADC10CTL0 |= ADC10SC;
while (ADC10CTL1 & ADC10BUSY); // 等待转换完成
// 使用头文件中的校准值计算温度
int adc_value = ADC10MEM;
float temperature = 30.0f + ((float)(adc_value - CALADC10_15V_30C) *
(85.0f - 30.0f)) / (CALADC10_15V_85C - CALADC10_15V_30C);
return temperature;
}
// 显示温度值(处理整数和小数部分)
void display_temperature(float temp) {
char buffer[16];
int whole = (int)temp; // 整数部分
int fraction = (int)((temp * 100) - (whole * 100)); // 小数部分(保留2位)
lcd_set_cursor(0, 0);
lcd_print("Temperature:");
lcd_set_cursor(1, 0);
sprintf(buffer, "%d.%d C", whole, fraction);
lcd_print(buffer);
}
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // 停用看门狗定时器
// 初始化系统时钟为1MHz(使用头文件中的校准值)
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
// 初始化ADC和LCD
adc_init();
lcd_init();
while (1) {
float temperature = read_temperature();
display_temperature(temperature);
delay_ms(1000); // 每秒更新一次温度
}
}
有什么修改方式吗?不用电位器,只有电阻的