1. 程式人生 > 其它 >51微控制器通過DHT11溫度感測器讀取溫度(3)

51微控制器通過DHT11溫度感測器讀取溫度(3)

一.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 void
lcd_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”
}