找回密码
 立即注册
查看: 297|回复: 9

高4位数据线驱动1602

[复制链接]
  • TA的每日心情
    开心
    昨天 08:08
  • 签到天数: 196 天

    [LV.7]常住居民III

    14

    主题

    53

    回帖

    882

    积分

    高级会员

    积分
    882
    发表于 2023-11-26 13:23:22 | 显示全部楼层 |阅读模式
    1. void LCD1602_ClearDataPort()
    2. {
    3.         LCD1602_D4 = 0;
    4.         LCD1602_D5 = 0;
    5.         LCD1602_D6 = 0;
    6.         LCD1602_D7 = 0;
    7. }
    8. //LCD写时序控制
    9. void LCD1602_EN_Write(void)        //EN端产生一个高电平脉冲,控制LCD写时序
    10. {
    11.         EN_SET;
    12.         LCD1602_Delay(5);
    13.         EN_CLR;
    14. }
    15. //写指令函数
    16. void LCD1602_Write_Instruction(char Command)
    17. {
    18.   LCD1602_Delay(32);
    19.   RS_CLR;
    20.   RW_CLR;
    21.   LCD1602_ClearDataPort();//清高四位
    22.   LCD1602_D7 = (Command&0X80)>>7;
    23.   LCD1602_D6 = (Command&0X40)>>6;
    24.   LCD1602_D5 = (Command&0X20)>>5;
    25.   LCD1602_D4 = (Command&0X10)>>4;
    26.   LCD1602_EN_Write();//写入指令数据
    27.   LCD1602_Delay(32);
    28.   LCD1602_ClearDataPort();//清高四位
    29.   LCD1602_D7 = (Command&0X08)>>3;
    30.   LCD1602_D6 = (Command&0X04)>>2;
    31.   LCD1602_D5 = (Command&0X02)>>1;
    32.   LCD1602_D4 = (Command&0X01);
    33.   LCD1602_EN_Write();//写入指令数据
    34. }
    35. //清屏函数
    36. void LCD1602_Clear(void)
    37. {
    38.   LCD1602_Write_Instruction(0x01);
    39.   LCD1602_Delay(10000);
    40. }
    41. //显示屏初始化函数
    42. void LCD1602_Init(void)
    43. {
    44.         LCD1602_Port_init();
    45.         LCD1602_Delay(50000);   //上电延时,以使供电稳定
    46.         RS_CLR;
    47.         RW_CLR;
    48.         LCD1602_ClearDataPort();//清高四位
    49.         LCD1602_D7 = (0x28&0X80)>>7;
    50.         LCD1602_D6 = (0x28&0X40)>>6;
    51.         LCD1602_D5 = (0x28&0X20)>>5;
    52.         LCD1602_D4 = (0x28&0X10)>>4;
    53.         LCD1602_EN_Write();//写入指令数据
    54.         LCD1602_Delay(35);       
    55.        
    56.         LCD1602_Write_Instruction(0x08);        //关显示,不显光标,光标不闪烁
    57.         LCD1602_Clear(); //清屏
    58.        
    59.         LCD1602_Write_Instruction(0x04);        //写一字符,整屏显示不移动
    60.         //LCD1602_Write_Instruction(0x05);        //写一字符,整屏右移
    61.         //LCD1602_Write_Instruction(0x06);        //写一字符,整屏显示不移动
    62.         //LCD1602_Write_Instruction(0x07);        //写一字符,整屏左移
    63.         LCD1602_Delay(5000);
    64.        
    65.         //LCD1602_Write_Instruction(0x0B);        //关闭显示(不显示字符,只有背光亮)
    66.         LCD1602_Write_Instruction(0x0C);        //开显示,光标、闪烁都关闭
    67.         //LCD1602_Write_Instruction(0x0D);        //开显示,不显示光标,但光标闪烁
    68.         //LCD1602_Write_Instruction(0x0E);        //开显示,显示光标,但光标不闪烁
    69.         //LCD1602_Write_Instruction(0x0F);        //开显示,光标、闪烁均显示
    70. }
    71. //写数据函数
    72. void LCD1602_Write_Data(char Wdata)
    73. {
    74.   LCD1602_Delay(32);
    75.   RS_SET;
    76.   RW_CLR;
    77.   LCD1602_ClearDataPort();//清高四位
    78.   LCD1602_D7 = (Wdata&0X80)>>7;
    79.   LCD1602_D6 = (Wdata&0X40)>>6;
    80.   LCD1602_D5 = (Wdata&0X20)>>5;
    81.   LCD1602_D4 = (Wdata&0X10)>>4;
    82.   LCD1602_EN_Write();//写入数据
    83.   LCD1602_Delay(32);
    84.   LCD1602_ClearDataPort();//清高四位
    85.   LCD1602_D7 = (Wdata&0X08)>>3;
    86.   LCD1602_D6 = (Wdata&0X04)>>2;
    87.   LCD1602_D5 = (Wdata&0X02)>>1;
    88.   LCD1602_D4 = (Wdata&0X01);
    89.   LCD1602_EN_Write();//写入指数据
    90. }
    91. //字符显示初始地址设置
    92. void LCD1602_SET_XY(char X,char Y)
    93. {
    94.   char address;
    95.   if(Y==0)
    96.     address=0x80+X;//Y=0,表示在第一行显示,地址基数为0x80
    97.   else
    98.     address=0xc0+X;//Y非0时,表时在第二行显示,地址基数为0XC0
    99.   LCD1602_Write_Instruction(address);//写指令,设置显示初始地址
    100. }
    101. //在第X列Y行开始显示,指针*S所指向的字符串
    102. void LCD1602_Write_Str(char X,char Y,char *s)
    103. {
    104.   unsigned char i = 0;
    105.   //LCD1602_SET_XY(X,Y);//设置初始字符显示地址
    106.   while(*s)//逐次写入显示字符,直到最后一个字符"/0"
    107.   {
    108.     LCD1602_SET_XY(X+i,Y);//设置初始字符显示地址
    109.         LCD1602_Write_Data(*s);//写入当前字符并显示
    110.         s++;//地址指针加1,指向下一个待写字符
    111.         i++;
    112.   }
    113. }
    114. //在第X行Y列开始显示Wdata所对应的单个字符
    115. void LCD1602_Write_Char(char X,char Y,char Wdata)
    116. {
    117.   LCD1602_SET_XY(X,Y);//写地址
    118.   LCD1602_Write_Data(Wdata);//写入当前字符并显示
    119. }
    复制代码
    只用LCD1602高四位可以节约MCU 4个IO口。


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


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

    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 09:01
  • 签到天数: 192 天

    [LV.7]常住居民III

    6

    主题

    80

    回帖

    990

    积分

    高级会员

    积分
    990
    发表于 2023-11-27 21:10:50 | 显示全部楼层
    学习中
    回复 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 09:33
  • 签到天数: 167 天

    [LV.7]常住居民III

    2

    主题

    55

    回帖

    480

    积分

    中级会员

    积分
    480
    发表于 2024-1-5 12:15:29 | 显示全部楼层
    while(*s)   楼主  这个*S  字符串的尾是0会退出?这个是什么原理?

    点评

    while(*s) ,这个技巧用的还是挺巧妙的  发表于 2024-2-5 16:20
    C语言中 会把0认为是false,把非零的数认为是true,,在ASCII中\0 的值是0,,所以会退出循环。  发表于 2024-1-5 14:32
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 10:20
  • 签到天数: 166 天

    [LV.7]常住居民III

    21

    主题

    1247

    回帖

    3027

    积分

    论坛元老

    积分
    3027
    发表于 2024-1-5 14:36:26 | 显示全部楼层
    fjstcmcu 发表于 2024-1-5 12:15
    while(*s)   楼主  这个*S  字符串的尾是0会退出?这个是什么原理?


    这个是判断条件为 非零的情况下;
    截图202401051435144277.jpg

    这个是判断条件为 零的情况下
    截图202401051436209691.jpg

    参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
    技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 21:45
  • 签到天数: 100 天

    [LV.6]常住居民II

    9

    主题

    1025

    回帖

    1882

    积分

    金牌会员

    积分
    1882
    发表于 2024-3-13 11:27:25 | 显示全部楼层
    _奶咖君_ 发表于 2024-1-5 14:36
    这个是判断条件为 非零的情况下;

    if(is)和if(is=1)不是等同的吗
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 10:20
  • 签到天数: 166 天

    [LV.7]常住居民III

    21

    主题

    1247

    回帖

    3027

    积分

    论坛元老

    积分
    3027
    发表于 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)这里是假。
    参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
    技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 10:20
  • 签到天数: 166 天

    [LV.7]常住居民III

    21

    主题

    1247

    回帖

    3027

    积分

    论坛元老

    积分
    3027
    发表于 2024-3-13 11:40:16 | 显示全部楼层
    soma 发表于 2024-3-13 11:27
    if(is)和if(is=1)不是等同的吗

    我觉得要论说等同 应该是这样的
    if(is)  等同 if(is!=0)   
    这种写法应该是等同的
    参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
    技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    前天 09:35
  • 签到天数: 76 天

    [LV.6]常住居民II

    1

    主题

    2

    回帖

    365

    积分

    中级会员

    积分
    365
    发表于 2024-3-19 21:05:56 | 显示全部楼层
    fjstcmcu 发表于 2024-1-5 12:15
    while(*s)   楼主  这个*S  字符串的尾是0会退出?这个是什么原理?

    这个while(*s)后面应该要加一个s++;
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-6-14 07:36 , Processed in 0.068950 second(s), 61 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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