找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3764|回复: 0
打印 上一主题 下一主题
收起左侧

[单片机LCD驱动程序分享] LCD1602时间显示

[复制链接]
跳转到指定楼层
楼主
LCD1602 时间显示

Proteus




AT89C51单片机源程序如下:
main.c
  1. /**
  2. * @file main.c
  3. * @author Kiyotaka
  4. * @brief Unix timestamp on LCD1602
  5. * @version 0.1
  6. * @date 2019-12-08
  7. *
  8. * @copyright Copyright (c) 2019
  9. *
  10. */
  11. #include "main.h"
  12. #include "lcd1602.h"

  13. void Delay1000ms(void);

  14. unsigned long int timestamp = 157579655;

  15. int main(void) {
  16.   LCD1602_Init();
  17.   LCD1602_Printf(0, 0, "Unix timestamp:");
  18.   while (1) {
  19.     LCD1602_Printf(0, 1, "%ld", timestamp++);
  20.     Delay1000ms();
  21.   }
  22. }

  23. void Delay1000ms(void) {  //@12.000MHz

  24.   unsigned char i = 8;
  25.   unsigned char j = 154;
  26.   unsigned char k = 122;

  27.   _nop_();
  28.   do {
  29.     do {
  30.       while (--k);
  31.     } while (--j);
  32.   } while (--i);
  33. }
复制代码

lcd1602.c
  1. /**
  2. * @file lcd1602.c
  3. * @author Kiyotaka
  4. * @brief LCD1602 driver
  5. * @version 0.1
  6. * @date 2019-12-08
  7. *
  8. * @copyright Copyright (c) 2019
  9. *
  10. */
  11. #include "lcd1602.h"

  12. typedef enum { GPIO_PIN_RESET = 0, GPIO_PIN_SET } GPIO_PinState;

  13. #define RS_CMD GPIO_PIN_RESET
  14. #define RS_DATA GPIO_PIN_SET

  15. /**
  16. * @brief 延时函数
  17. *
  18. * @param us 延时时间
  19. * @return None
  20. */
  21. static void Delay(int us) {
  22.   while (us-- > 0) {
  23.     _nop_();
  24.   }
  25. }

  26. /**
  27. * @brief 液晶I/O 口复位
  28. *
  29. * @return None
  30. */
  31. static void PinReset(void) {
  32.   LCD1602_E_Pin = GPIO_PIN_RESET;
  33.   LCD1602_RS_Pin = GPIO_PIN_RESET;
  34.   LCD1602_RW_Pin = GPIO_PIN_RESET;
  35.   LCD1602_Port = 0xFF;
  36. }

  37. /**
  38. * @brief LCD1602 等待液晶空闲
  39. *
  40. *@return None
  41. */
  42. static void WaitIdleTime(void) {
  43.   LCD1602_RS_Pin = RS_CMD;
  44.   LCD1602_RW_Pin = GPIO_PIN_SET;
  45.   LCD1602_Port = 0x00;
  46.   LCD1602_E_Pin = GPIO_PIN_SET;
  47.   do {
  48.     Delay(100);
  49.   } while ((LCD1602_Port & 0x80) >> 7);
  50.   PinReset();
  51. }

  52. /**
  53. * @brief LCD1602 写数据/指令函数
  54. *
  55. * @param val 8位数据
  56. * @param is_data true 是数据, false 是指令
  57. * @return None
  58. */
  59. static void Write(unsigned char val, bit is_data) {
  60.   bit interrupt_stat = EA;

  61.   EA = 0;
  62.   WaitIdleTime();
  63.   LCD1602_RS_Pin = is_data;
  64.   LCD1602_Port = val;
  65.   LCD1602_E_Pin = GPIO_PIN_SET;
  66.   Delay(100);
  67.   PinReset();
  68.   EA = interrupt_stat;
  69. }

  70. /**
  71. * @brief LCD1602 初始化
  72. *
  73. * @return None
  74. */
  75. void LCD1602_Init(void) {
  76.   PinReset();
  77.   Write(0x38, RS_CMD);
  78.   Write(0x0C, RS_CMD);
  79.   Write(0x06, RS_CMD);
  80.   Write(0x01, RS_CMD);
  81. }

  82. /**
  83. * @brief LCD1602 显示函数
  84. *
  85. * @param addr_x (0~15) 横坐标
  86. * @param addr_y (0~1) 纵坐标
  87. * @param fmt 格式化字符串
  88. * @param ...
  89. * @return int
  90. */
  91. int LCD1602_Printf(int addr_x, int addr_y, const char *fmt, ...) {
  92.   char buf[20] = {0};
  93.   char *p = buf;
  94.   int ret = 0;
  95.   va_list args;

  96.   va_start(args, fmt);
  97.   ret = vsprintf(p, fmt, args);
  98.   va_end(args);

  99.   Write(0x80 + 0x40 * addr_y + addr_x, RS_CMD);
  100.   while (*p != '\0') {
  101.     if (*p == '\f') {
  102.       Write(0x01, RS_CMD);
  103.     } else if (isprint(*p) != 0) {
  104.       Write(*p, RS_DATA);
  105.     }
  106.     p++;
  107.   }

  108.   return ret;
  109. }
复制代码


驱动程序(Keil + Proteus)
lcd1602.zip (47.8 KB, 下载次数: 24)

如果注释为乱码,Keil的Encoding设置成UTF-8


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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