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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5275|回復: 0
打印 上一主題 下一主題
收起左側

STM8L驅動LCD1602液晶屏

[復制鏈接]
跳轉到指定樓層
樓主
ID:145459 發表于 2016-11-1 00:29 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
由于上次諾基亞5110的液晶屏接觸不良,所以沒辦法用在我要做的自平衡小車上面.我主要是想用液晶屏顯示PID參數,用兩個按鍵設置PID,方便平衡小車的調試.
我手中只剩下LCD1602這款液晶屏了,雖然一直很嫌棄它(驅動IO多,顯示字符少)但也沒辦法.
本文使用四線驅動LCD1602的方法,主要是八線驅動太占用IO口.關于四線驅動,網上有很多例程可以參考,我也是參考網上的程序寫的.但在編寫LCD1602驅動程序時,還是經歷了很多困難,時序問題就不提了.網上的很多程序都是沒有判斷忙標志位的,直接通過延時來實現.這樣,延時時間多少合適成為一個問題,我改了好多次延時,但發現延時時間都比較長,寫入一次數據的時間很長.這樣的液晶屏用著很鬧心,刷新一次時間那么,我的程序還有很多對時間要求比較苛刻的任務要執行呢,這樣的速度可不行.
關于四線驅動如何去判斷忙標志位,我也不懂,只好去網上搜,很少有這方面的例程,但最后還是找到了一個,照著寫,總算解決了.

上圖是單片機與LCD1602的接線圖,DB0~DB7為8條并行數據線.VL是調節液晶屏的對比度的,外接一個電位器到地,如果顯示不清晰,可以通過此電位器調節值最佳對比度.BLK,BLA接液晶背光.
除了8個數據線,和顯示控制有關的還有RS,RW,E三個端口,上圖是他們對應的功能.

通過向LCD1602寫入命令和數據來控制顯示.讀狀態是為了判斷LCD1602此時是否處于忙的狀態,如果忙,就只能等待不忙的時候再進行寫操作.通過讀狀態時序,讀到一個八位數據,最高位是忙標志位,此位為1說明此時忙,為了表示空閑.
大概沒什么要講的了,LCD1602的一些設置指令比較重要,手上也沒找到詳細的配置說明.


下圖是LCD1602驅動芯片的顯存,向對應的顯存地址寫入數據,就可以控制顯示字符.由于LCD1602自帶了一個ASCII碼字庫,所以一些常用的字符都可以直接顯示,不需要自己去用軟件生成字庫了.


四線驅動時,寫入的是0x28,八線驅動是寫入的是0x38,如上圖.

四線驅動的寫命令寫數據時序可以參考下面的例程.
本例程,使用STM8L的PB口驅動LCD1602,正好用完PB口的八個IO.高四位是數據接口,寫入一字節數據時,先寫高四位,再寫第四位.

  1. /*硬件連接*/

  2. //    PB0     -->      RS

  3. //    PB1     -->      RW

  4. //    PB2     -->      E

  5. //    PB3     -->      A(背光正極)

  6. //    PB4     -->      D4

  7. //    PB5     -->      D5

  8. //    PB6     -->      D6

  9. //    PB7     -->      D7

  10. //    PD6     -->      按鍵+

  11. //    PD7     -->      按鍵-



  12. #define   RS_H       PB_ODR_ODR0=1

  13. #define   RS_L       PB_ODR_ODR0=0


  14. #define   RW_H       PB_ODR_ODR1=1

  15. #define   RW_L       PB_ODR_ODR1=0


  16. #define   EN_H       PB_ODR_ODR2=1

  17. #define   EN_L       PB_ODR_ODR2=0


  18. /****************************************************************************************

  19. *開發環境:IAR for stm8 v6.5.3

  20. *硬件平臺:STM8L-DISCOVERY

  21. *功能說明:LCD1602四線驅動控制,檢測忙標志位    第一行顯示一串字符,第二行顯示一個可以用按鍵改變大小的三位數字

  22. *作    者:茗風

  23. ****************************************************************************************/

  24. #include"iostm8l152c6.h"

  25. #include"stdbool.h"

  26. #include"stdint.h"

  27. const uint8_t Num_to_Char[10]="0123456789";


  28. /******************************************************************************************************

  29. *  名    稱:void delay_100us(uint8_t x_us)

  30. *  功    能:延時100us

  31. *  入口參數:無

  32. *  出口參數:無

  33. *  說    明:

  34. *  范    例:無

  35. ******************************************************************************************************/

  36. void delay_100us(uint16_t x_us)

  37. {

  38.   uint8_t j;

  39.   while(x_us--)

  40.   {

  41.     for(j=0;j<33;j++);//2*40個指令周期

  42.   }

  43.   //delay_10ms共消耗 x_ms*2*255+2*x_ms個指令周期  

  44.   //*2*40+2*x_ms=80us+

  45.   //16M/8/2=1M 一個指令周期為1us

  46. }

  47. ///******************************************************************** **********************************

  48. //*  功  能   :LCD1602端口初始化函數

  49. //*  入口參數 :無

  50. //*  出口參數 :無

  51. //*  說  明   :對LCD1602用的IO端口進行初始化

  52. //*  范  例   :無

  53. //******************************************************************************************************/

  54. void LCD1602_GPIO_Init(void)

  55. {

  56.    

  57.   PB_DDR =0xFF;//PB設置為輸出

  58.   PB_CR1 =0xFF;//PB設置為推挽輸出

  59.   PB_CR2 =0xFF;//PB的IO輸出速率為10MHz

  60.   PB_ODR =0x00;//PB輸出高電平

  61.   PB_ODR |=0x08;

  62. }

  63. ///******************************************************************************************************

  64. //* 功    能        :LCD1602忙檢測,若不忙則退出,忙則等待

  65. //* 入口參數        :無

  66. //* 出口參數        :無

  67. //* 說    明        :

  68. //* 編寫日期  :2016年10月21日

  69. //* 作    者  :茗風

  70. //******************************************************************************************************/

  71. void LCD1602_Busy_Check(void)

  72. {

  73.   PB_CR1 &=0x7F;//浮空輸入

  74.   PB_CR2 &=0x7F;//無中斷能力

  75.   PB_DDR &=0x7F;

  76.   PB_ODR |=0x80;

  77.   RS_L;

  78.   RW_H;

  79.   EN_H;

  80.   while(PB_IDR&0x80);

  81.   PB_DDR |=0x80;//PB設置為輸出

  82.   PB_CR1 |=0x80;//PB設置為推挽輸出

  83.   PB_CR2 |=0x80;//PB的IO輸出速率為10MHz

  84.   EN_L;

  85. }

  86. ///******************************************************************************************************

  87. //* 功    能        :LCD1602寫命令函數

  88. //* 入口參數        :d 寫入的一字節命令

  89. //* 出口參數        :無

  90. //* 說    明        :

  91. //* 編寫日期  :2016年10月21日

  92. //* 作    者  :茗風

  93. //******************************************************************************************************/

  94. void LCD1602_Write_One_Byte_Cmd(uint8_t d)

  95. {

  96.   LCD1602_Busy_Check();

  97.   

  98.   RW_L;//寫

  99.   RS_L;//命令

  100.        

  101.   PB_ODR &=0x0F;//清高四位

  102.   PB_ODR |=(d&0xF0);

  103.   EN_H;//

  104.   asm("nop");//200ns延時

  105.   EN_L;

  106.   asm("nop");//200ns延時

  107.   

  108.   d<<=4;        //低四位移到到高四位

  109.   PB_ODR &=0x0F;//清高四位

  110.   PB_ODR |=(d&0xF0);

  111.   EN_H;

  112.   asm("nop");//200ns延時

  113.   EN_L;

  114.   asm("nop");//200ns延時

  115. }

  116. ///******************************************************************************************************

  117. //* 功    能        :LCD1602寫數據函數

  118. //* 入口參數        :d 寫入的一字節數據

  119. //* 出口參數        :無

  120. //* 說    明        :

  121. //* 編寫日期  :2016年10月21日

  122. //* 作    者  :茗風

  123. //******************************************************************************************************/

  124. void LCD1602_Write_One_Byte_Data(char d)

  125. {

  126.   LCD1602_Busy_Check();

  127.   RS_H;//數據

  128.   RW_L;//寫

  129.   

  130.   PB_ODR &=0x0F;//清高四位

  131.   PB_ODR |=(d&0xF0);

  132.   EN_H;

  133.   asm("nop");

  134.   EN_L;

  135. //  asm("nop");

  136. //  delay_100us(1500);

  137.        

  138.   d<<=4;        //低四位移到到高四位

  139.   PB_ODR &=0x0F;//清高四位

  140.   PB_ODR |=(d&0xF0);

  141.   EN_H;

  142.   asm("nop");

  143.   EN_L;

  144.   asm("nop");

  145. //  delay_100us(1500);

  146. }

  147. ///******************************************************************************************************

  148. //* 功    能        :LCD1602一串字符函數

  149. //* 入口參數        :x  x軸坐標,取值范圍(0~15)

  150. //*             y  y軸坐標,取值范圍(0~1),一共兩行

  151. //*             *s 一串字符

  152. //* 出口參數        :無

  153. //* 說    明        :

  154. //* 編寫日期  :2016年10月21日

  155. //* 作    者  :茗風

  156. //******************************************************************************************************/

  157. uint8_t LCD1602_Display_String(uint8_t x,uint8_t y,uint8_t *s)

  158. {


  159.     if(y==1)

  160.     {

  161.       LCD1602_Write_One_Byte_Cmd(0xC0+x);//設置寫入字符開始坐標  

  162.     }

  163.     else

  164.     {

  165.       LCD1602_Write_One_Byte_Cmd(0x80+x);//設置寫入字符開始坐標  

  166.     }

  167.     while(*s != '\0')

  168.     {

  169.       LCD1602_Write_One_Byte_Data(*s++);

  170.     }

  171.     return 0;

  172. }

  173. ///******************************************************************************************************

  174. //* 功    能        :LCD1602顯示兩位數字

  175. //* 入口參數        :x  x軸坐標,取值范圍(0~15)

  176. //*             y  y軸坐標,取值范圍(0~1),一共兩行

  177. //*             *s 一串字符

  178. //* 出口參數        :無

  179. //* 說    明        :

  180. //* 編寫日期  :2016年10月22日

  181. //* 作    者  :茗風

  182. //******************************************************************************************************/

  183. void LCD1602_Display_Number(uint8_t x,uint8_t y,uint8_t number)

  184. {


  185.   if(y==1)

  186.   {

  187.     LCD1602_Write_One_Byte_Cmd(0xC0+x);//設置寫入字符開始坐標  

  188.   }

  189.   else

  190.   {

  191.     LCD1602_Write_One_Byte_Cmd(0x80+x);//設置寫入字符開始坐標  

  192.   }

  193.   if(number<10)

  194.   {

  195.      LCD1602_Write_One_Byte_Data(' ');

  196.      LCD1602_Write_One_Byte_Data(' ');

  197.      LCD1602_Write_One_Byte_Data(Num_to_Char[number%10]);

  198.   }

  199.   else if(number<100)

  200.   {

  201.      LCD1602_Write_One_Byte_Data(' ');

  202.      LCD1602_Write_One_Byte_Data(Num_to_Char[number/10]);

  203.      LCD1602_Write_One_Byte_Data(Num_to_Char[number%10]);

  204.   }

  205.   else

  206.   {

  207.      LCD1602_Write_One_Byte_Data(Num_to_Char[number/100]);

  208.      LCD1602_Write_One_Byte_Data(Num_to_Char[number%100/10]);

  209.      LCD1602_Write_One_Byte_Data(Num_to_Char[number%10]);

  210.   }

  211.   

  212. }

  213. ///******************************************************************************************************

  214. //* 功    能        :LCD1602初始化配置

  215. //* 入口參數        :無

  216. //* 出口參數        :無

  217. //* 說    明        :

  218. //* 編寫日期  :2016年10月21日

  219. //* 作    者  :茗風

  220. //******************************************************************************************************/

  221. void LCD1602_init(void)

  222. {

  223.   LCD1602_GPIO_Init();

  224.   LCD1602_Write_One_Byte_Cmd(0x28);//四線驅動

  225.   LCD1602_Write_One_Byte_Cmd(0x01);//清屏

  226.         LCD1602_Write_One_Byte_Cmd(0x06);//這個是上面指令碼是 000001NS的設

  227.   LCD1602_Write_One_Byte_Cmd(0x0C);//顯示開及光標設置

  228. }

  229. ///******************************************************************************************************

  230. //* 功    能        :按鍵GPIO初始化配置

  231. //* 入口參數        :無

  232. //* 出口參數        :無

  233. //* 說    明        :

  234. //* 編寫日期    :2016年10月21日

  235. //* 作    者    :茗風

  236. //******************************************************************************************************/

  237. void GPIO_Config(void)

  238. {

  239.   //PE7 LED控制引腳

  240.   PE_DDR_DDR7 =1;//輸出

  241.   PE_CR1_C17 =1;//推挽輸出

  242.   PE_CR2_C27 =1;//輸出速率10M

  243.   

  244.   //配置閥門到位檢測引腳PD6,PD7

  245.   PD_DDR_DDR6 =0;

  246.   PD_CR1_C16 =1;//帶上拉電阻輸入

  247.   PD_CR2_C26 =1;//使能外部中斷

  248.   

  249.   PD_DDR_DDR7 =0;

  250.   PD_CR1_C17 =1;//帶上拉電阻輸入

  251.   PD_CR2_C27 =1;//使能外部中斷

  252.   

  253.   EXTI_CR3_PDIS =2;//PD口上升沿中斷

  254. /*00: Falling edge and low level

  255.   01: Rising edge only

  256.   10: Falling edge only

  257.   11: Rising and falling edge*/  

  258.   EXTI_CONF_PDHIS =1;//PD[7:4] are used for EXTID interrupt generation

  259.   

  260. //設置中斷

  261. //CPU_CCR |=MASK_CPU_CCR_I1+MASK_CPU_CCR_I0;//啟用硬件優先級,禁用軟件優先級

  262. }

  263. uint8_t num=30;

  264. void main(void)

  265. {

  266.   GPIO_Config();

  267.   LCD1602_init();

  268.   LCD1602_Display_String(0,0,"nannan wo ai ni!");

  269.   LCD1602_Display_String(0,1,"NUM:");

  270.   asm("rim");               //enable interrupts

  271.   while(1)

  272.   {

  273.     LCD1602_Display_Number(4,1,num);

  274.     PE_ODR ^=0x80;

  275.     asm("wfi");

  276.     //delay_100us(10000);

  277.   }

  278. }


  279. #pragma vector=EXTID_vector

  280. __interrupt void EXTID_ISR(void)

  281. {

  282.   delay_100us(100);//10ms延時,暫時這么做

  283.   if(PD_IDR_IDR6==0)//加

  284.   {

  285.     if(num>256)

  286.       num=255;

  287.     else

  288.       num++;

  289.   }

  290.   else if(PD_IDR_IDR7==0)//減

  291.   {

  292.     if(num==0)

  293.       num=0;

  294.     else

  295.       num--;

  296.   }

  297.   EXTI_SR2_PDF =1;//They are cleared by writing a ‘1’ by software

  298. }
復制代碼




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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 尤物在线精品视频 | 日韩在线观看精品 | 欧美精品第一页 | 日本成人三级电影 | 日本三级网址 | 国产精品大片在线观看 | 男人的天堂久久 | 欧美在线成人影院 | 九九热在线视频 | 亚洲精品乱码久久久久久按摩观 | 在线观看www高清视频 | 久久久国产一区二区三区四区小说 | 精品一区av | 狠狠插狠狠操 | 99精品在线 | 精国产品一区二区三区 | 日韩一级免费电影 | 欧美日本韩国一区二区三区 | 精品久久久久久18免费网站 | 日韩成人精品视频 | 乱一性一乱一交一视频a∨ 色爱av | 成人在线免费网站 | 99视频在线免费观看 | a在线视频 | 天天操天天射天天 | 黑人性hd | 久干网 | 蜜桃视频成人 | 久久国产精品-国产精品 | 久久无毛 | 欧洲尺码日本国产精品 | 成人h动漫精品一区二区器材 | 精品国产视频 | 久久久久国产一区二区三区四区 | 欧美xxxx色视频在线观看免费 | 国产精品国产成人国产三级 | 国产亚洲一区精品 | 日本中文字幕一区 | 成人h视频在线 | 九九热精品视频 | 中文字幕一区二区三区日韩精品 |