找回密码
 立即注册
查看: 2730|回复: 5

使用2位数据线做控制 LCD1602用HC164

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-05-02 00:29:54

10

主题

1159

回帖

5121

积分

论坛元老

积分
5121
发表于 2023-2-10 00:04:17 | 显示全部楼层 |阅读模式
本帖最后由 angmall 于 2023-2-10 00:04 编辑

I/O口 不够,咋办 使用2位数据线做控制 LCD1602  用 HC164 的串行输入控制 扩展输出 8位
STC15W_LCD1602_HC164TwoWire.jpg


  1. /* Main.c file generated by New Project wizard
  2. *
  3. * Created:   周四 2月 9 2023
  4. * Processor: STC15W4K32S4
  5. * Compiler:  Keil for 8051
  6. I/O口 不够,咋办 使用2位数据线做控制 LCD1602  用 HC164 的串行输入控制 扩展输出 8位
  7. */
  8. #include <reg51.h>
  9. #include <stdio.h>
  10. #include <intrins.h >  //头文件的包含 _nop_()  
  11. //#define MAIN_Fosc       11059200UL  //定义主时钟
  12. #define MAIN_Fosc       12000000UL  //定义主时钟
  13. sfr P0M1 = 0x93;
  14. sfr P0M0 = 0x94;
  15. sfr P1M1 = 0x91;
  16. sfr P1M0 = 0x92;
  17. sfr P2M1 = 0x95;
  18. sfr P2M0 = 0x96;
  19. sfr P3M1 = 0xb1;
  20. sfr P3M0 = 0xb2;
  21. sfr P4M1 = 0xb3;
  22. sfr P4M0 = 0xb4;
  23. sfr P5M1 = 0xC9;
  24. sfr P5M0 = 0xCA;
  25. sfr P6M1 = 0xCB;
  26. sfr P6M0 = 0xCC;
  27. sfr P7M1 = 0xE1;
  28. sfr P7M0 = 0xE2;
  29. typedef unsigned char      uint8;          // 无符号8位整型变量 //
  30. typedef unsigned int       uint16;          // 无符号16位整型变量 //
  31. /********************************************************************************************
  32. // 指令集 //将所有可能用到的指令先预定义一下,方面以后的使用
  33. /********************************************************************************************/
  34. #define CMD_clear       0x01             // 清除屏幕
  35. #define CMD_back       0x02             // DDRAM回零位
  36. #define CMD_dec1       0x04             // 读入后AC(指针)减1,向左写
  37. #define CMD_add1      0x06             // 读入后AC(指针)加1,向右写
  38. #define CMD_dis_gb1  0x0f             // 开显示_开光标_开光标闪烁
  39. #define CMD_dis_gb2  0x0e             // 开显示_开光标_关光标闪烁
  40. #define CMD_dis_gb3  0x0c             // 开显示_关光标_关光标闪烁
  41. #define CMD_OFF_dis  0x08             // 关显示_关光标_关光标闪烁
  42. #define CMD_set82     0x38             // 8位总线_2行显示
  43. #define CMD_set81     0x30             // 8位总线_1行显示(上边行)
  44. #define CMD_set42     0x28             // 4位总线_2行显示
  45. #define CMD_set41     0x20             // 4位总线_1行显示(上边行)
  46. #define lin_1         0x80             // 4位总线_1行显示(上边行)
  47. #define lin_2         0xc0             // 4位总线_1行显示(上边行)
  48. sbit   LCD1602_RS=P2^1;  /* Data Command Pin  1 data  0 command pin 4  */
  49. sbit   LCD1602_E =P2^0;  /* LCD Enable Signal  pin 6  */
  50. bit    rs = 0;             // lcd 'rs' flag
  51. void _delay_us(uint16 i)
  52. {
  53.         while(i--)
  54.    {        
  55.         _nop_();
  56.         _nop_();
  57.         _nop_();
  58.         _nop_();
  59.    }
  60. }
  61. void Delay1ms(unsigned int xms)
  62. {
  63.         uint16 x,y;
  64.         for(x=xms;x>12;x--)
  65.             for(y=169;y>0;y--);
  66. }
  67. /********************************************************************************************
  68. // 写数据程序 //
  69. /********************************************************************************************/
  70. void LCD1602_Write(uint8 LCD1602_work) {
  71.     uint8 bitctr = 8;
  72.      do                         // start of bit clock cycle
  73.      { if(!(LCD1602_work & 128))        // if b7 is a '0' bit
  74.          LCD1602_RS = 0;       // start clock cycle for a '0'
  75.        _delay_us(55);            // charge or drain cap to 3t
  76.       
  77.                LCD1602_RS = 0;         // start clock cycle for a '1'
  78.                LCD1602_RS = 1;         // clock out the '0' or '1'
  79.        LCD1602_work <<= 1;      // prep for next bit
  80.      } while(--bitctr);         // until all 8 bits clocked out
  81.      if(!rs) LCD1602_RS = 0;   // make clk pin = rs flag
  82.      LCD1602_E = 1;           // latch 595, pulse LCD 'E' pin
  83.      LCD1602_E = 0;            //  "
  84.      LCD1602_RS = 1;            // always leave clk pin high
  85. }
  86. /********************************************************************************************
  87. // 写指令程序 //
  88. /********************************************************************************************/
  89. void LCD1602_WriteCMD(uint8 LCD1602_command) {
  90. rs = 0;  LCD1602_Write(LCD1602_command); rs = 1;  
  91. }
  92. /********************************************************************************************
  93. // 初始化
  94. /********************************************************************************************/
  95. void LCD1602_Init(void){
  96.     LCD1602_E = 0;
  97.     LCD1602_RS = 1;
  98.     Delay1ms(100);
  99.         LCD1602_WriteCMD(CMD_set82);  //16*2显示,5*7点阵,8位数据
  100.         LCD1602_WriteCMD(CMD_set82);
  101.         LCD1602_WriteCMD(CMD_clear);
  102.         LCD1602_WriteCMD(CMD_back);
  103.         LCD1602_WriteCMD(CMD_add1);
  104.         LCD1602_WriteCMD(CMD_dis_gb3);
  105.     Delay1ms(2);
  106. }
  107. /********************************************************************************************
  108. // 打印字符串程序 // (本函数调用指针函数)
  109. // 第一行位置 0x00~0x0f  第二行位置 0x40~0x4f
  110. /********************************************************************************************/
  111. void print_str(uint8 a, uint8 *str){
  112.         LCD1602_WriteCMD(a | 0x80);
  113.         while(*str != '\0'){
  114.                 LCD1602_Write(*str++);
  115.         //_delay_us(2);
  116.         }
  117.         *str = 0;
  118. }
  119. /********************************************************************************************
  120. // 打印单字符程序 //
  121. /********************************************************************************************/
  122. /*
  123. void print_char(uint8 a,uint8 t){
  124.         LCD1602_WriteCMD(a | 0x80);
  125.         LCD1602_Write(t);
  126. }*/
  127. void main(void)
  128. {
  129.     P2M0 = 0x00;
  130.     P2M1 = 0x00;
  131.     LCD1602_Init();
  132.         print_str(0x80,"Hi  stcaimcu.com");
  133.     Delay1ms(1);
  134.          print_str(0xC0,"0123456789ABCDEF");
  135.   // Write your code here
  136.    while (1){
  137.          //print_str(0xC0,"0123456789ABCDEF");
  138.     }
  139.       
  140. }
复制代码





回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-05-02 00:29:54

10

主题

1159

回帖

5121

积分

论坛元老

积分
5121
发表于 2023-2-11 22:36:27 | 显示全部楼层
STC8H8K64U转STC89-打狗棒  使用2位数据线做控制 LCD1602  用 HC164 的串行输入控制 扩展输出 8位

STC8H8K64U转STC89-打狗棒

STC8H8K64U转STC89-打狗棒

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15613
发表于 2023-2-11 22:51:50 | 显示全部楼层
I/O 不够,可以 用 开天斧-STC8H8K64U-45MHz-LQFP64转DIP64



1.png
深圳国芯人工智能有限公司-核心功能实验板 (stcai.com)
  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-05-02 00:29:54

10

主题

1159

回帖

5121

积分

论坛元老

积分
5121
发表于 2023-6-5 08:05:20 | 显示全部楼层
神*** 发表于 2023-2-11 22:51
I/O 不够,可以 用 开天斧-STC8H8K64U-45MHz-LQFP64转DIP64

不是每个项目都可以用这么多 I/O 的单片机。
这里给的是,怎么用最少的I/O脚来控制LCD1602液晶显示。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15613
发表于 2023-6-5 11:26:36 | 显示全部楼层
应该有 SPI-LCD12864,  SPI-LCD1602
应该有 I2C-LCD12864,  I2C-LCD1602

1.png


1.png

1.png


1.png









回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2023-6-5 15:10:06 | 显示全部楼层
使用I2C接口的OLED或LCD1602,2线即可。74HC164输出时,每一个输出都会“闪烁”一下,一般建议使用有锁存功能的74HC595来扩展IO输出,3线即可,可以多片级联。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 06:23 , Processed in 0.124822 second(s), 85 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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