LCD.ob07 9.3 KB

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