Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
8097 maxcodehac 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.