sujingliang 发表于 2023-11-26 13:23:22

高4位数据线驱动1602

void LCD1602_ClearDataPort()
{
        LCD1602_D4 = 0;
        LCD1602_D5 = 0;
        LCD1602_D6 = 0;
        LCD1602_D7 = 0;
}
//LCD写时序控制
void LCD1602_EN_Write(void)      //EN端产生一个高电平脉冲,控制LCD写时序
{
        EN_SET;
        LCD1602_Delay(5);
        EN_CLR;
}

//写指令函数
void LCD1602_Write_Instruction(char Command)
{
LCD1602_Delay(32);
RS_CLR;
RW_CLR;
LCD1602_ClearDataPort();//清高四位
LCD1602_D7 = (Command&0X80)>>7;
LCD1602_D6 = (Command&0X40)>>6;
LCD1602_D5 = (Command&0X20)>>5;
LCD1602_D4 = (Command&0X10)>>4;

LCD1602_EN_Write();//写入指令数据
LCD1602_Delay(32);
LCD1602_ClearDataPort();//清高四位
LCD1602_D7 = (Command&0X08)>>3;
LCD1602_D6 = (Command&0X04)>>2;
LCD1602_D5 = (Command&0X02)>>1;
LCD1602_D4 = (Command&0X01);

LCD1602_EN_Write();//写入指令数据
}
//清屏函数
void LCD1602_Clear(void)
{
LCD1602_Write_Instruction(0x01);
LCD1602_Delay(10000);
}
//显示屏初始化函数
void LCD1602_Init(void)
{
        LCD1602_Port_init();
        LCD1602_Delay(50000);   //上电延时,以使供电稳定

        RS_CLR;
        RW_CLR;
        LCD1602_ClearDataPort();//清高四位
        LCD1602_D7 = (0x28&0X80)>>7;
        LCD1602_D6 = (0x28&0X40)>>6;
        LCD1602_D5 = (0x28&0X20)>>5;
        LCD1602_D4 = (0x28&0X10)>>4;
        LCD1602_EN_Write();//写入指令数据
        LCD1602_Delay(35);       
       
        LCD1602_Write_Instruction(0x08);        //关显示,不显光标,光标不闪烁
        LCD1602_Clear(); //清屏
       
        LCD1602_Write_Instruction(0x04);        //写一字符,整屏显示不移动
        //LCD1602_Write_Instruction(0x05);        //写一字符,整屏右移
        //LCD1602_Write_Instruction(0x06);        //写一字符,整屏显示不移动
        //LCD1602_Write_Instruction(0x07);        //写一字符,整屏左移
        LCD1602_Delay(5000);
       
        //LCD1602_Write_Instruction(0x0B);        //关闭显示(不显示字符,只有背光亮)
        LCD1602_Write_Instruction(0x0C);        //开显示,光标、闪烁都关闭
        //LCD1602_Write_Instruction(0x0D);        //开显示,不显示光标,但光标闪烁
        //LCD1602_Write_Instruction(0x0E);        //开显示,显示光标,但光标不闪烁
        //LCD1602_Write_Instruction(0x0F);        //开显示,光标、闪烁均显示
}

//写数据函数
void LCD1602_Write_Data(char Wdata)
{
LCD1602_Delay(32);
RS_SET;
RW_CLR;
LCD1602_ClearDataPort();//清高四位

LCD1602_D7 = (Wdata&0X80)>>7;
LCD1602_D6 = (Wdata&0X40)>>6;
LCD1602_D5 = (Wdata&0X20)>>5;
LCD1602_D4 = (Wdata&0X10)>>4;

LCD1602_EN_Write();//写入数据
LCD1602_Delay(32);
LCD1602_ClearDataPort();//清高四位
LCD1602_D7 = (Wdata&0X08)>>3;
LCD1602_D6 = (Wdata&0X04)>>2;
LCD1602_D5 = (Wdata&0X02)>>1;
LCD1602_D4 = (Wdata&0X01);
LCD1602_EN_Write();//写入指数据
}

//字符显示初始地址设置
void LCD1602_SET_XY(char X,char Y)
{
char address;
if(Y==0)
    address=0x80+X;//Y=0,表示在第一行显示,地址基数为0x80
else
    address=0xc0+X;//Y非0时,表时在第二行显示,地址基数为0XC0
LCD1602_Write_Instruction(address);//写指令,设置显示初始地址
}

//在第X列Y行开始显示,指针*S所指向的字符串
void LCD1602_Write_Str(char X,char Y,char *s)
{
unsigned char i = 0;
//LCD1602_SET_XY(X,Y);//设置初始字符显示地址
while(*s)//逐次写入显示字符,直到最后一个字符"/0"
{
    LCD1602_SET_XY(X+i,Y);//设置初始字符显示地址
        LCD1602_Write_Data(*s);//写入当前字符并显示
        s++;//地址指针加1,指向下一个待写字符
        i++;
}
}

//在第X行Y列开始显示Wdata所对应的单个字符
void LCD1602_Write_Char(char X,char Y,char Wdata)
{
LCD1602_SET_XY(X,Y);//写地址
LCD1602_Write_Data(Wdata);//写入当前字符并显示
}
只用LCD1602高四位可以节约MCU 4个IO口。


控制上,写数据时要向D7、D6、D5、D4写两遍数据,第一遍写数据高4位,第二遍写数据低4位。


一般有8位数据口的LCD1602也可以用4位驱动,低4位悬空即可。

stb988 发表于 2023-11-27 21:10:50

学习中

fjstcmcu 发表于 2024-1-5 12:15:29

while(*s)   楼主这个*S字符串的尾是0会退出?这个是什么原理?

_奶咖君_ 发表于 2024-1-5 14:36:26

fjstcmcu 发表于 2024-1-5 12:15
while(*s)   楼主这个*S字符串的尾是0会退出?这个是什么原理?


这个是判断条件为 非零的情况下;


这个是判断条件为 零的情况下


soma 发表于 2024-3-13 11:27:25

_奶咖君_ 发表于 2024-1-5 14:36
这个是判断条件为 非零的情况下;




if(is)和if(is=1)不是等同的吗

_奶咖君_ 发表于 2024-3-13 11:37:05

soma 发表于 2024-3-13 11:27
if(is)和if(is=1)不是等同的吗

第一,如果 判断条件里 你写成了 “is = 1” 那么这个条件永远为真。
第二,这里暂且认为 “is = 1” 是 “is == 1”.那么基于这个前提,if(is) 也不能等同if(is==1) 当is = 5;时if(is) 这里时为真的 ,但是if(if==1)这里是假。

_奶咖君_ 发表于 2024-3-13 11:40:16

soma 发表于 2024-3-13 11:27
if(is)和if(is=1)不是等同的吗

我觉得要论说等同 应该是这样的
if(is)等同 if(is!=0)   
这种写法应该是等同的

mtt661 发表于 2024-3-19 21:05:56

fjstcmcu 发表于 2024-1-5 12:15
while(*s)   楼主这个*S字符串的尾是0会退出?这个是什么原理?

这个while(*s)后面应该要加一个s++;
页: [1]
查看完整版本: 高4位数据线驱动1602