找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 738|回复: 3
打印 上一主题 下一主题
收起左侧

stc89c51+lcd1602+pcf8574转接板

[复制链接]
跳转到指定楼层
楼主
ID:845027 发表于 2023-3-21 10:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
stc89c51+lcd1602+pcf8574转接板
代码如下,不知道为什么lcd没有显示,我这个pcf8574的地址是和A0 A1 A2有关的,三个接地是0x20
#include <reg52.h>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int

//#define                        L1                0x80            // 第一行写入地址
//#define                        L2                0xc0            // 第二行写入地址
        
sbit SCL = P2^0;
sbit SDA = P2^1;

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位数据线,显示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++)
//        {
        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);
//}

跪求大佬帮忙
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:102963 发表于 2023-3-21 16:56 | 只看该作者
你说你的地址码是0x20,可你程序里面是0x27,char ADDR = 0x27;    // PCF8574   AT  模块的地址码。这对不上吧?
回复

使用道具 举报

板凳
ID:845027 发表于 2023-3-22 14:45 | 只看该作者
songxia8013 发表于 2023-3-21 16:56
你说你的地址码是0x20,可你程序里面是0x27,char ADDR = 0x27;    // PCF8574   AT  模块的地址码。这对不 ...

三个悬空的话,地址码就是0x27,我0x27和0x20都试过还是没有亮
回复

使用道具 举报

地板
ID:996773 发表于 2023-3-27 15:00 | 只看该作者
本来也想用串行转并输出到1602方案,觉得成本提高不少,最终衡量下用四线方案

数据线,时钟线,en使能线加四线数据共 7根线正好一个p1口驱动。这样方案最好

少了四根线还不用串转并芯片
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表