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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

STM8L的LCD接口詳解及驅動程序

[復制鏈接]
跳轉到指定樓層
樓主
STM8L部分型號集成了段式液晶驅動器,可以驅動4*28=112個液晶段.段式液晶屏為低功耗顯示器件,功耗根據屏的大小和顯示段數會有所不同,通常功耗在10ua左右.生活中,數字電子表,數字萬用表,數顯溫度計等,使用的都是段式液晶屏,通常一顆紐扣電池可以保證設備間隔不斷顯示數字兩年或更久.


大家比較熟悉的液晶屏1602模塊其實也是段式液晶,是一個有很多段的點組成的,由于點比較多,所以1602模塊集成了驅動芯片,我們只需給1602送數據,就可以控制1602進行顯示了.液晶本身不會發光,1602之所以會發光是因為使用了LED背光板.
段式液晶驅動器,通常會含有一個電壓泵,一個頻率分頻器.電壓泵用來提供驅動液晶段的電壓,電壓的高低決定著顯示的清晰度,也就是決定著液晶的對比度.提供給LCD驅動器的頻率決定著,刷新段式液晶的頻率,如果提供給LCD的頻率太低,會看到顯示時的頻閃.

從上圖可以看到,除了分頻器和電壓泵部分,還有顯存.所有液晶屏都會有顯存,每個顯存控制著對應的引腳,對于STM8L的八位顯存,可以控制8個引腳和一個COM引腳,比如STM8L的RAM0控制著COM0對應的S0~S7引腳.
當我們需要驅動一塊液晶屏時,首先要拿到這種液晶屏的引腳對應顯示段的圖紙.如下圖,由于STM8L152C6的RAM0控制著COM0對應的S0~S7引腳,如果要顯示下圖的"元",那么我們只需要向RAM0寫入數據0x01.
本例程的硬件平臺仍然是ST官方的開發板STM8L-DISCOVERY.在ST官網的編號為UM0970這份文檔中,有對開發板上液晶屏的介紹.

這份資料,并不是十分直觀.找到顯存對應的液晶屏上的段,對寫程序來說很重要.

本例程,參考ST提供的例程,根據自己的理解,編寫了LCD驅動程序,提供一個可以在液晶屏上最多顯示六位數字的接口的程序,讀者可以調用此程序,顯示任意六位以內的數字.


  1. /****************************************************************************************

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

  3. *硬件平臺:STM8L-DISCOVERY

  4. *功能說明:使用STM8L-DISCOVERY液晶屏顯示一串6位數字

  5. *作    者:茗風

  6. ****************************************************************************************/

  7. #include"iostm8l152c6.h"

  8. #include"stdint.h"

  9. /*  =========================================================================

  10.                                  LCD MAPPING

  11.     =========================================================================

  12.             A

  13.      _  ----------

  14. COL |_| |\   |J  /|

  15.        F| H  |  K |B

  16.      _  |  \ | /  |

  17. COL |_| --G-- --M--

  18.         |   /| \  |

  19.        E|  Q |  N |C

  20.      _  | /  |P  \|   

  21. DP  |_| -----------  

  22.             D      

  23. */


  24. #define a 0x01

  25. #define b 0x02

  26. #define c 0x04

  27. #define d 0x08

  28. #define e 0x10

  29. #define f 0x20

  30. #define g 0x40

  31. #define m 0x80


  32. const uint8_t LCD_Tab[10] = {

  33.                 a + b + c + d + e + f,                        // Displays "0"

  34.                 b + c,                                        // Displays "1"

  35.                 a + b + m + g + e + d,                        // Displays "2"

  36.                 a + b + m + g + c + d,                        // Displays "3"

  37.                 f + g + m + b + c,                        // Displays "4"

  38.                 a + f + g + m + c +d,                        // Displays "5"

  39.                 a + f + e + d + c + g + m ,                // Displays "6"

  40.                 a + b + c,                                // Displays "7"

  41.                 a + b + c + d + e + f + g + m,                // Displays "8"

  42.                 a + b + c + d + f + g + m                // Displays "9"


  43. };


  44. /******************************************************************************************************

  45. *  名    稱:void LCD_Config(void)

  46. *  功    能:配置DAC,禁用DMA,不使用TIM4觸發,也不用軟件觸發,寫入DHR的數據被立即送入DOR寄存器,

  47. *            立即輸出對應電壓

  48. *  入口參數:無

  49. *  出口參數:無

  50. *  說    明:STM8L152C6屬于中等容量MCU,只有一路DAC輸出,輸出引腳為PF0

  51. *  范    例:無

  52. ******************************************************************************************************/

  53. void LCD_Config(void)

  54. {

  55. //------打開LCD/RTC時鐘------

  56.   CLK_PCKENR2_PCKEN22=1;//打開RTC時鐘,LCD刷新頻率與此時鐘有關

  57.   CLK_PCKENR2_PCKEN23=1;//打開LCD時鐘,讀寫LCD寄存器用到此時鐘

  58.   

  59. //---選擇LSE作為RTC時鐘---

  60.   CLK_CRTCR_RTCSEL0=0;

  61.   CLK_CRTCR_RTCSEL1=0;

  62.   CLK_CRTCR_RTCSEL2=0;

  63.   CLK_CRTCR_RTCSEL3=1;

  64. /* 0000: No clock selected

  65.    0001: HSI clock used as RTC clock source

  66.    0010: LSI clock used as RTC clock source

  67.    0100: HSE clock used as RTC clock source

  68.    1000: LSE clock used as RTC clock sourc*/

  69.   

  70. //----設置RTC時鐘分頻值----

  71.   CLK_CRTCR_RTCDIV0=0;

  72.   CLK_CRTCR_RTCDIV1=0;

  73.   CLK_CRTCR_RTCDIV2=0;

  74. /*000: RTC clock source/1

  75.   001: RTC clock source /2

  76.   010: RTC clock source /4

  77.   011: RTC clock source /8

  78.   100: RTC clock source /16

  79.   101: RTC clock source /32

  80.   110: RTC clock source /64

  81.   111: RTC clock source /128*/

  82.   

  83. //----設置LCD預分頻值----  

  84.   LCD_FRQ_PS0=0;// 2^PS[3:0]

  85.   LCD_FRQ_PS1=0;//分頻值為1

  86.   LCD_FRQ_PS2=0;

  87.   LCD_FRQ_PS3=0;

  88.   

  89. //----設置LCD分頻值----  

  90.   LCD_FRQ_DIV0=1;//DIV[3:0]+16

  91.   LCD_FRQ_DIV1=1;//分頻值為15+16=31

  92.   LCD_FRQ_DIV2=1;

  93.   LCD_FRQ_DIV3=1;  



  94. //以上分頻值的設置,最為了得到適合的LCD的刷新頻率,如果增大分頻值,會導致

  95. //LCD刷新頻率變低,會看到LCD顯示出現閃爍

  96. //比如,我們將PS[3:0]設置為0011,會看到液晶閃爍  

  97.   

  98. //----1/4 duty----  

  99.   LCD_CR1_DUTY0=1;//1/4 duty

  100.   LCD_CR1_DUTY1=1;

  101. /* Duty ratio selection

  102.    00: Static duty

  103.    01: 1/2 duty

  104.    10: 1/3 duty

  105.    11: 1/4 duty      */


  106. //----1/3 bias----     

  107.   LCD_CR1_B2=0;//1/3 bias

  108. /* 0: 1/3 bias

  109.    1: 1/2 bias  */


  110. //----內部電壓源----   

  111.   LCD_CR2_VSEL=0;

  112.   

  113. //----打開引腳的SEG功能----     

  114. // LCD_PM0=0xFF;//頭文件這個地方定義錯誤,無法直接向LCD_PM0寫入數據

  115. // LCD_PM1=0xFF;//PM0寄存器定義錯誤,導致PM1也無法直接寫入

  116. // LCD_PM2=0xFF;//PM0寄存器定義錯誤,導致PM2也無法直接寫入

  117.   *((uint8_t *)0x5404)=0xFF;//直接向LCD_PM0寄存器的地址寫入數據

  118.   *((uint8_t *)0x5405)=0xFF;//直接向LCD_PM1寄存器的地址寫入數據

  119.   *((uint8_t *)0x5406)=0xFF;//直接向LCD_PM2寄存器的地址寫入數據

  120.   

  121. //----To set contrast to mean value----   

  122.   LCD_CR2_CC0=0;//對比度

  123.   LCD_CR2_CC1=1;

  124.   LCD_CR2_CC2=0;

  125. /*  000: VLCD0  2.6V

  126.     001: VLCD1  2.7V

  127.     010: VLCD2  2.8V

  128.     011: VLCD3  2.9V

  129.     100: VLCD4  3.0V

  130.     101: VLCD5  3.1V

  131.     110: VLCD6  3.2V

  132.     111: VLCD7    */

  133.        

  134. //----Dead time 0----        

  135.   LCD_CR3_DEAD0=0;//no dead time

  136.   LCD_CR3_DEAD1=0;  

  137.   LCD_CR3_DEAD2=0;

  138. //----LCD_PulseOnDuration_1----

  139.   LCD_CR2_PON0=1;

  140.   LCD_CR2_PON1=0;  

  141.   LCD_CR2_PON2=0;         

  142. /*  000: 0 CLKps pulses

  143.     001: 1 CLKps pulses

  144.     010: 2 CLKps pulses

  145.     011: 3 CLKps pulses

  146.     100: 4 CLKps pulses

  147.     101: 5 CLKps pulses

  148.     110: 6 CLKps pulses

  149.     111: 7 CLKps pulses  */

  150.        

  151. //----Enable LCD peripheral----       

  152.   LCD_CR3_LCDEN=1;

  153. }


  154. /******************************************************************************************************

  155. *  名          稱:LCD_DisplayNum(uint8_t number)

  156. *  功            能:控制段式液晶屏的數字顯示部分

  157. *  入口參數:number:要顯示的數字

  158. *  出口參數:無

  159. *  說          明:根據數字的長度,判斷要顯示的長度,長度大于6位,只顯示后六位

  160. *  范          例:無

  161. ******************************************************************************************************/

  162. void LCD_DisplayNum(uint32_t number)

  163. {

  164.   uint8_t cnts=0,tmp=0;

  165.   

  166.   if(number<10)cnts=1;

  167.   else if(number<100)cnts=2;

  168.   else if(number<1000)cnts=3;

  169.   else if(number<10000)cnts=4;

  170.   else if(number<100000)cnts=5;

  171.   else if(number<(uint32_t) 1000000)cnts=6;

  172.   else cnts=6;


  173.   //判斷需要顯示數字的長度,確定在LCD屏上需要的位數

  174.   switch(cnts)

  175.   {

  176.     case 6:

  177.            tmp = LCD_Tab[number%1000000/100000];

  178.            ((tmp&m)==0)?(LCD_RAM0&=~0x02):(LCD_RAM0 |=0x02) ;

  179.            ((tmp&e)==0)?(LCD_RAM0&=~0x01):(LCD_RAM0 |=0x01) ;

  180.            ((tmp&g)==0)?(LCD_RAM2&=~0x80):(LCD_RAM2 |=0x80) ;

  181.            ((tmp&b)==0)?(LCD_RAM2&=~0x40):(LCD_RAM2 |=0x40) ;

  182.            ((tmp&f)==0)?(LCD_RAM6&=~0x08):(LCD_RAM6 |=0x08) ;

  183.            ((tmp&a)==0)?(LCD_RAM6&=~0x04):(LCD_RAM6 |=0x04) ;

  184.            ((tmp&c)==0)?(LCD_RAM3&=~0x20):(LCD_RAM3 |=0x20) ;

  185.            ((tmp&d)==0)?(LCD_RAM3&=~0x10):(LCD_RAM3 |=0x10) ;                     

  186.     case 5:

  187.            tmp = LCD_Tab[number%100000/10000];

  188.            ((tmp&m)==0)?(LCD_RAM0&=~0x08):(LCD_RAM0 |=0x08) ;

  189.            ((tmp&e)==0)?(LCD_RAM0&=~0x04):(LCD_RAM0 |=0x04) ;

  190.            ((tmp&g)==0)?(LCD_RAM2&=~0x20):(LCD_RAM2 |=0x20) ;

  191.            ((tmp&b)==0)?(LCD_RAM2&=~0x10):(LCD_RAM2 |=0x10) ;

  192.            ((tmp&f)==0)?(LCD_RAM6&=~0x02):(LCD_RAM6 |=0x02) ;

  193.            ((tmp&a)==0)?(LCD_RAM6&=~0x01):(LCD_RAM6 |=0x01) ;

  194.            ((tmp&c)==0)?(LCD_RAM3&=~0x80):(LCD_RAM3 |=0x80) ;

  195.            ((tmp&d)==0)?(LCD_RAM3&=~0x40):(LCD_RAM3 |=0x40) ;           

  196.            

  197.     case 4:

  198.            tmp = LCD_Tab[number%10000/1000];


  199.            ((tmp&m)==0)?(LCD_RAM0&=~0x20):(LCD_RAM0 |=0x20) ;

  200.            ((tmp&e)==0)?(LCD_RAM0&=~0x10):(LCD_RAM0 |=0x10) ;

  201.            ((tmp&g)==0)?(LCD_RAM2&=~0x08):(LCD_RAM2 |=0x08) ;

  202.            ((tmp&b)==0)?(LCD_RAM2&=~0x04):(LCD_RAM2 |=0x04) ;

  203.            ((tmp&f)==0)?(LCD_RAM5&=~0x80):(LCD_RAM5 |=0x80) ;

  204.            ((tmp&a)==0)?(LCD_RAM5&=~0x40):(LCD_RAM5 |=0x40) ;

  205.            ((tmp&c)==0)?(LCD_RAM4&=~0x02):(LCD_RAM4 |=0x02) ;

  206.            ((tmp&d)==0)?(LCD_RAM4&=~0x01):(LCD_RAM4 |=0x01) ;           

  207.     case 3:

  208.            tmp = LCD_Tab[number%1000/100];

  209.            ((tmp&m)==0)?(LCD_RAM0&=~0x80):(LCD_RAM0 |=0x80) ;

  210.            ((tmp&e)==0)?(LCD_RAM0&=~0x40):(LCD_RAM0 |=0x40) ;

  211.            ((tmp&g)==0)?(LCD_RAM2&=~0x02):(LCD_RAM2 |=0x02) ;

  212.            ((tmp&b)==0)?(LCD_RAM2&=~0x01):(LCD_RAM2 |=0x01) ;

  213.            ((tmp&f)==0)?(LCD_RAM5&=~0x20):(LCD_RAM5 |=0x20) ;

  214.            ((tmp&a)==0)?(LCD_RAM5&=~0x10):(LCD_RAM5 |=0x10) ;

  215.            ((tmp&c)==0)?(LCD_RAM4&=~0x08):(LCD_RAM4 |=0x08) ;

  216.            ((tmp&d)==0)?(LCD_RAM4&=~0x04):(LCD_RAM4 |=0x04) ;


  217.    case 2:

  218.            tmp = LCD_Tab[number%100/10];

  219.            ((tmp&m)==0)?(LCD_RAM1&=~0x02):(LCD_RAM1 |=0x02) ;

  220.            ((tmp&e)==0)?(LCD_RAM1&=~0x01):(LCD_RAM1 |=0x01) ;

  221.            ((tmp&g)==0)?(LCD_RAM1&=~0x80):(LCD_RAM1 |=0x80) ;

  222.            ((tmp&b)==0)?(LCD_RAM1&=~0x40):(LCD_RAM1 |=0x40) ;

  223.            ((tmp&f)==0)?(LCD_RAM5&=~0x08):(LCD_RAM5 |=0x08) ;

  224.            ((tmp&a)==0)?(LCD_RAM5&=~0x04):(LCD_RAM5 |=0x04) ;

  225.            ((tmp&c)==0)?(LCD_RAM4&=~0x20):(LCD_RAM4 |=0x20) ;

  226.            ((tmp&d)==0)?(LCD_RAM4&=~0x10):(LCD_RAM4 |=0x10) ;


  227.    case 1:

  228.            tmp = LCD_Tab[number%10];

  229.            ((tmp&m)==0)?(LCD_RAM1&=~0x08):(LCD_RAM1 |=0x08) ;

  230.            ((tmp&e)==0)?(LCD_RAM1&=~0x04):(LCD_RAM1 |=0x04) ;

  231.            ((tmp&g)==0)?(LCD_RAM1&=~0x20):(LCD_RAM1 |=0x20) ;

  232.            ((tmp&b)==0)?(LCD_RAM1&=~0x10):(LCD_RAM1 |=0x10) ;

  233.            ((tmp&f)==0)?(LCD_RAM5&=~0x02):(LCD_RAM5 |=0x02) ;

  234.            ((tmp&a)==0)?(LCD_RAM5&=~0x01):(LCD_RAM5 |=0x01) ;

  235.            ((tmp&c)==0)?(LCD_RAM4&=~0x80):(LCD_RAM4 |=0x80) ;

  236.            ((tmp&d)==0)?(LCD_RAM4&=~0x40):(LCD_RAM4 |=0x40) ;

  237.     break;


  238.     default:break;

  239.   }

  240. }

  241. void main(void)

  242. {

  243.   LCD_Config();

  244.   LCD_DisplayNum(201609);

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

  246.   while(1)

  247.   {

  248.     asm("wfi");

  249.   }

  250. }
復制代碼




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

使用道具 舉報

來自 4#
ID:466148 發表于 2019-3-29 19:28 來自手機 | 只看該作者
大師,我用你的lcd程序和你的adc程序調試stm8ldiscouer套件時發現,stm8l152c 6t6的adc測電壓時,電壓從0伏調到2.99伏,lcd輸出顯示正常 ,電壓從2.99到1伏正常,電壓從1伏到0.99伏時,顯示1.99伏,電壓從1伏調到0伏,顯示就從1伏到1.99到1.0,就可以要多顯示1伏,而在電腦上的調試程序中顯示的電壓確是正常的,而單片機輸入電壓是用萬用表和示波器看的,電壓沒有跳躍,不知道是那里的問題?感覺好像跟中斷觸發有關系。
回復

使用道具 舉報

沙發
ID:276663 發表于 2018-4-24 17:23 | 只看該作者
謝謝分享,發現最難的就是對應顯存。不知道有什么規則。
回復

使用道具 舉報

板凳
ID:419511 發表于 2018-11-5 10:58 | 只看該作者
為什么我這里會報錯
回復

使用道具 舉報

5#
ID:164100 發表于 2019-12-20 13:32 | 只看該作者
本帖最后由 huang_hzl 于 2019-12-20 14:55 編輯


你好,我按你的LCD配置,依然無法點亮LCD,請問,是哪里的問題呢  ?
仿真時,可以看到LCD_RAM0~LCDRAM13,已經被寫入了數據。
回復

使用道具 舉報

6#
ID:679630 發表于 2020-1-13 16:03 | 只看該作者
huang_hzl 發表于 2019-12-20 13:32
你好,我按你的LCD配置,依然無法點亮LCD,請問,是哪里的問題呢  ?
仿真時,可以看到LCD_RAM0~LCDRAM13 ...

你好,我現在遇到跟你一樣的問題,請問你的點亮了嘛
回復

使用道具 舉報

7#
ID:679630 發表于 2020-1-13 18:36 | 只看該作者
huang_hzl 發表于 2019-12-20 13:32
你好,我按你的LCD配置,依然無法點亮LCD,請問,是哪里的問題呢  ?
仿真時,可以看到LCD_RAM0~LCDRAM13 ...

你好,我用的也是STM8L系列的LCD型芯片,遇到了跟你一樣的問題,可以回復我或則加我qq為我解除一下疑惑嘛,非常感謝!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩欧美一区二区三区 | 影视一区| 亚洲美女网站 | 亚洲一区二区三区视频免费观看 | 国产精品99一区二区 | 免费99精品国产自在在线 | 一区二区三区在线免费观看视频 | 国产精品视频一区二区三区不卡 | 色视频网站| 日韩美女一区二区三区在线观看 | 国产免费福利 | 国产精品美女 | 精精精精xxxx免费视频 | 九九伊人sl水蜜桃色推荐 | 亚洲一区二区在线 | 中文在线а√在线8 | 亚洲欧美日韩久久久 | 中文字幕第十页 | 精品无码久久久久久国产 | 亚洲精品一区在线观看 | 久久久.com | 久久tv在线观看 | 亚洲成人精品久久 | 国产成人a亚洲精品 | 精品亚洲第一 | 日韩精品一区二区三区久久 | 欧美在线小视频 | 美女黄18岁以下禁止观看 | 免费在线观看成人 | 国产日韩一区二区三免费高清 | 干干天天 | 国产一区二区三区日韩 | 欧美一区二区久久 | 国产一二三视频在线观看 | 欧美日韩在线一区二区 | 91亚洲国产| 国产精品成人av | 精品入口麻豆88视频 | a毛片视频网站 | 国产成人99久久亚洲综合精品 | 亚洲人在线观看视频 |