标题:
stc89c51单片机+pcf8574(默认地址0x27)+lcd1602没有亮
[打印本页]
作者:
jokerking
时间:
2023-3-21 16:03
标题:
stc89c51单片机+pcf8574(默认地址0x27)+lcd1602没有亮
stc89c51+pcf8574(默认地址0x27)+lcd1602代码烧录上去,lcd没有亮,不知道到底是哪里出现了问题,LCD1602是在某一个宝上面买的,只有个C8051的破的代码和arduino都用不了,我们学校要求用stc89c51单片机去编写,求大佬看看哪里出现了问题。
1679385714895.jpg
(2.48 MB, 下载次数: 36)
下载附件
2023-3-21 16:02 上传
单片机源程序如下:
#include <reg52.h>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
//#define L1 0x80 // 第一行写入地址
//#define L2 0xc0 // 第二行写入地址
sbit SCL = P2^1;
sbit SDA = P2^0;
uchar woder[]={"wangzijie"};
//char ADDR = 0x4E; // PCF8574 T 模块的地址码
//char ADDR = 0x7e; // PCF8574 AT 模块的地址码
char ADDR = 0x27; // PCF8574 AT 模块的地址码
//***************************** 延时 y ms ***********************************************
void delay1(int y) //
{
;
while(y--)
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
//******************************** IIC 串口开始 ********************************************
void IIC_start(void)
{
SDA=1;
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
//********************************** IIC 串口写1个字节 ******************************************
void IIC_writeByte(char temp)
{
char i;
for(i=0;i<8;i++)
{
SDA=(bit)(temp & 0x80) ; // 根据规定1602的数据最高位必须为 1
temp <<=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
while(SDA);
_nop_();
SCL=0;
}
//******************************** 1602写命令 ********************************************
void LCD_write_command(char comm)
{
char tmp;
IIC_start(); // 串口开始
IIC_writeByte(ADDR); // 先选PCF 8574T 的地址 (应该是相当于选中的意思吧)
tmp = comm & 0xF0; // 与0xf0 应该是取第四位的意思吧
tmp |= 0x0C; //保留高4位为指令的高四位,低四位为 RS = 0, RW = 0, EN = 1
IIC_writeByte(tmp); //从串口送出
delay1(20);
tmp &= 0xFB; //Make EN = 0
IIC_writeByte(tmp);
tmp = (comm & 0x0F) << 4 ; //将指令的低四位 送到高位置保存
tmp |= 0x0C; //RS = 0, RW = 0, EN = 1
IIC_writeByte(tmp);
delay1(20);
tmp &= 0xFB; // Make EN = 0
IIC_writeByte(tmp);
}
//******************************** 1602写数据 ********************************************
void LCD_write_data(char data1)
{
char tmp;
IIC_start();
IIC_writeByte(ADDR); // 先选PCF8574T 的地址 (应该是相当于选中的意思吧)
tmp = data1 & 0xF0;
tmp |= 0x0D; //RS = 0, RW = 0, EN = 1
IIC_writeByte(tmp);
delay1(20);
tmp &= 0xFB; //Make EN = 0
IIC_writeByte(tmp);
tmp = (data1 & 0x0F) << 4 ;
tmp |= 0x0D; //RS = 0, RW = 0, EN = 1
IIC_writeByte(tmp);
delay1(20);
tmp &= 0xFB ; // Make EN = 0
IIC_writeByte(tmp);
}
//******************************** 1602初始化 ********************************************
void Init_Lcd(void)
{
LCD_write_command(0x33); //将8位总线转为4位总线
delay1(50) ;
LCD_write_command(0x32); //
delay1(50) ;
LCD_write_command(0x28); // 4位数据线0x28,显示2行,5*7点阵字符 !如果是0x38 则为8位数据线,显示2行,5*7点阵字符
delay1(50) ;
LCD_write_command(0x0C); // 开显示,关闭光标,不闪烁
delay1(50) ;
LCD_write_command(0x06); // 设定输入方式,增量不位移
delay1(50) ;
LCD_write_command(0x01); // 清屏
delay1(50) ;
// LCD_write_command(0x80); //设置数据指针起点
// delay1(50) ;
}
//*************************************** 在指定位置显示字符串 *************************************
void Write_LCD(int x, int y, char *str)
{
char addr;
if( x < 0)
{
x = 0;
}
if(x > 15)
{
x = 15;
}
if(y<0)
{
y = 0;
}
if(y > 1)
{
y = 1;
}
addr = 0x80 + 0x40 * y + x; // Move cursor 移动光标
LCD_write_command(addr);
while (*str)
{
LCD_write_data(*str++);
}
}
//-------------------------------------------- 显示字符串的函数 ----------------------------------------------------
void LCD_write_word(unsigned char *s) //显示字符串的函数
{
while(*s>0)
{
LCD_write_data(*s);
s++;
}
}
void main()
{
uchar i;
Init_Lcd();
// for(i=0;i<9;i++)
// {
Write_LCD(0,0,(uchar *)woder[i]);
LCD_write_word((uchar *)woder[i]);
// }
while(1);
}
//********************************* 指定位置显示一个字符*******************************************
/*
void Print_Char (unsigned char line,unsigned char num,unsigned char date)
{
LCD_write_command(line+num);
LCD_write_data(date);
}
*/
//按指定位置显示一个字符(针对1602液晶)-用在温度显示
//void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
//{
//Y &= 0x1;
//X &= 0xF; //限制X不能大于15,Y不能大于1
//if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
//X |= 0x80; // 算出指令码
//LCD_write_command(X); //这里不检测忙信号,发送地址码
//LCD_write_data(DData);
//}
复制代码
作者:
dragon19790000
时间:
2025-8-14 19:53
查询一下PFC8574地址吧,试试0x7E
作者:
lzuoxin
时间:
2025-8-15 07:22
IIC的地址挨个试一下,可能是下面中的一个:
0x4e
0x7e
0x27
0x3f
作者:
joyb
时间:
2025-8-15 11:19
常见问题
1. 屏幕不显示
不显示的原因有很多, 如果确认代码和接线无误, 可能的原因有
1)检查1602LCD的供电电压是不是5V, 在3.3V下无法驱动, 只有背光没有字符
2)检查I2C地址是否正确. 查看串口扫描到的实际的设备I2C地址, 是否和程序中的地址一致, 通常情况下, PCF8574T的地址是0x4E, PCF8574AT的地址是0x7E
2. 字符显示乱码
HD44780对启动的指令顺序和延时是有要求的, 可以参考其数据手册的P45, 如果延时不够或指令顺序不正确, 会导致屏幕未进入4-bit模式而导致显示错乱。对于部分屏幕, 启动时需要增大延时, 如果等待时间不足, 会导致输出乱码。
作者:
cy009
时间:
2025-8-15 17:42
IIC时序不严谨
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1