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. |