STC32和STC8H通过IIC转接板驱动LCD1602
前几天看到论坛有关于LCD1602的帖子,正好手边有带有 PCF8574T 转接板的 LCD1602 模块,如图所示,代码见附件。但是无论怎么调节电位器,字迹的对比度最大就是图中那样,开背光情况下文字不够黑……用 Arduino Nano 显示效果就很好,不知道是不是程序哪里出问题了,求大神帮忙指点~
LCD的显示清晰度通过调节VO脚的电压进行调整。
这是实验箱例程包里面LCD接口的参考原理图:
是不是3.3V电压的原因呢? 21cnsound 发表于 2024-1-27 15:00
是不是3.3V电压的原因呢?
正解啊,一箭双雕的跳线帽换到 5V ,完美解决问题啦~
感谢~~
本帖最后由 405616736 于 2024-9-19 00:28 编辑
根据楼主的程序,个人稍微修改了一下
/**********接口说明**********/
sbit SCL=P1^0;
sbit SDA=P1^1;
/**********全局变量**********/
bit LED=1;
char T;
unsigned char Address={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+y,0x0c); //执行地址转换,x为行号 y为列号
while(*str!='\0') //表示显示内容不为空时,执行循环体的代码段,
{
LCD_SendData(*str++,0x0d); //发送命令,*就是声明他的类型,是一个指向整型数据的指针
}
}
竟然是模拟i2c的看下能不能改硬件i2c soma 发表于 2024-9-18 19:31
竟然是模拟i2c的看下能不能改硬件i2c
我改了一个使用硬件IIC的程序
/**********全局变量**********/
bit LED=1;
char address={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+y,0x0c); //执行地址转换,x为行号 y为列号
while(*str!='\0') //表示显示内容不为空时,执行循环体的代码段,
{
LCD_SendData(*str++,0x0d); //发送命令,*就是声明他的类型,是一个指向整型数据的指针
}
}
页:
[1]