2301_77448649 2025-06-16 22:13 采纳率: 0%
浏览 4

MSP430G2553芯片温度用LCD屏显示报错

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

img

img

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);  // 每秒更新一次温度
    }
}

有什么修改方式吗?不用电位器,只有电阻的

  • 写回答

5条回答 默认 最新

  • 阿里嘎多学长 2025-06-16 22:14
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    MSP430G2553芯片温度用LCD屏显示报错

    你遇到了MSP430G2553芯片和LCD1602显示温度数据时,LCD显示满屏方块的问题。下面是可能的解决方案:

    1. 检查LCD连接是否正确:请检查LCD的I2C引脚是否正确连接到MSP430G2553芯片的I2C引脚。
    2. 检查LCD的初始化是否正确:请检查LCD的初始化代码是否正确,是否正确设置LCD的模式、地址和数据寄存器。
    3. 检查数据传输是否正确:请检查数据传输代码是否正确,是否正确将温度数据传输到LCD的数据寄存器。
    4. 检查LCD的显示模式是否正确:请检查LCD的显示模式是否正确,是否正确设置LCD的显示模式为文本模式或图形模式。

    以下是一个简单的示例代码,用于初始化LCD和显示温度数据:

    #include <msp430.h>
    #include <i2c.h>
    
    #define LCD_ADDRESS 0x27
    #define LCD_WIDTH 20
    #define LCD_HEIGHT 4
    
    void lcd_init(void) {
        // 初始化LCD
        I2C_Init(LCD_ADDRESS);
        I2C_Write(LCD_ADDRESS, 0x38, 0x38); // 设置LCD模式
        I2C_Write(LCD_ADDRESS, 0x06, 0x06); // 设置LCD地址
        I2C_Write(LCD_ADDRESS, 0x0C, 0x0C); // 设置LCD数据寄存器
    }
    
    void lcd_display_temperature(int temperature) {
        // 显示温度数据
        char buffer[10];
        sprintf(buffer, "%d°C", temperature);
        I2C_Write(LCD_ADDRESS, 0x80, buffer); // 显示温度数据
    }
    
    int main(void) {
        // 初始化LCD
        lcd_init();
    
        // 显示温度数据
        int temperature = 25; // 例子温度
        lcd_display_temperature(temperature);
    
        return 0;
    }
    

    请注意,这只是一个简单的示例代码,实际情况可能需要根据LCD的具体型号和MSP430G2553芯片的具体实现进行修改。

    评论

报告相同问题?

问题事件

  • 创建了问题 6月16日