forked from KolibriOS/kolibrios
2f54c7de00
git-svn-id: svn://kolibrios.org@8097 a494cfbc-eb01-0410-851d-a64ba20cac60
366 lines
8.8 KiB
Plaintext
366 lines
8.8 KiB
Plaintext
(*
|
||
Пример для STM32L152C-DISCO
|
||
|
||
Работа со встроенным ЖКИ.
|
||
|
||
использовано:
|
||
https://habr.com/ru/post/173709/
|
||
*)
|
||
|
||
MODULE LCD;
|
||
|
||
IMPORT SYSTEM;
|
||
|
||
|
||
CONST
|
||
|
||
GPIOA = 40020000H;
|
||
GPIOAMODER = GPIOA;
|
||
GPIOAOTYPER = GPIOA + 04H;
|
||
GPIOAOSPEEDR = GPIOA + 08H;
|
||
GPIOAPUPDR = GPIOA + 0CH;
|
||
GPIOAIDR = GPIOA + 10H;
|
||
GPIOAODR = GPIOA + 14H;
|
||
GPIOABSRR = GPIOA + 18H;
|
||
GPIOALCKR = GPIOA + 1CH;
|
||
GPIOAAFRL = GPIOA + 20H;
|
||
GPIOAAFRH = GPIOA + 24H;
|
||
GPIOABRR = GPIOA + 28H;
|
||
|
||
|
||
GPIOB = 40020400H;
|
||
GPIOBMODER = GPIOB;
|
||
GPIOBOTYPER = GPIOB + 04H;
|
||
GPIOBOSPEEDR = GPIOB + 08H;
|
||
GPIOBPUPDR = GPIOB + 0CH;
|
||
GPIOBIDR = GPIOB + 10H;
|
||
GPIOBODR = GPIOB + 14H;
|
||
GPIOBBSRR = GPIOB + 18H;
|
||
GPIOBLCKR = GPIOB + 1CH;
|
||
GPIOBAFRL = GPIOB + 20H;
|
||
GPIOBAFRH = GPIOB + 24H;
|
||
GPIOBBRR = GPIOB + 28H;
|
||
|
||
|
||
GPIOC = 40020800H;
|
||
GPIOCMODER = GPIOC;
|
||
GPIOCOTYPER = GPIOC + 04H;
|
||
GPIOCOSPEEDR = GPIOC + 08H;
|
||
GPIOCPUPDR = GPIOC + 0CH;
|
||
GPIOCIDR = GPIOC + 10H;
|
||
GPIOCODR = GPIOC + 14H;
|
||
GPIOCBSRR = GPIOC + 18H;
|
||
GPIOCLCKR = GPIOC + 1CH;
|
||
GPIOCAFRL = GPIOC + 20H;
|
||
GPIOCAFRH = GPIOC + 24H;
|
||
GPIOCBRR = GPIOC + 28H;
|
||
|
||
|
||
RCC = 40023800H;
|
||
RCC_CR = RCC;
|
||
RCC_AHBENR = RCC + 1CH;
|
||
RCC_APB2ENR = RCC + 20H;
|
||
RCC_APB1ENR = RCC + 24H;
|
||
RCC_CSR = RCC + 34H;
|
||
|
||
|
||
PWR = 40007000H;
|
||
PWR_CR = PWR;
|
||
|
||
|
||
LCD = 40002400H;
|
||
LCD_CR = LCD;
|
||
LCD_FCR = LCD + 04H;
|
||
LCD_SR = LCD + 08H;
|
||
LCD_RAM = LCD + 14H;
|
||
|
||
|
||
AFM = 2;
|
||
|
||
AF11 = 11;
|
||
|
||
PinsA = {1..3, 8..10, 15};
|
||
PinsB = {3..5, 8..15};
|
||
PinsC = {0..3, 6..11};
|
||
|
||
A = 0; H = 7;
|
||
B = 1; J = 8;
|
||
C = 2; K = 9;
|
||
D = 3; M = 10;
|
||
E = 4; N = 11;
|
||
F = 5; P = 12;
|
||
G = 6; Q = 13;
|
||
|
||
DP = 14; COLON = 15; BAR = 16;
|
||
|
||
|
||
VAR
|
||
display: ARRAY 6, 17 OF INTEGER;
|
||
|
||
digits: ARRAY 10 OF SET;
|
||
|
||
|
||
PROCEDURE SetPinsMode (reg: INTEGER; pins: SET; mode: INTEGER);
|
||
VAR
|
||
x: SET;
|
||
pin: INTEGER;
|
||
|
||
BEGIN
|
||
mode := mode MOD 4;
|
||
SYSTEM.GET(reg, x);
|
||
FOR pin := 0 TO 30 BY 2 DO
|
||
IF (pin DIV 2) IN pins THEN
|
||
x := x - {pin, pin + 1} + BITS(LSL(mode, pin))
|
||
END
|
||
END;
|
||
SYSTEM.PUT(reg, x)
|
||
END SetPinsMode;
|
||
|
||
|
||
PROCEDURE SRBits (adr: INTEGER; setbits, resetbits: SET);
|
||
VAR
|
||
x: SET;
|
||
|
||
BEGIN
|
||
SYSTEM.GET(adr, x);
|
||
SYSTEM.PUT(adr, x - resetbits + setbits)
|
||
END SRBits;
|
||
|
||
|
||
PROCEDURE SetBits (adr: INTEGER; bits: SET);
|
||
VAR
|
||
x: SET;
|
||
|
||
BEGIN
|
||
SYSTEM.GET(adr, x);
|
||
SYSTEM.PUT(adr, x + bits)
|
||
END SetBits;
|
||
|
||
|
||
PROCEDURE ResetBits (adr: INTEGER; bits: SET);
|
||
VAR
|
||
x: SET;
|
||
|
||
BEGIN
|
||
SYSTEM.GET(adr, x);
|
||
SYSTEM.PUT(adr, x - bits)
|
||
END ResetBits;
|
||
|
||
|
||
PROCEDURE TestBits (adr: INTEGER; bits: SET): BOOLEAN;
|
||
VAR
|
||
x: SET;
|
||
|
||
BEGIN
|
||
SYSTEM.GET(adr, x);
|
||
RETURN x * bits = bits
|
||
END TestBits;
|
||
|
||
|
||
PROCEDURE Init;
|
||
VAR
|
||
i, j: INTEGER;
|
||
seg: ARRAY 30 OF INTEGER;
|
||
|
||
BEGIN
|
||
FOR i := 0 TO 29 DO
|
||
seg[i] := i
|
||
END;
|
||
|
||
FOR i := 3 TO 11 DO
|
||
seg[i] := i + 4
|
||
END;
|
||
|
||
seg[18] := 17;
|
||
seg[19] := 16;
|
||
|
||
FOR i := 20 TO 23 DO
|
||
seg[i] := i - 2
|
||
END;
|
||
|
||
j := 0;
|
||
FOR i := 0 TO 5 DO
|
||
display[i, A] := 256 + seg[28 - j];
|
||
display[i, B] := 0 + seg[28 - j];
|
||
display[i, C] := 256 + seg[j + 1];
|
||
display[i, D] := 256 + seg[j];
|
||
display[i, E] := 0 + seg[j];
|
||
display[i, F] := 256 + seg[29 - j];
|
||
display[i, G] := 0 + seg[29 - j];
|
||
display[i, H] := 768 + seg[29 - j];
|
||
display[i, J] := 768 + seg[28 - j];
|
||
display[i, K] := 512 + seg[28 - j];
|
||
display[i, M] := 0 + seg[j + 1];
|
||
display[i, N] := 768 + seg[j];
|
||
display[i, P] := 512 + seg[j];
|
||
display[i, Q] := 512 + seg[29 - j];
|
||
INC(j, 2)
|
||
END;
|
||
|
||
display[0, DP] := 768 + 1;
|
||
display[1, DP] := 768 + 7;
|
||
display[2, DP] := 768 + 9;
|
||
display[3, DP] := 768 + 11;
|
||
|
||
display[0, COLON] := 512 + 1;
|
||
display[1, COLON] := 512 + 7;
|
||
display[2, COLON] := 512 + 9;
|
||
display[3, COLON] := 512 + 11;
|
||
|
||
display[0, BAR] := 768 + 15;
|
||
display[1, BAR] := 512 + 15;
|
||
display[2, BAR] := 768 + 13;
|
||
display[3, BAR] := 512 + 13;
|
||
|
||
digits[0] := {A, B, C, D, E, F};
|
||
digits[1] := {B, C};
|
||
digits[2] := {A, B, M, G, E, D};
|
||
digits[3] := {A, B, M, G, C, D};
|
||
digits[4] := {F, G, M, B, C};
|
||
digits[5] := {A, F, G, M, C, D};
|
||
digits[6] := {A, F, G, M, C, D, E};
|
||
digits[7] := {F, A, B, C};
|
||
digits[8] := {A, B, C, D, E, F, G, M};
|
||
digits[9] := {A, B, C, D, F, G, M};
|
||
END Init;
|
||
|
||
|
||
PROCEDURE ResetSeg (seg: INTEGER);
|
||
BEGIN
|
||
ResetBits(LCD_RAM + (seg DIV 256) * 2 * 4, {seg MOD 256})
|
||
END ResetSeg;
|
||
|
||
|
||
PROCEDURE SetSeg (seg: INTEGER);
|
||
BEGIN
|
||
SetBits(LCD_RAM + (seg DIV 256) * 2 * 4, {seg MOD 256})
|
||
END SetSeg;
|
||
|
||
|
||
PROCEDURE Digit (pos, dgt: INTEGER);
|
||
VAR
|
||
s: SET;
|
||
i: INTEGER;
|
||
|
||
BEGIN
|
||
s := digits[dgt];
|
||
FOR i := 0 TO 13 DO
|
||
IF i IN s THEN
|
||
SetSeg(display[pos, i])
|
||
ELSE
|
||
ResetSeg(display[pos, i])
|
||
END
|
||
END
|
||
END Digit;
|
||
|
||
|
||
PROCEDURE WhileBits (adr: INTEGER; bits: SET);
|
||
BEGIN
|
||
WHILE TestBits(adr, bits) DO END
|
||
END WhileBits;
|
||
|
||
|
||
PROCEDURE UntilBits (adr: INTEGER; bits: SET);
|
||
BEGIN
|
||
REPEAT UNTIL TestBits(adr, bits)
|
||
END UntilBits;
|
||
|
||
|
||
PROCEDURE main;
|
||
VAR
|
||
i: INTEGER;
|
||
|
||
BEGIN
|
||
Init;
|
||
|
||
(* подключить GPIOA, GPIOB, GPIOC *)
|
||
SetBits(RCC_AHBENR, {0, 1, 2});
|
||
|
||
(* настроить на режим альтернативной функции *)
|
||
SetPinsMode(GPIOAMODER, PinsA, AFM);
|
||
|
||
(* 400 кГц *)
|
||
SetPinsMode(GPIOAOSPEEDR, PinsA, 0);
|
||
|
||
(* без подтягивающих резисторов *)
|
||
SetPinsMode(GPIOAPUPDR, PinsA, 0);
|
||
|
||
(* режим push-pull *)
|
||
ResetBits(GPIOAOTYPER, PinsA);
|
||
|
||
(* альтернативная функция AF11 = 0BH *)
|
||
SYSTEM.PUT(GPIOAAFRL, 0BBB0H);
|
||
SYSTEM.PUT(GPIOAAFRH, 0B0000BBBH);
|
||
|
||
(* аналогично для GPIOB *)
|
||
SetPinsMode(GPIOBMODER, PinsB, AFM);
|
||
SetPinsMode(GPIOBOSPEEDR, PinsB, 0);
|
||
SetPinsMode(GPIOBPUPDR, PinsB, 0);
|
||
ResetBits(GPIOBOTYPER, PinsB);
|
||
SYSTEM.PUT(GPIOBAFRL, 000BBB000H);
|
||
SYSTEM.PUT(GPIOBAFRH, 0BBBBBBBBH);
|
||
|
||
(* аналогично для GPIOC *)
|
||
SetPinsMode(GPIOCMODER, PinsC, AFM);
|
||
SetPinsMode(GPIOCOSPEEDR, PinsC, 0);
|
||
SetPinsMode(GPIOCPUPDR, PinsC, 0);
|
||
ResetBits(GPIOCOTYPER, PinsC);
|
||
SYSTEM.PUT(GPIOCAFRL, 0BB00BBBBH);
|
||
SYSTEM.PUT(GPIOCAFRH, 00000BBBBH);
|
||
|
||
(* подключить контроллер ЖКИ *)
|
||
SetBits(RCC_APB1ENR, {9, 28}); (* LCDEN = {9}; PWREN = {28} *)
|
||
|
||
(* разрешить запись в регистр RCC_CSR *)
|
||
SetBits(PWR_CR, {8}); (* DBP = {8} *)
|
||
|
||
(* сбросить источник тактирования *)
|
||
SetBits(RCC_CSR, {23}); (* RTCRST = {23} *)
|
||
|
||
(* выбрать новый источник *)
|
||
ResetBits(RCC_CSR, {23}); (* RTCRST = {23} *)
|
||
|
||
(* включить НЧ генератор *)
|
||
SetBits(RCC_CSR, {8}); (* LSEON = {8} *)
|
||
|
||
(* ждать готовность НЧ генератора *)
|
||
UntilBits(RCC_CSR, {9}); (* LSERDY = {9} *)
|
||
|
||
(* выбрать НЧ генератор как источник тактирования *)
|
||
SRBits(RCC_CSR, {16}, {17}); (* RCC_CSR[17:16] := 01b *)
|
||
|
||
(* настроить контроллер ЖКИ *)
|
||
SRBits(LCD_CR, {2, 3, 6, 7}, {4, 5}); (* MUX_SEG = {7}; BIAS1 = {6}; BIAS0 = {5}; DUTY2 = {4}; DUTY1 = {3}; DUTY0 = {2} *)
|
||
|
||
(* Установить значения коэффициентов деления частоты тактового сигнала LCDCLK *)
|
||
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 *)
|
||
|
||
(* ждать синхронизацию регистра LCD_FCR *)
|
||
UntilBits(LCD_SR, {5}); (* FCRSF = {5} *)
|
||
|
||
(* выбрать внутренний источник напряжения для ЖКИ и разрешить его работу *)
|
||
SRBits(LCD_CR, {0}, {1}); (* LCD_CR_VSEL = {1}; LCD_CR_LCDEN = {0} *)
|
||
|
||
(* ждать готовность контроллера ЖКИ *)
|
||
UntilBits(LCD_SR, {0, 4}); (* LCD_SR_RDY = {4}; LCD_SR_ENS = {0} *)
|
||
|
||
(* ждать завершение предыдущей записи *)
|
||
WhileBits(LCD_SR, {2}); (* LCD_SR_UDR = {2} *)
|
||
|
||
(* начать запись *)
|
||
FOR i := 0 TO 5 DO
|
||
Digit(i, i + 1) (* 123456 *)
|
||
END;
|
||
|
||
SetSeg(display[1, DP]); (* 12.3456 *)
|
||
SetSeg(display[3, COLON]); (* 12.34:56 *)
|
||
SetSeg(display[0, BAR]); (* 12.34:56_ *)
|
||
|
||
(* завершить запись *)
|
||
SetBits(LCD_SR, {2}) (* LCD_SR_UDR = {2} *)
|
||
END main;
|
||
|
||
|
||
BEGIN
|
||
main
|
||
END LCD. |