久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

AVR 單片機學習筆記–LCD1602模塊

作者:佚名   來源:本站原創   點擊數:  更新時間:2013年10月21日   【字體:

學完51單片機再來學AVR,感覺很容易上手,LCD1602在學51的時候學過,所以可以直接修改相關的IO口操作即可。現在順便也復習一下。1602可以顯示兩行字符,每行可以顯示16個字符,可惜的是不能顯示中文,在我調試的時候它幫我不少的忙。

一、主要技術參數:

顯示容量:            16X2個字符(兩行,每行16個字符)
       模塊工作電源:              4.5~5.5V
       模塊工作電流:              2.0mA (5.0V)
       模塊最佳工作電源:        5.0V
       字符尺寸:                     2.95X4.35(WXH)mm

二、IO引腳功能

LCD1602A模塊引腳功能

編號

符號

引腳說明

編號

符號

引腳說明

1

VSS

電源地(模塊供電)

9

D2

Data I/O

2

VDD

電源正極(模塊供電)

10

D3

Data I/O

3

VL

接在滑動電阻可以調節對比度

11

D4

Data I/O

4

RS

數據/命令選擇端 (H/L)

12

D5

Data I/O

5

R/W

讀/寫選擇端 (H/L)

13

D6

Data I/O

6

E

使能信號(通知芯片讀取數據)

14

D7

Data I/O

7

D0

Data I/O

15

BLA

模塊背光燈正極

8

D1

Data I/O

16

BLK

模塊背光燈負極

 

三、基本操作時序:

讀狀態:輸入:RS=L、RW=H、E=H                    模塊輸出:狀態字=D0~D7
       寫指令:輸入:RS=L、RW=L、D0~D7=指令碼、E=H       模塊輸出:無
       讀數據:輸入:RS=H、RW=H、E=H                               模塊輸出:數據=D0~D7
       寫數據:輸入:RS=H、RW=L、D0~D7=數據、E=H          模塊輸出:無

 狀態字說明(因為單片機的速度可能快過1602,所以需要判斷當1602是否在忙,或者延時。)

STA7

STA6

STA5

STA4

STA3

STA2

STA1

STA0

D7

D6

D5

D4

D3

D2

D1

D0

STA0-6:當前數據地址指針的數值

STA7

主要用來檢查1602模塊的是否可以寫入或讀出操作

1:禁止  0:允許

               

 

四、指令說明(這指令是用來設置1602顯示的方式)

顯示模式設置

指令碼

功能

0

0

1

1

1

0

0

0

設置16X2顯示,5X7點陣,8位數據接口

                 

 

顯示開/關及光標設置

指令碼

功能

0

0

0

0

1

D

C

B

D=1 開顯示         D=0 關顯示
C=1 顯示光標       C=0 不顯示光標
B=1 光標閃爍       B=0 光標不閃爍

0

0

0

0

0

1

N

S

N=1 當讀或寫一個字符后地址指針加1,且光
     標加1(即從左往右顯示)
N=0 當讀或寫一個字符后地址指針減1,且光
     標減1(即從右往左顯示)
S=1 當寫一個字符,中國男排顯示左移(N=1)

                 

 

五、時序圖

 

 
 

 


寫操作(寫指令、寫數據)時序圖

 


時序參數

寫指令時序,RS拉低表示寫指令,R/W拉低表示寫操作,給DB0-DB7賦值指令數據并保持>40ns時間,將E拉高表示數據已經準備好保持>150ns讓1602讀取,將E拉低,并延時>10ns一次寫操作完畢。

寫數據時序,RS拉高表示寫數據,R/W拉低表示寫操作,給DB0-DB7賦值指令數據并保持>40ns時間,將E拉高表示數據已經準備好保持>150ns讓1602讀取,將E拉低,并延時>10ns一次寫操作完畢。 

六、電路圖 
    
 

由于只是寫操作,所以R/W直接接地即可。 

PORTA接1602的8位數據引腳

PORTD5接1602的RS引腳 區分數據或命令:H數據,L命令

    PORTD4接1602的E引腳 高脈沖使能,使能脈寬最小150ns 

 

七、完整代碼。

// 代碼功能:驅動LCD1602顯示屏
// 平臺:DB-51 Ver2.1開發板
// 控制芯片:ATmega16A
// 時鐘:片內時鐘
// 設計者:L、QQ:1007566569
//                2013-8-10
//*************************************** 包含必備文件 *******************************************************
#ifndef _STRING_H
   #include "string.h"
#endif

#ifndef uchar         
   #define uchar unsigned char
#endif                 

#ifndef uint
   #define uint  unsigned int
#endif

//*************************************** 移植必須修改 *******************************************************

// 共占用 PORTA一組IO 、PORTD中第4、5 IO  由于只是寫操作,所以R/W直接接地即可。 

#define _1602_DATA        PORTA   // 接1602的8位數據引腳
#define _1602_CMDIO       PORTD   // 控制線所對應的IO口
#define _1602_CMDIO_RS    5       // 接1602的RS引腳 區分數據或命令:H數據,L命令
#define _1602_CMDIO_E     4       // 接1602的E引腳 高脈沖使能,使能脈寬最小150ns 

/**************************************************
設計者:L、QQ:1007566569
函數:自定義函數 void My_SetBit(unsigned char *Date, unsigned char Wei, unsigned char ms)
參數:Date:寄存器地址 Wei:更改指定位 ms:若為1則將指定位置1 若為0則將指定位置0
返回值:無返回值,函數里面會更改寄存器值
例子:My_SetBit((unsigned char*)&PORTB, 2, 1); 將PORTB寄存器中的第2位置1
函數描述:
    修改指定寄存器中的指定位,不影響其他位。
**************************************************/
/*** 第二版本 ***/
void My_SetBit(unsigned char *Date, unsigned char Wei, unsigned char ms)
{
   (((ms) == (0)) ? (*Date &= ~(0x1<<Wei)) : (*Date |= (0x1<<Wei)));
}

/* 延時函數 */
void delay_50us_1602(unsigned int x)
{  
   unsigned char y;
   for(;x>0;x--)
      for(y=19;y>0;y--);
}

/* 寫入指定命令 由于是寫操作 R/W 可以直接接地保持低電平即可*/
void lcdwrcom_1602(unsigned char cdat)
{  
   My_SetBit((unsigned char*)&_1602_CMDIO, _1602_CMDIO_E, 0);      // E置0,即將改變數據。不允許1602讀取數據(IO口狀態)
   My_SetBit((unsigned char*)&_1602_CMDIO, _1602_CMDIO_RS, 0);      // RS拉低 表示是命令
   _1602_DATA = cdat;                                    // 將命令送至與1602的8位數據口相連接的IO口              
   delay_50us_1602(4);                                    // 數據建立時間要 >40ns
   My_SetBit((unsigned char*)&_1602_CMDIO, _1602_CMDIO_E, 1);      // E使能,命令已經準備好,通知1602讀取命令(IO口狀態)
   delay_50us_1602(8);                                    // E高電平保持時間要 >150ns,讓1602有時間讀取完整
   My_SetBit((unsigned char*)&_1602_CMDIO, _1602_CMDIO_E, 0);      // E置0,不允許1602讀取數據(IO口狀態)可能改變。
   delay_50us_1602(2);                                    // 根據時序圖,讓數據再保持一小段時間 >10ns
}
/* 將指定數據寫入顯示屏 由于是寫操作 R/W 可以直接接地保持低電平即可*/
void lcdwrdata_1602(unsigned char dat)
{  
   My_SetBit((unsigned char*)&_1602_CMDIO, _1602_CMDIO_E, 0);      // E置0,即將改變數據。不允許1602讀取數據(IO口狀態)
   My_SetBit((unsigned char*)&_1602_CMDIO, _1602_CMDIO_RS, 1);      // RS拉高 表示是數據
   _1602_DATA = dat;                                    // 將命令送至與1602的8位數據口相連接的IO口              
   delay_50us_1602(4);                                    // 數據建立時間要 >40ns
   My_SetBit((unsigned char*)&_1602_CMDIO, _1602_CMDIO_E, 1);      // E使能,命令已經準備好,通知1602讀取命令(IO口狀態)
   delay_50us_1602(8);                                    // E高電平保持時間要 >150ns,讓1602有時間讀取完整
   My_SetBit((unsigned char*)&_1602_CMDIO, _1602_CMDIO_E, 0);      // E置0,不允許1602讀取數據(IO口狀態)可能改變。
   delay_50us_1602(2);                                    // 根據時序圖,讓數據再保持一小段時間 >10ns                                 // 根據時序圖,讓數據保持一小段時間
}

/* 初始化 1602 */
void lcd_init_1602()
{   // 具體含義請參考 1602官方使用手冊
   lcdwrcom_1602(0x38);//0x38設置顯示模式為:16X2 顯示,5X7 點陣,8 位數據接口
   lcdwrcom_1602(0x0C);//打開顯示光標閃爍
   lcdwrcom_1602(0x06);//顯示光標移動設置
   lcdwrcom_1602(0x01);//顯示清屏    
}

/* 綜合函數 API */
/* 參數:Show_1602(第一行顯示的數據, 第二行顯示的數據, 每個字符顯示的時間)*/
void Show_1602(unsigned char Text_1[], unsigned char Text_2[], unsigned int Time)
{
   unsigned char n;
   unsigned int Tmp;
   unsigned char TmpA, TmpC, TmpD;
  
   // 備份IO口原來的配置以備復原,避免影響其他模塊代碼
   TmpA = DDRA;  
   TmpC = DDRC;
   TmpD = DDRD;
   // 端口初始化
   DDRA = 0xFF;     
   DDRC = 0xC0;
   DDRD = 0x30;

   // 1602 初始化
   lcd_init_1602();
  
   lcdwrcom_1602(0x80+0x00);         // 設置要顯示(寫入)的位置 0x80-0x8F 第一行的位置
   Tmp = strlen(Text_1);      
   if(Tmp)
   {
      for(n=0; n<Tmp; n++)
      {
         lcdwrdata_1602(Text_1[n]);   // 一個字節一個字節寫入
         delay_50us_1602(Time);      // 延時指定時間 可以達到一個字符一個字符慢慢依次顯示的效果
      }
   }

   lcdwrcom_1602(0x80+0x40);         // 設置要顯示(寫入)的位置 0xC0-0xCF 第二行的位置  
   Tmp = strlen(Text_2);
   if(Tmp)
   {
      for(n=0; n<Tmp; n++)
      {
         lcdwrdata_1602(Text_2[n]);   // 一個字節一個字節寫入
         delay_50us_1602(Time);      // 延時指定時間 可以達到一個字符一個字符慢慢依次顯示的效果
      }
   }
  
   // 恢復端口原來的設置避免影響其他模塊的使用。
   DDRA = TmpA;
   DDRC = TmpC;
   DDRD = TmpD;
}

/*  寫完這個函數后,靈光一現!擦,被誤導了!霖鋒老師和郭天祥老師是不是都寫懵
   了,搞那么復雜,靠 一個 sprintf 就能搞定。
void Show_1602_Int(unsigned int Shuzi, unsigned int Time)
{
   unsigned char Tdate[]="0123456789";
   char Text[33] = {0};
   unsigned int Tmp;
   unsigned int Weishu = 10;
   char Textlen = 0;

   // 判斷位數 ↓
   if(Shuzi < 10 )                        // 如果是一位數 則不必拆分 直接引用
   {
      Text[Textlen] = Tdate[Shuzi];
      Show_1602_Char(Text, "", Time);
      return ;
   }

   while(1)                           // 如果是兩位數以上 則先判斷幾位
   {
      if(Shuzi>=Weishu && Shuzi<Weishu*10)
         break;
      Weishu*=10;
   }
   // 判斷位數 ↑

   // 將每一位拆分翻譯 ↓
   for(Textlen=0; Weishu; Textlen++)
   {                          
      Tmp = Shuzi/Weishu;        
      Text[Textlen] = Tdate[Tmp];
      Shuzi = Shuzi % Weishu;
      Weishu /= 10;
   }
   // 將每一位拆分翻譯 ↑

   Show_1602_Char(Text, "", Time);
}
*/

關閉窗口

相關文章

主站蜘蛛池模板: 欧美韩一区二区 | 国产一区二区三区免费视频 | 午夜a√| 精品视频久久久 | 国产在线精品一区二区 | 国产日韩视频在线 | 亚洲综合二区 | 精国产品一区二区三区 | 久久久精 | 蜜臀91视频| 精品产国自在拍 | 久草资源在线 | 国产视频一区二区三区四区五区 | 国产一区二区小视频 | 久久精品免费 | 精品中文字幕一区二区三区 | 国产精品久久久久久久久久久久午夜片 | 精品国产91乱码一区二区三区 | 精品久久久网站 | 成人欧美一区二区三区在线观看 | 成年人视频在线免费观看 | 超碰在线97国产 | 自拍偷拍第一页 | 欧美国产日韩一区二区三区 | 欧美精品一二三 | 99精彩视频 | 日韩一区在线播放 | 一区二区小视频 | 天天躁天天操 | 性色网站 | 国产在线中文字幕 | 亚洲美女天堂网 | 玖玖国产精品视频 | 爱爱小视频| 日本午夜精品一区二区三区 | 亚洲一区二区三区免费在线观看 | www.久久| 一区二区三区国产好的精 | 三级高清 | 97视频免费 | 国产亚洲一区二区三区在线观看 |