找回密码
 立即注册
查看: 912|回复: 6

STC32和STC8H通过IIC转接板驱动LCD1602

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:521
  • 最近打卡:2025-05-03 00:08:48
已绑定手机
已实名认证

46

主题

161

回帖

482

积分

中级会员

积分
482
发表于 2024-1-27 05:23:36 | 显示全部楼层 |阅读模式
前几天看到论坛有关于LCD1602的帖子,正好手边有带有 PCF8574T 转接板的 LCD1602 模块,如图所示,代码见附件。

但是无论怎么调节电位器,字迹的对比度最大就是图中那样,开背光情况下文字不够黑……用 Arduino Nano 显示效果就很好,不知道是不是程序哪里出问题了,求大神帮忙指点~

LCD1602 Display

LCD1602 Display

PCF8574T

PCF8574T

LCD1602_PCF8574T_STC8H.c

5.89 KB, 下载次数: 95

Code_STC8H

LCD1602_PCF8574T_STC32G.c

6.24 KB, 下载次数: 74

Code_STC32G

MCU开发者和爱好者
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6845

积分

论坛元老

积分
6845
发表于 2024-1-27 12:46:43 | 显示全部楼层
LCD的显示清晰度通过调节VO脚的电压进行调整。
这是实验箱例程包里面LCD接口的参考原理图:
截图202401271245305728.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:454
  • 最近打卡:2025-05-03 00:18:42
已绑定手机

13

主题

1257

回帖

2979

积分

金牌会员

积分
2979
发表于 2024-1-27 15:00:00 | 显示全部楼层
是不是3.3V电压的原因呢?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:521
  • 最近打卡:2025-05-03 00:08:48
已绑定手机
已实名认证

46

主题

161

回帖

482

积分

中级会员

积分
482
发表于 2024-1-28 03:29:40 | 显示全部楼层
21cns*** 发表于 2024-1-27 15:00
是不是3.3V电压的原因呢?

正解啊,一箭双雕的跳线帽换到 5V ,完美解决问题啦~
感谢~~

LCD1602_5V

LCD1602_5V
MCU开发者和爱好者
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-04-26 20:12:05
已绑定手机

3

主题

17

回帖

1449

积分

金牌会员

积分
1449
发表于 2024-9-18 18:58:59 | 显示全部楼层
本帖最后由 405616736 于 2024-9-19 00:28 编辑

根据楼主的程序,个人稍微修改了一下



/**********接口说明**********/
sbit SCL=P1^0;
sbit SDA=P1^1;

/**********全局变量**********/
bit LED=1;
char T[10];
unsigned char Address[4]={0x80,0xc0,0x94,0xd4};

/******************************
                IIC初始化
******************************/
void IIC_Init()
        {
                SDA=1;                //拉高SDA
                SCL=1;                //拉高SCL
                _nop_();_nop_();_nop_();_nop_();_nop_();                //软件延时
        }

/******************************
                IIC启始信号
******************************/
void IIC_Start()                //当SCL时钟线为高电平,SDA数据线由高变低时,为起始信号。
                {
                        SCL=1;                //拉高SDA
                        SDA=1;                //拉高SCL
                        _nop_();_nop_();_nop_();_nop_();_nop_();                //软件延时
                        SDA=0;                //SDA从高到低跳变
                        _nop_();_nop_();_nop_();_nop_();_nop_();                //软件延时
                        SCL=0;                //每次操作完拉低SCL,继续占用总线
                }

/******************************
                IIC停止信号
******************************/
void IIC_Stop()                //SCL时钟线为高电平,SDA数据线由低变高时,为停止信号。
        {
    SCL=1;                //SCL为高
    SDA=0;                //SDA为低
                _nop_();_nop_();_nop_();_nop_();_nop_();                //软件延时
    SDA=1;                //SDA由低到高跳变
        }
       
/******************************
                IIC串口写入1个字节
******************************/
void IIC_WriteByte(unsigned char dat)
        {
                unsigned char i;
    for(i=0;i<8;i++)
    {
                        dat<<=1;                //移掉高位,准备发次高位
                        SDA=CY;                //发数据位1
                        _nop_();_nop_();
                        SCL=1;                //拉高SCL,从机读取数据
                        _nop_();_nop_();_nop_();_nop_();_nop_();                //软件延时
                        SCL=0;                //拉低时钟,低电平发数据
    }               
                _nop_();_nop_();_nop_();_nop_();_nop_();                //软件延时
                SDA=1;                //主机读数据前,先切断输出通道,切换为输入模式
                _nop_();_nop_();_nop_();_nop_();_nop_();                //软件延时
    SCL=1;                //拉高SCL,准备接收应答
                _nop_();_nop_();_nop_();_nop_();_nop_();                //软件延时
                while((SDA==1)&&(++i!=0));                //向主机发应答,主机读取SDA,判断应答状态
    SCL=0;                //每次操作完拉低SCL,继续占用总线
        }
       
/******************************
                LCD发送命令或数据
******************************/
void LCD_SendData(unsigned char dat,unsigned char mode)                //mode=0x0c,指令寄存器;mode=0x0d,数据寄存器
        {
    unsigned char i,temp;
    IIC_Start();                // 串口开始
    IIC_WriteByte(0x4E);                //PCF8574T模块的地址码
    for(i=0;i<2;i++)
                {
                        if(i==0)        temp=dat&0xf0;                //低4位置0,高4位不变
                        if(i==1)        temp=dat<<4;                //左移4位,低4位变高4位
                        temp|=mode;                //0x0C→EN=1,RW=0,RS=0        0x0D→EN=1,RW=1,RS=0                       
                        if(LED==0)        temp&=0xf7;                //LED关闭
                        IIC_WriteByte(temp);
                        Delay(1);                //延时,给硬件反应时间
                        if(LED==0)        temp&=0xf7;                //LED关闭
                        temp&=0xfb;                //EN=0
                        IIC_WriteByte(temp);
                }
                IIC_Stop();
        }

/******************************
                LCD初始化
******************************/
void LCD_Init(void)
        {
    LCD_SendData(0x02,0x0c);                //写命令,光标复位
    Delay(10);                //10ms延时,给硬件反应时间
    LCD_SendData(0x28,0x0c);                //写命令,设置16*2显示,5*7点阵,4位数据接口
    Delay(10);                //10ms延时,给硬件反应时间
    LCD_SendData(0x01,0x0c);                //写命令,显示清屏:1.数据指针清零 2.所有显示清零
    Delay(10);                //10ms延时,给硬件反应时间
    LCD_SendData(0x06,0x0c);                //写命令,当读或写一个字符后地址指针加一,且光标加一
    Delay(10);                //10ms延时,给硬件反应时间
    LCD_SendData(0x0c,0x0c);                //写命令,开显示,不显示光标,光标不显示
    Delay(10);                //10ms延时,给硬件反应时间
        }

/******************************
                发送字符串到LCD
******************************/
void LCD_PutString(unsigned char x,y,unsigned char *str)
        {
                LCD_SendData(Address[x]+y,0x0c);                //执行地址转换,x为行号 y为列号
                while(*str!='\0')                //表示显示内容不为空时,执行循环体的代码段,
                        {
                                LCD_SendData(*str++,0x0d);                //发送命令,*就是声明他的类型,是一个指向整型数据的指针
                        }
        }

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:424
  • 最近打卡:2025-05-03 00:02:01
已绑定手机

19

主题

3191

回帖

4876

积分

论坛元老

积分
4876
发表于 2024-9-18 19:31:33 来自手机 | 显示全部楼层
竟然是模拟i2c的看下能不能改硬件i2c
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-04-26 20:12:05
已绑定手机

3

主题

17

回帖

1449

积分

金牌会员

积分
1449
发表于 2024-9-25 23:36:15 | 显示全部楼层
so*** 发表于 2024-9-18 19:31
竟然是模拟i2c的看下能不能改硬件i2c

我改了一个使用硬件IIC的程序

/**********全局变量**********/
bit LED=1;
char address[4]={0x80,0xc0,0x94,0xd4};

void I2C_Wait()
        {
                while(!(I2CMSST&0x40));                //主机模式时PC控制器状态位(只读位)  0:控制器处于空闲状态          1:控制器处于忙碌状态
    I2CMSST&=~0x40;
        }

void I2C_Start()
        {
                I2CMSCR=0x01;                //发送START命令
    I2C_Wait();
        }

void I2C_SendData(char dat)
        {
    I2CTXD=dat;                //写数据到数据缓冲区
    I2CMSCR=0x02;                //发送SEND命令
    I2C_Wait();
        }

void I2C_RecvACK()
        {
    I2CMSCR=0x03;                //发送读ACK命令
    I2C_Wait();
        }

void I2C_Stop()
        {
                I2CMSCR=0x06;                //发送STOP命令
    I2C_Wait();
        }

/******************************
                LCD发送命令或数据
******************************/
void LCD_SendData(char dat,char mode)                //mode=0x0c,指令寄存器;mode=0x0d,数据寄存器
        {
    char i,temp;
    I2C_Start();                //串口开始
    I2C_SendData(0x4E);I2C_RecvACK();                //PCF8574T模块的地址码   
    for(i=0;i<4;i++)
                {
                        if(i==0)                temp=dat&0xf0|mode;                //低4位置0,高4位不变
                        if(i==2)                temp=dat<<4|mode;                //左移4位,低4位变高4位
                        if(i%2==1)        temp&=0xfb;                //EN=0               
                        if(LED==0)        temp&=0xf7;                //LED关闭
                        I2C_SendData(temp);I2C_RecvACK();
                }
                I2C_Stop();
                if(mode==0x0c)        Delay(10);                //延时,LCD反应时间
        }

/******************************
                LCD初始化
******************************/
void LCD_Init(void)
        {
    LCD_SendData(0x02,0x0c);                //写命令,光标复位   
    LCD_SendData(0x28,0x0c);                //写命令,设置16*2显示,5*7点阵,4位数据接口
    LCD_SendData(0x01,0x0c);                //写命令,显示清屏:1.数据指针清零 2.所有显示清零
    LCD_SendData(0x06,0x0c);                //写命令,当读或写一个字符后地址指针加一,且光标加一
    LCD_SendData(0x0c,0x0c);                //写命令,开显示,不显示光标,光标不显示
        }

/******************************
                发送字符串到LCD
******************************/
void LCD_PutString(char x,char y,unsigned char *str)
        {
                LCD_SendData(address[x]+y,0x0c);                //执行地址转换,x为行号 y为列号
                while(*str!='\0')                //表示显示内容不为空时,执行循环体的代码段,
                        {
                                LCD_SendData(*str++,0x0d);                //发送命令,*就是声明他的类型,是一个指向整型数据的指针
                        }
        }
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 20:21 , Processed in 0.147873 second(s), 92 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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