51微控制器通過DHT11溫度感測器讀取溫度(3)
阿新 • • 發佈:2022-04-01
一.LCD1602的初始化
1.延時15ms
2.寫指令38H(不檢測忙訊號)
3.延時5ms
4.以後每次寫指令,讀/寫資料操作均需要檢測忙訊號
5.寫指令38h:顯示模式設定
6.寫指令08h:顯示關閉
7.寫指令01h:顯示清屏
8.寫指令06h:顯示游標移動設定
9.寫指令0ch:顯示開及游標設定
相關程式碼
1 #include <REGX52.H> 2 #include "intrins.h" 3 sbit RS = P1^0; 4 sbit RW = P1^1; 5 sbit E = P1^2; 6 #define data_buffer P0 7 /* 8 用於讀取LCD1602的忙碌狀態9 */ 10 11 void Delay15ms() //@11.0592MHz 12 { 13 unsigned char i, j; 14 15 i = 27; 16 j = 226; 17 do 18 { 19 while (--j); 20 } while (--i); 21 } 22 void Delay5ms() //@11.0592MHz 23 { 24 unsigned char i, j; 25 26 i = 9; 27 j = 244; 28 do 29 {30 while (--j); 31 } while (--i); 32 } 33 34 void check_lcd_busy() 35 { 36 char tep = 0x80; 37 data_buffer = 0x80; 38 while(tep & 0x80) 39 { 40 RS = 0; 41 RW = 1; 42 E = 0; 43 _nop_(); 44 E = 1; 45 _nop_(); 46 tep = data_buffer; 47 } 48 } 49 voidlcd_write_cmd(char cmd) 50 { 51 check_lcd_busy(); 52 RS = 0; 53 RW = 0; 54 E = 0; 55 data_buffer = cmd; 56 _nop_(); 57 E = 1; 58 _nop_(); 59 E = 0; 60 _nop_(); 61 } 62 void lcd_write_data(char datashow) 63 { 64 check_lcd_busy(); 65 RS = 1; 66 RW = 0; 67 E = 0; 68 data_buffer = datashow; 69 _nop_(); 70 E = 1; 71 _nop_(); 72 E = 0; 73 _nop_(); 74 } 75 void lcd_start() 76 { 77 Delay15ms(); 78 lcd_write_cmd(0x38); 79 Delay5ms(); 80 lcd_write_cmd(0x38); 81 lcd_write_cmd(0x08); 82 lcd_write_cmd(0x01); 83 lcd_write_cmd(0x06); 84 lcd_write_cmd(0x0c); 85 }
二.通過lcd1602顯示一個字元
要求通過lcd1602顯示字元“A”
分析:需要在螢幕上顯示出資格字元,需要將顯示的位置、顯示的內容給螢幕,所以可以寫出如下的程式碼
#include "reg52.h" #include "intrins.h" /* RS -- P1.0 RW -- P1.1 E -- P1.4 */ #define databuffer P0 //定義8位資料線,Po埠組 sbit RS = P1^0; sbit RW = P1^1; sbit EN = P1^4; void check_busy() { char tmp = 0x80; databuffer = 0x80; while(tmp & 0x80){//1000 0000 RS = 0; RW = 1; EN = 0; _nop_(); EN = 1; _nop_(); _nop_(); tmp = databuffer; EN = 0; _nop_(); } } void Write_Cmd_Func(char cmd) { check_busy(); RS = 0; RW = 0; EN = 0; _nop_(); databuffer = cmd; _nop_(); EN = 1; _nop_(); _nop_(); EN = 0; _nop_(); } void Write_Data_Func(char dataShow) { check_busy(); RS = 1; RW = 0; EN = 0; _nop_(); databuffer = dataShow; _nop_(); EN = 1; _nop_(); _nop_(); EN = 0; _nop_(); } void Delay15ms() //@11.0592MHz { unsigned char i, j; i = 27; j = 226; do { while (--j); } while (--i); } void Delay5ms() //@11.0592MHz { unsigned char i, j; i = 9; j = 244; do { while (--j); } while (--i); } void LCD1602_INIT() { //(1)延時 15ms Delay15ms(); //(2)寫指令 38H(不檢測忙訊號) Write_Cmd_Func(0x38); //(3)延時 5ms Delay5ms(); //(4)以後每次寫指令,讀/寫資料操作均需要檢測忙訊號 //(5)寫指令 38H:顯示模式設定 Write_Cmd_Func(0x38); //(6)寫指令 08H:顯示關閉 Write_Cmd_Func(0x08); //(7)寫指令 01H:顯示清屏 Write_Cmd_Func(0x01); //(8)寫指令 06H:顯示游標移動設定 Write_Cmd_Func(0x06); //(9)寫指令 0CH:顯示開及游標設定} Write_Cmd_Func(0x0c); } void main() { char position = 0x80 + 0x05; char dataShow = 'C'; LCD1602_INIT(); Write_Cmd_Func(position);//選擇要顯示的地址 Write_Data_Func(dataShow);//傳送要顯示的字元 }
三.通過lcd1602顯示一行字元
分析:如果需要通過LCD1602顯示一行字元,則需要定義出每一行的開始字元位置,比如,第一行從第五列開始顯示,第二行開始從第一列顯示,這樣就可以通過LCD1602顯示不同的字串,根據以上要求可以寫出如下的程式碼
#include <REGX52.H> #include "intrins.h" sbit RS = P1^0; sbit RW = P1^1; sbit E = P1^2; #define data_buffer P0 /* 用於讀取LCD1602的忙碌狀態 */ void Delay15ms() //@11.0592MHz { unsigned char i, j; i = 27; j = 226; do { while (--j); } while (--i); } void Delay5ms() //@11.0592MHz { unsigned char i, j; i = 9; j = 244; do { while (--j); } while (--i); } void check_lcd_busy() { char tep = 0x80; data_buffer = 0x80; while(tep & 0x80) { RS = 0; RW = 1; E = 0; _nop_(); E = 1; _nop_(); tep = data_buffer; } } void lcd_write_cmd(char cmd) { check_lcd_busy(); RS = 0; RW = 0; E = 0; data_buffer = cmd; _nop_(); E = 1; _nop_(); E = 0; _nop_(); } void lcd_write_data(char datashow) { check_lcd_busy(); RS = 1; RW = 0; E = 0; data_buffer = datashow; _nop_(); E = 1; _nop_(); E = 0; _nop_(); } void lcd_start() { Delay15ms(); lcd_write_cmd(0x38); Delay5ms(); lcd_write_cmd(0x38); lcd_write_cmd(0x08); lcd_write_cmd(0x01); lcd_write_cmd(0x06); lcd_write_cmd(0x0c); } void lcd1602_showlines(char row,char line ,char *string) //定義三個形式引數,分別表示行、列和字串 { switch(row) { case 1: lcd_write_cmd(0x80 + line); while(*string) { lcd_write_data(*string); string++; } break; case 2: lcd_write_cmd(0x80 + 0x04 + line); while(*string) { lcd_write_data(*string); string++; } break; } } void main() { lcd_start(); lcd1602_showlines(1,3,"NO.1"); //通過第一行第三列開始顯示內容“NO.1” lcd1602_showlines(2,0,"UP handsome"); //通過第二行第一列開始顯示內容“UP handsome” }