找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2963|回復(fù): 12
打印 上一主題 下一主題
收起左側(cè)

單片機LCD1602非阻塞顯示程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:744809 發(fā)表于 2023-5-24 23:30 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
    今天看到一個論壇提問,怎么防止lcd1602的忙判斷導(dǎo)致的阻塞,進而影響其他程序的運行。特此寫了一下代碼,該代碼在stm32f1 72M情況下運行時間大概十幾微妙,51單片機環(huán)境下應(yīng)該會更久一下,沒辦法,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. 函數(shù)聲明
  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
復(fù)制代碼
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)
復(fù)制代碼
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. //主函數(shù)
  16. int main( void )
  17. {
  18.     idata float disTemp[4] = {0};
  19.     idata unsigned char display_buf[16];//顯示數(shù)組
  20.     idata unsigned int display_len;//顯示數(shù)據(jù)長度

  21.     Timer0Init();
  22.     MngLCD1602_Init();//LCD1602初始化
  23.     EA = 1;
  24.     while( 1 )
  25.     {
  26.         if(1 == _100ms_flag)
復(fù)制代碼
Keil代碼與Proteus7.8仿真下載:: keil.zip (135.3 KB, 下載次數(shù): 42)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:1064915 發(fā)表于 2023-5-25 10:35 | 只看該作者
注釋太少,奧妙在哪,求前輩科普
回復(fù)

使用道具 舉報

板凳
ID:584814 發(fā)表于 2023-5-31 08:32 | 只看該作者
不知道奧妙在哪里,自己實際用時可以不判忙。
回復(fù)

使用道具 舉報

地板
ID:996773 發(fā)表于 2023-5-31 10:14 | 只看該作者
沒看懂,1602我也一直用很熟悉,不用判斷忙。51單片機再怎么弱也不用一直伺候它,

完全可以干其他事情
回復(fù)

使用道具 舉報

5#
ID:744809 發(fā)表于 2023-6-1 17:25 | 只看該作者
hi等你 發(fā)表于 2023-5-31 10:14
沒看懂,1602我也一直用很熟悉,不用判斷忙。51單片機再怎么弱也不用一直伺候它,

完全可以干其他事情

別的性能好一些的單片機就要判忙了
回復(fù)

使用道具 舉報

6#
ID:390416 發(fā)表于 2023-6-1 18:09 | 只看該作者
http://www.torrancerestoration.com/bbs/dpj-228933-1.html
這個帖子里面 有LCD1602使用詳細說明,這玩意就是個慢東西 沒必要判忙
回復(fù)

使用道具 舉報

7#
ID:744809 發(fā)表于 2023-6-2 14:00 | 只看該作者
人人學(xué)會單片機 發(fā)表于 2023-6-1 18:09
http://www.torrancerestoration.com/bbs/dpj-228933-1.html
這個帖子里面 有LCD1602使用詳細說明,這玩意就是個慢東西  ...

就是因為慢才要判忙啊,STM32單片機執(zhí)行太快了,51是不用判忙
回復(fù)

使用道具 舉報

8#
ID:69115 發(fā)表于 2023-6-2 20:46 | 只看該作者
確實不需要判斷忙,更不用等待.寫或讀1602之后,MCU是要去干一些別的事,過一會再來后續(xù)的寫或是讀.可以在定時中斷里分時分步處理,也可以在主程序里,在大循環(huán)中分階段處理.
回復(fù)

使用道具 舉報

9#
ID:390416 發(fā)表于 2023-6-3 11:33 | 只看該作者
123156fsadf 發(fā)表于 2023-6-2 14:00
就是因為慢才要判忙啊,STM32單片機執(zhí)行太快了,51是不用判忙

lcd1602 寫一條指令后,需要等40us 才能寫數(shù)據(jù)。要是STM32 可以執(zhí)行幾百條指令了。要是STM32來寫LCD,最佳方式就是刷數(shù)組內(nèi)容 ,第一條寫指令,后面32字節(jié)  都是寫數(shù)據(jù),并且把這32字節(jié) 分別在某個時間點寫入
比如 每隔1ms 寫入一個字符,寫完后CPU立馬去干別的事情。這樣寫 就不需要判盲。也就不存在浪費CPU性能的情況了
回復(fù)

使用道具 舉報

10#
ID:744809 發(fā)表于 2023-6-7 14:58 | 只看該作者
人人學(xué)會單片機 發(fā)表于 2023-6-3 11:33
lcd1602 寫一條指令后,需要等40us 才能寫數(shù)據(jù)。要是STM32 可以執(zhí)行幾百條指令了。要是STM32來寫LCD,最 ...

我的代碼不就是這樣實現(xiàn)的么
回復(fù)

使用道具 舉報

11#
ID:275826 發(fā)表于 2023-9-23 08:56 | 只看該作者
樓主程序思路很好;但程序?qū)懙膹?fù)雜了,有很簡單的寫法
回復(fù)

使用道具 舉報

12#
ID:326261 發(fā)表于 2023-9-26 08:57 | 只看該作者
作為你看到的論壇那個問題發(fā)起人,來回答一下目前的現(xiàn)狀
如果使用STM32芯片,芯片越好,兼容操作系統(tǒng),程序體量大了之后,你是不能實時1ms去伺服這個LCD1602的程序的,比如你要去做高優(yōu)先級的程序,可能幾個ms才能輪到LCD1602,又因為LCD1602沒有顯示緩存,就會導(dǎo)致LCD1602顯示一個一個跳出來。
所以要么用二級芯片控制,要么你用51單片機開發(fā)LCD1602。
目前我也在考慮辦法。
回復(fù)

使用道具 舉報

13#
ID:458247 發(fā)表于 2023-12-11 19:27 | 只看該作者
工學(xué)院陳偉霆 發(fā)表于 2023-9-26 08:57
作為你看到的論壇那個問題發(fā)起人,來回答一下目前的現(xiàn)狀
如果使用STM32芯片,芯片越好,兼容操作系統(tǒng),程 ...

我這個程序運行周期才十幾微妙,如果168MHz的話十微秒不到,如果顯示實時性要求很高,完全可以把它放在定時器中斷里面每1ms執(zhí)行一次
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表