网购几块PCF8574T驱1602液晶模块,代码是坛里前辈写的,实验液晶不能显示,检查硬件没有错误,始终不能解决问题。无奈之下求助DpSk,生成的代码编译时出错,提示67行数据类型错误,将66行子函数的参数rs数据类型由bit改为unsigned char后编译成功,下载到单片机显示正常。AI生成的代码也不错。
#include <STC15.h>
#include <intrins.h>
#define PCF_ADDR 0x4E
sbit SDA = P0^1; // I2C数据线
sbit SCL = P0^0; // I2C时钟线
void delay_us(unsigned int us) {
while (us--) {
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 114; j++);
}
void I2C_Start() {
SDA = 1;
SCL = 1;
delay_us(5);
SDA = 0;
delay_us(5);
SCL = 0;
}
void I2C_Stop() {
SDA = 0;
SCL = 1;
delay_us(5);
SDA = 1;
delay_us(5);
}
void I2C_WriteByte(unsigned char dat) {
unsigned char i;
for (i = 0; i < 8; i++) {
SDA = (dat & 0x80) ? 1 : 0;
dat <<= 1;
SCL = 1;
delay_us(5);
SCL = 0;
delay_us(5);
}
SDA = 1; // 释放总线等待ACK
SCL = 1;
delay_us(5);
SCL = 0;
}
void PCF8574_Write(unsigned char dat) {
I2C_Start();
I2C_WriteByte(PCF_ADDR);
I2C_WriteByte(dat);
I2C_Stop();
}
void lcd_send_nibble(unsigned char nibble, unsigned char rs) {
unsigned char data_pcf;
// 数据位: P4-P7, RS: P0, E: P2, Backlight: P3 (开启)
data_pcf = (nibble << 4) | (rs << 0) | (1 << 3);
// E下降沿
PCF8574_Write(data_pcf & ~(1 << 2)); // E=0
delay_us(1);
PCF8574_Write(data_pcf | (1 << 2)); // E=1
delay_us(1);
PCF8574_Write(data_pcf & ~(1 << 2)); // E=0
delay_us(100);
}
void lcd_send_byte(unsigned char dat, bit rs) {
lcd_send_nibble(dat >> 4, rs); // 高四位
lcd_send_nibble(dat & 0x0F, rs); // 低四位
}
void lcd_init() {
delay_ms(50);
lcd_send_nibble(0x03, 0);
delay_ms(5);
lcd_send_nibble(0x03, 0);
delay_ms(1);
lcd_send_nibble(0x03, 0);
delay_us(100);
lcd_send_nibble(0x02, 0);
delay_us(100);
lcd_send_byte(0x28, 0); // 4位, 2行, 5x8
delay_us(100);
lcd_send_byte(0x0C, 0); // 显示开, 光标关
delay_us(100);
lcd_send_byte(0x06, 0); // 增量不移屏
delay_us(100);
lcd_send_byte(0x01, 0); // 清屏
delay_ms(2);
}
void lcd_set_cursor(unsigned char row, unsigned char col) {
unsigned char address = (row == 0) ? 0x80 : 0xC0;
lcd_send_byte(address + col, 0);
}
void lcd_write_string(char *str) {
while (*str) {
lcd_send_byte(*str++, 1);
}
}
void main() {
lcd_init();
lcd_set_cursor(0, 0);
lcd_write_string("Hello World!");
lcd_set_cursor(1, 0);
lcd_write_string("51 & PCF8574T");
while (1);
}
|