Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.   Пример для STM32L152C-DISCO
  3.  
  4.   Работа со встроенным ЖКИ.
  5.  
  6.   использовано:
  7.     https://habr.com/ru/post/173709/
  8. *)
  9.  
  10. MODULE LCD;
  11.  
  12. IMPORT SYSTEM;
  13.  
  14.  
  15. CONST
  16.  
  17.     GPIOA = 40020000H;
  18.         GPIOAMODER   = GPIOA;
  19.         GPIOAOTYPER  = GPIOA + 04H;
  20.         GPIOAOSPEEDR = GPIOA + 08H;
  21.         GPIOAPUPDR   = GPIOA + 0CH;
  22.         GPIOAIDR     = GPIOA + 10H;
  23.         GPIOAODR     = GPIOA + 14H;
  24.         GPIOABSRR    = GPIOA + 18H;
  25.         GPIOALCKR    = GPIOA + 1CH;
  26.         GPIOAAFRL    = GPIOA + 20H;
  27.         GPIOAAFRH    = GPIOA + 24H;
  28.         GPIOABRR     = GPIOA + 28H;
  29.  
  30.  
  31.     GPIOB = 40020400H;
  32.         GPIOBMODER   = GPIOB;
  33.         GPIOBOTYPER  = GPIOB + 04H;
  34.         GPIOBOSPEEDR = GPIOB + 08H;
  35.         GPIOBPUPDR   = GPIOB + 0CH;
  36.         GPIOBIDR     = GPIOB + 10H;
  37.         GPIOBODR     = GPIOB + 14H;
  38.         GPIOBBSRR    = GPIOB + 18H;
  39.         GPIOBLCKR    = GPIOB + 1CH;
  40.         GPIOBAFRL    = GPIOB + 20H;
  41.         GPIOBAFRH    = GPIOB + 24H;
  42.         GPIOBBRR     = GPIOB + 28H;
  43.  
  44.  
  45.     GPIOC = 40020800H;
  46.         GPIOCMODER   = GPIOC;
  47.         GPIOCOTYPER  = GPIOC + 04H;
  48.         GPIOCOSPEEDR = GPIOC + 08H;
  49.         GPIOCPUPDR   = GPIOC + 0CH;
  50.         GPIOCIDR     = GPIOC + 10H;
  51.         GPIOCODR     = GPIOC + 14H;
  52.         GPIOCBSRR    = GPIOC + 18H;
  53.         GPIOCLCKR    = GPIOC + 1CH;
  54.         GPIOCAFRL    = GPIOC + 20H;
  55.         GPIOCAFRH    = GPIOC + 24H;
  56.         GPIOCBRR     = GPIOC + 28H;
  57.  
  58.  
  59.     RCC = 40023800H;
  60.         RCC_CR      = RCC;
  61.         RCC_AHBENR  = RCC + 1CH;
  62.         RCC_APB2ENR = RCC + 20H;
  63.         RCC_APB1ENR = RCC + 24H;
  64.         RCC_CSR     = RCC + 34H;
  65.  
  66.  
  67.     PWR = 40007000H;
  68.         PWR_CR = PWR;
  69.  
  70.  
  71.     LCD = 40002400H;
  72.         LCD_CR   = LCD;
  73.         LCD_FCR  = LCD + 04H;
  74.         LCD_SR   = LCD + 08H;
  75.         LCD_RAM  = LCD + 14H;
  76.  
  77.  
  78.     AFM = 2;
  79.  
  80.     AF11 = 11;
  81.  
  82.     PinsA = {1..3, 8..10, 15};
  83.     PinsB = {3..5, 8..15};
  84.     PinsC = {0..3, 6..11};
  85.  
  86.     A = 0;  H = 7;
  87.     B = 1;  J = 8;
  88.     C = 2;  K = 9;
  89.     D = 3;  M = 10;
  90.     E = 4;  N = 11;
  91.     F = 5;  P = 12;
  92.     G = 6;  Q = 13;
  93.  
  94.     DP = 14; COLON = 15; BAR = 16;
  95.  
  96.  
  97. VAR
  98.     display: ARRAY 6, 17 OF INTEGER;
  99.  
  100.     digits: ARRAY 10 OF SET;
  101.  
  102.  
  103. PROCEDURE SetPinsMode (reg: INTEGER; pins: SET; mode: INTEGER);
  104. VAR
  105.     x: SET;
  106.     pin: INTEGER;
  107.  
  108. BEGIN
  109.     mode := mode MOD 4;
  110.     SYSTEM.GET(reg, x);
  111.     FOR pin := 0 TO 30 BY 2 DO
  112.         IF (pin DIV 2) IN pins THEN
  113.             x := x - {pin, pin + 1} + BITS(LSL(mode, pin))
  114.         END
  115.     END;
  116.     SYSTEM.PUT(reg, x)
  117. END SetPinsMode;
  118.  
  119.  
  120. PROCEDURE SRBits (adr: INTEGER; setbits, resetbits: SET);
  121. VAR
  122.     x: SET;
  123.  
  124. BEGIN
  125.     SYSTEM.GET(adr, x);
  126.     SYSTEM.PUT(adr, x - resetbits + setbits)
  127. END SRBits;
  128.  
  129.  
  130. PROCEDURE SetBits (adr: INTEGER; bits: SET);
  131. VAR
  132.     x: SET;
  133.  
  134. BEGIN
  135.     SYSTEM.GET(adr, x);
  136.     SYSTEM.PUT(adr, x + bits)
  137. END SetBits;
  138.  
  139.  
  140. PROCEDURE ResetBits (adr: INTEGER; bits: SET);
  141. VAR
  142.     x: SET;
  143.  
  144. BEGIN
  145.     SYSTEM.GET(adr, x);
  146.     SYSTEM.PUT(adr, x - bits)
  147. END ResetBits;
  148.  
  149.  
  150. PROCEDURE TestBits (adr: INTEGER; bits: SET): BOOLEAN;
  151. VAR
  152.     x: SET;
  153.  
  154. BEGIN
  155.     SYSTEM.GET(adr, x);
  156.     RETURN x * bits = bits
  157. END TestBits;
  158.  
  159.  
  160. PROCEDURE Init;
  161. VAR
  162.     i, j: INTEGER;
  163.     seg: ARRAY 30 OF INTEGER;
  164.  
  165. BEGIN
  166.     FOR i := 0 TO 29 DO
  167.         seg[i] := i
  168.     END;
  169.  
  170.     FOR i := 3 TO 11 DO
  171.         seg[i] := i + 4
  172.     END;
  173.  
  174.     seg[18] := 17;
  175.     seg[19] := 16;
  176.  
  177.     FOR i := 20 TO 23 DO
  178.         seg[i] := i - 2
  179.     END;
  180.  
  181.     j := 0;
  182.     FOR i := 0 TO 5 DO
  183.         display[i, A] := 256 + seg[28 - j];
  184.         display[i, B] :=   0 + seg[28 - j];
  185.         display[i, C] := 256 + seg[j + 1];
  186.         display[i, D] := 256 + seg[j];
  187.         display[i, E] :=   0 + seg[j];
  188.         display[i, F] := 256 + seg[29 - j];
  189.         display[i, G] :=   0 + seg[29 - j];
  190.         display[i, H] := 768 + seg[29 - j];
  191.         display[i, J] := 768 + seg[28 - j];
  192.         display[i, K] := 512 + seg[28 - j];
  193.         display[i, M] :=   0 + seg[j + 1];
  194.         display[i, N] := 768 + seg[j];
  195.         display[i, P] := 512 + seg[j];
  196.         display[i, Q] := 512 + seg[29 - j];
  197.         INC(j, 2)
  198.     END;
  199.  
  200.     display[0, DP] := 768 + 1;
  201.     display[1, DP] := 768 + 7;
  202.     display[2, DP] := 768 + 9;
  203.     display[3, DP] := 768 + 11;
  204.  
  205.     display[0, COLON] := 512 + 1;
  206.     display[1, COLON] := 512 + 7;
  207.     display[2, COLON] := 512 + 9;
  208.     display[3, COLON] := 512 + 11;
  209.  
  210.     display[0, BAR] := 768 + 15;
  211.     display[1, BAR] := 512 + 15;
  212.     display[2, BAR] := 768 + 13;
  213.     display[3, BAR] := 512 + 13;
  214.  
  215.     digits[0] := {A, B, C, D, E, F};
  216.     digits[1] := {B, C};
  217.     digits[2] := {A, B, M, G, E, D};
  218.     digits[3] := {A, B, M, G, C, D};
  219.     digits[4] := {F, G, M, B, C};
  220.     digits[5] := {A, F, G, M, C, D};
  221.     digits[6] := {A, F, G, M, C, D, E};
  222.     digits[7] := {F, A, B, C};
  223.     digits[8] := {A, B, C, D, E, F, G, M};
  224.     digits[9] := {A, B, C, D, F, G, M};
  225. END Init;
  226.  
  227.  
  228. PROCEDURE ResetSeg (seg: INTEGER);
  229. BEGIN
  230.     ResetBits(LCD_RAM + (seg DIV 256) * 2 * 4, {seg MOD 256})
  231. END ResetSeg;
  232.  
  233.  
  234. PROCEDURE SetSeg (seg: INTEGER);
  235. BEGIN
  236.     SetBits(LCD_RAM + (seg DIV 256) * 2 * 4, {seg MOD 256})
  237. END SetSeg;
  238.  
  239.  
  240. PROCEDURE Digit (pos, dgt: INTEGER);
  241. VAR
  242.     s: SET;
  243.     i: INTEGER;
  244.  
  245. BEGIN
  246.     s := digits[dgt];
  247.     FOR i := 0 TO 13 DO
  248.         IF i IN s THEN
  249.             SetSeg(display[pos, i])
  250.         ELSE
  251.             ResetSeg(display[pos, i])
  252.         END
  253.     END
  254. END Digit;
  255.  
  256.  
  257. PROCEDURE WhileBits (adr: INTEGER; bits: SET);
  258. BEGIN
  259.     WHILE TestBits(adr, bits) DO END
  260. END WhileBits;
  261.  
  262.  
  263. PROCEDURE UntilBits (adr: INTEGER; bits: SET);
  264. BEGIN
  265.     REPEAT UNTIL TestBits(adr, bits)
  266. END UntilBits;
  267.  
  268.  
  269. PROCEDURE main;
  270. VAR
  271.     i: INTEGER;
  272.  
  273. BEGIN
  274.     Init;
  275.  
  276.     (* подключить GPIOA, GPIOB, GPIOC *)
  277.     SetBits(RCC_AHBENR, {0, 1, 2});
  278.  
  279.     (* настроить на режим альтернативной функции *)
  280.     SetPinsMode(GPIOAMODER,   PinsA, AFM);
  281.  
  282.     (* 400 кГц *)
  283.     SetPinsMode(GPIOAOSPEEDR, PinsA,   0);
  284.  
  285.     (* без подтягивающих резисторов *)
  286.     SetPinsMode(GPIOAPUPDR,   PinsA,   0);
  287.  
  288.     (* режим push-pull *)
  289.     ResetBits(GPIOAOTYPER, PinsA);
  290.  
  291.     (* альтернативная функция AF11 = 0BH *)
  292.     SYSTEM.PUT(GPIOAAFRL, 0BBB0H);
  293.     SYSTEM.PUT(GPIOAAFRH, 0B0000BBBH);
  294.  
  295.     (* аналогично для GPIOB *)
  296.     SetPinsMode(GPIOBMODER,   PinsB, AFM);
  297.     SetPinsMode(GPIOBOSPEEDR, PinsB,   0);
  298.     SetPinsMode(GPIOBPUPDR,   PinsB,   0);
  299.     ResetBits(GPIOBOTYPER, PinsB);
  300.     SYSTEM.PUT(GPIOBAFRL, 000BBB000H);
  301.     SYSTEM.PUT(GPIOBAFRH, 0BBBBBBBBH);
  302.  
  303.     (* аналогично для GPIOC *)
  304.     SetPinsMode(GPIOCMODER,   PinsC, AFM);
  305.     SetPinsMode(GPIOCOSPEEDR, PinsC,   0);
  306.     SetPinsMode(GPIOCPUPDR,   PinsC,   0);
  307.     ResetBits(GPIOCOTYPER, PinsC);
  308.     SYSTEM.PUT(GPIOCAFRL, 0BB00BBBBH);
  309.     SYSTEM.PUT(GPIOCAFRH, 00000BBBBH);
  310.  
  311.     (* подключить контроллер ЖКИ *)
  312.     SetBits(RCC_APB1ENR, {9, 28});  (* LCDEN = {9}; PWREN = {28} *)
  313.  
  314.     (* разрешить запись в регистр RCC_CSR *)
  315.     SetBits(PWR_CR, {8});  (* DBP = {8} *)
  316.  
  317.     (* сбросить источник тактирования *)
  318.     SetBits(RCC_CSR, {23}); (* RTCRST = {23} *)
  319.  
  320.     (* выбрать новый источник *)
  321.     ResetBits(RCC_CSR, {23}); (* RTCRST = {23} *)
  322.  
  323.     (* включить НЧ генератор *)
  324.     SetBits(RCC_CSR, {8}); (* LSEON = {8} *)
  325.  
  326.     (* ждать готовность НЧ генератора *)
  327.     UntilBits(RCC_CSR, {9}); (* LSERDY = {9} *)
  328.  
  329.     (* выбрать НЧ генератор как источник тактирования *)
  330.     SRBits(RCC_CSR, {16}, {17});   (* RCC_CSR[17:16] := 01b *)
  331.  
  332.     (* настроить контроллер ЖКИ *)
  333.     SRBits(LCD_CR, {2, 3, 6, 7}, {4, 5}); (* MUX_SEG = {7}; BIAS1 = {6}; BIAS0 = {5}; DUTY2 = {4}; DUTY1 = {3}; DUTY0 = {2} *)
  334.  
  335.     (* Установить значения коэффициентов деления частоты тактового сигнала LCDCLK *)
  336.     SRBits(LCD_FCR, {11, 18, 24}, {10..12, 18..25}); (* LCD_FCR[12:10] := 010b; LCD_FCR[21:18] := 0001b; LCD_FCR[25:22] := 0100b *)
  337.  
  338.     (* ждать синхронизацию регистра LCD_FCR *)
  339.     UntilBits(LCD_SR, {5}); (* FCRSF = {5} *)
  340.  
  341.     (* выбрать внутренний источник напряжения для ЖКИ и разрешить его работу *)
  342.     SRBits(LCD_CR, {0}, {1}); (* LCD_CR_VSEL = {1}; LCD_CR_LCDEN = {0} *)
  343.  
  344.     (* ждать готовность контроллера ЖКИ *)
  345.     UntilBits(LCD_SR, {0, 4}); (* LCD_SR_RDY = {4}; LCD_SR_ENS = {0} *)
  346.  
  347.     (* ждать завершение предыдущей записи *)
  348.     WhileBits(LCD_SR, {2}); (* LCD_SR_UDR = {2} *)
  349.  
  350.     (* начать запись *)
  351.     FOR i := 0 TO 5 DO
  352.         Digit(i, i + 1)  (* 123456 *)
  353.     END;
  354.  
  355.     SetSeg(display[1, DP]);    (* 12.3456   *)
  356.     SetSeg(display[3, COLON]); (* 12.34:56  *)
  357.     SetSeg(display[0, BAR]);   (* 12.34:56_ *)
  358.  
  359.     (* завершить запись *)
  360.     SetBits(LCD_SR, {2})  (* LCD_SR_UDR = {2} *)
  361. END main;
  362.  
  363.  
  364. BEGIN
  365.     main
  366. END LCD.