标题: 单片机LCD1602非阻塞显示程序 [打印本页]

作者: 123156fsadf    时间: 2023-5-24 23:30
标题: 单片机LCD1602非阻塞显示程序
    今天看到一个论坛提问,怎么防止lcd1602的忙判断导致的阻塞,进而影响其他程序的运行。特此写了一下代码,该代码在stm32f1 72M情况下运行时间大概十几微妙,51单片机环境下应该会更久一下,没办法,51性能比较弱。
    代码分为lcd1602.c、lcd1602.h、以及main.c(主要演示下怎么使用该代码。)
    lcd1602.h如下所示。
  1. #ifndef __LCD1602_H_
  2. #define __LCD1602_H_

  3. /**********************************
  4. 包含头文件
  5. **********************************/
  6. #include <REGX52.H>

  7. typedef unsigned long uint32_t;
  8. typedef unsigned int  uint16_t;
  9. typedef unsigned char uint8_t;

  10. /**********************************
  11. PIN口定义
  12. **********************************/
  13. #define LCD1602_DATAPINS P0
  14. sbit LCD1602_RS = P2 ^ 6;
  15. sbit LCD1602_RW = P2 ^ 5;
  16. sbit LCD1602_E = P2 ^ 7;

  17. /**********************************
  18. 函数声明
  19. **********************************/
  20. extern void MngLCD1602_Init( void );
  21. extern void MngLCD1602_Handle( void );
  22. extern void displayString( uint8_t x, uint8_t y, uint8_t* dat, uint8_t len);
  23. #endif
复制代码
lcd1602.c如下所示
  1. #include "lcd1602.h"
  2. #include <string.h>

  3. #define LCD1602_ROW_NUM         2u
  4. #define LCD1602_COLUMN_NUM      16u

  5. #define LCD1602_READ_DATA()     (LCD1602_DATAPINS)
  6. #define LCD1602_WRITE_DATA(dat) (LCD1602_DATAPINS = (uint8_t)dat)
  7. #define LCD1602_SET_RS_H()      (LCD1602_RS = 1)
  8. #define LCD1602_SET_RS_L()      (LCD1602_RS = 0)

  9. #define LCD1602_SET_RW_H()      (LCD1602_RW = 1)
  10. #define LCD1602_SET_RW_L()      (LCD1602_RW = 0)

  11. #define LCD1602_SET_E_H()       (LCD1602_E = 1)
  12. #define LCD1602_SET_E_L()       (LCD1602_E = 0)
复制代码
main.c
  1. #include <REGX52.H>
  2. #include <stdio.h>
  3. #include "lcd1602.h"

  4. #define MAIN_FOSC_DELAY 12000000UL

  5. #define T1MS_0 (65536-MAIN_FOSC_DELAY/12/1000)   //1ms timer calculation method in 12T mode
  6. #define T1MS_1 (65536-MAIN_FOSC_DELAY/12/1000)   //1ms timer calculation method in 12T mode
  7. #define TIMER_MODE0     0x00
  8. #define TIMER_MODE1     0x01
  9. #define TIMER_MODE2     0x02
  10. #define TIMER_MODE3     0x03

  11. static bit _1_ms_flag = 0;    //1ms标志位
  12. static bit _100ms_flag = 0;   //100ms标志位
  13. static bit _500ms_flag = 0;  //500ms标志位

  14. static void Timer0Init( void );

  15. //主函数
  16. int main( void )
  17. {
  18.     idata float disTemp[4] = {0};
  19.     idata unsigned char display_buf[16];//显示数组
  20.     idata unsigned int display_len;//显示数据长度

  21.     Timer0Init();
  22.     MngLCD1602_Init();//LCD1602初始化
  23.     EA = 1;
  24.     while( 1 )
  25.     {
  26.         if(1 == _100ms_flag)
复制代码
Keil代码与Proteus7.8仿真下载:: keil.zip (135.3 KB, 下载次数: 42)

作者: joyb    时间: 2023-5-25 10:35
注释太少,奥妙在哪,求前辈科普
作者: man1234567    时间: 2023-5-31 08:32
不知道奥妙在哪里,自己实际用时可以不判忙。
作者: hi等你    时间: 2023-5-31 10:14
没看懂,1602我也一直用很熟悉,不用判断忙。51单片机再怎么弱也不用一直伺候它,

完全可以干其他事情
作者: 123156fsadf    时间: 2023-6-1 17:25
hi等你 发表于 2023-5-31 10:14
没看懂,1602我也一直用很熟悉,不用判断忙。51单片机再怎么弱也不用一直伺候它,

完全可以干其他事情

别的性能好一些的单片机就要判忙了
作者: 人人学会单片机    时间: 2023-6-1 18:09
http://www.51hei.com/bbs/dpj-228933-1.html
这个帖子里面 有LCD1602使用详细说明,这玩意就是个慢东西 没必要判忙
作者: 123156fsadf    时间: 2023-6-2 14:00
人人学会单片机 发表于 2023-6-1 18:09
http://www.51hei.com/bbs/dpj-228933-1.html
这个帖子里面 有LCD1602使用详细说明,这玩意就是个慢东西  ...

就是因为慢才要判忙啊,STM32单片机执行太快了,51是不用判忙
作者: xiexugang    时间: 2023-6-2 20:46
确实不需要判断忙,更不用等待.写或读1602之后,MCU是要去干一些别的事,过一会再来后续的写或是读.可以在定时中断里分时分步处理,也可以在主程序里,在大循环中分阶段处理.
作者: 人人学会单片机    时间: 2023-6-3 11:33
123156fsadf 发表于 2023-6-2 14:00
就是因为慢才要判忙啊,STM32单片机执行太快了,51是不用判忙

lcd1602 写一条指令后,需要等40us 才能写数据。要是STM32 可以执行几百条指令了。要是STM32来写LCD,最佳方式就是刷数组内容 ,第一条写指令,后面32字节  都是写数据,并且把这32字节 分别在某个时间点写入
比如 每隔1ms 写入一个字符,写完后CPU立马去干别的事情。这样写 就不需要判盲。也就不存在浪费CPU性能的情况了
作者: 123156fsadf    时间: 2023-6-7 14:58
人人学会单片机 发表于 2023-6-3 11:33
lcd1602 写一条指令后,需要等40us 才能写数据。要是STM32 可以执行几百条指令了。要是STM32来写LCD,最 ...

我的代码不就是这样实现的么
作者: tyrl800    时间: 2023-9-23 08:56
楼主程序思路很好;但程序写的复杂了,有很简单的写法
作者: 工学院陈伟霆    时间: 2023-9-26 08:57
作为你看到的论坛那个问题发起人,来回答一下目前的现状
如果使用STM32芯片,芯片越好,兼容操作系统,程序体量大了之后,你是不能实时1ms去伺服这个LCD1602的程序的,比如你要去做高优先级的程序,可能几个ms才能轮到LCD1602,又因为LCD1602没有显示缓存,就会导致LCD1602显示一个一个跳出来。
所以要么用二级芯片控制,要么你用51单片机开发LCD1602。
目前我也在考虑办法。
作者: yzw846562238    时间: 2023-12-11 19:27
工学院陈伟霆 发表于 2023-9-26 08:57
作为你看到的论坛那个问题发起人,来回答一下目前的现状
如果使用STM32芯片,芯片越好,兼容操作系统,程 ...

我这个程序运行周期才十几微妙,如果168MHz的话十微秒不到,如果显示实时性要求很高,完全可以把它放在定时器中断里面每1ms执行一次




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1