max7219_8x8led_4in1.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // Copyright 2021 IOsetting <iosetting(at)outlook.com>
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * Demo: MAX7219 8x8 LED Matrix 4 in 1
  16. * Board: STC8H1K08
  17. *
  18. * P1.3 -> DIN
  19. * P1.5 -> SCLK
  20. * P1.7 -> CS
  21. */
  22. /**
  23. *
  24. * PlatformIO configuration example
  25. [env:stc8g1k08]
  26. platform = intel_mcs51
  27. board = stc8g1k08
  28. build_flags =
  29. -D__CONF_FOSC=36864000UL
  30. -D__CONF_MCU_MODEL=MCU_MODEL_STC8G1K08
  31. -D__CONF_CLKDIV=0x00
  32. -D__CONF_IRCBAND=0x01
  33. -D__CONF_VRTRIM=0x20
  34. -D__CONF_IRTRIM=0xA3
  35. -D__CONF_LIRTRIM=0x03
  36. upload_protocol = custom
  37. upload_port = /dev/ttyUSB0
  38. upload_speed = 115200
  39. upload_flags =
  40. -p$UPLOAD_PORT
  41. -s$UPLOAD_SPEED
  42. -e
  43. upload_command = ${platformio.packages_dir}/tool-stc8prog/stc8prog $UPLOAD_FLAGS -f $SOURCE
  44. */
  45. #include "fw_hal.h"
  46. #define MAX7219_CS P17
  47. #define MAX7219_BLOCKS 4
  48. #define DECODE_MODE 0x09
  49. #define INTENSITY 0x0A
  50. #define SCAN_LIMIT 0x0B
  51. #define SHUT_DOWN 0x0C
  52. #define DISPLAY_TEST 0x0F
  53. const uint8_t numbers[]={
  54. 0x3e,0x63,0x63,0x7f,0x63,0x63,0x63,0x63, //A
  55. 0x7e,0x63,0x63,0x7e,0x63,0x63,0x63,0x7e, //B
  56. 0x3e,0x63,0x63,0x60,0x60,0x63,0x63,0x3e, //C
  57. 0x7e,0x63,0x63,0x63,0x63,0x63,0x63,0x7e, //D
  58. 0x7f,0x60,0x60,0x7f,0x60,0x60,0x60,0x7f, //E
  59. 0x7f,0x60,0x60,0x7e,0x60,0x60,0x60,0x60, //F
  60. 0x3e,0x63,0x63,0x60,0x67,0x63,0x63,0x3e, //G
  61. 0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x63, //H
  62. 0x3f,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3f, //I
  63. 0x1f,0x06,0x06,0x06,0x06,0x66,0x66,0x3c, //J
  64. 0x63,0x66,0x6c,0x78,0x6c,0x66,0x63,0x61, //K
  65. 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7f, //L
  66. 0x63,0x77,0x7f,0x6b,0x63,0x63,0x63,0x63, //M
  67. 0x63,0x63,0x73,0x7b,0x6f,0x67,0x63,0x63, //N
  68. 0x3e,0x63,0x63,0x63,0x63,0x63,0x63,0x3e, //O
  69. 0x7e,0x63,0x63,0x63,0x7e,0x60,0x60,0x60, //P
  70. 0x3c,0x66,0x66,0x66,0x66,0x6e,0x66,0x3f, //Q
  71. 0x7e,0x63,0x63,0x63,0x7e,0x6c,0x66,0x63, //R
  72. 0x3e,0x63,0x63,0x60,0x3e,0x03,0x63,0x3e, //S
  73. 0x3f,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, //T
  74. 0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3e, //U
  75. 0x63,0x63,0x63,0x63,0x63,0x36,0x1c,0x08, //V
  76. 0x63,0x63,0x63,0x63,0x6b,0x7f,0x77,0x63, //W
  77. 0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x63, //X
  78. 0x33,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x0c, //Y
  79. 0x7f,0x03,0x06,0x0c,0x18,0x30,0x60,0x7f, //Z
  80. 0x3e,0x63,0x73,0x6b,0x67,0x63,0x63,0x3e, //0
  81. 0x0c,0x1c,0x3c,0x0c,0x0c,0x0c,0x0c,0x3f, //1
  82. 0x3e,0x63,0x63,0x06,0x0c,0x18,0x30,0x7f, //2
  83. 0x3e,0x63,0x63,0x0e,0x03,0x63,0x63,0x3e, //3
  84. 0x06,0x0e,0x1e,0x36,0x66,0x7f,0x06,0x06, //4
  85. 0x7f,0x60,0x60,0x7e,0x03,0x03,0x03,0x7e, //5
  86. 0x3e,0x63,0x60,0x7e,0x63,0x63,0x63,0x3e, //6
  87. 0x7f,0x03,0x03,0x06,0x0c,0x18,0x18,0x18, //7
  88. 0x3e,0x63,0x63,0x3e,0x63,0x63,0x63,0x3e, //8
  89. 0x3e,0x63,0x63,0x63,0x3f,0x03,0x63,0x3e, //9
  90. };
  91. uint8_t val[MAX7219_BLOCKS];
  92. uint8_t character_len = sizeof(numbers) / 8;
  93. void MAX7219_singeWrite(uint8_t index, uint8_t addr, uint8_t dat)
  94. {
  95. index = index % MAX7219_BLOCKS;
  96. MAX7219_CS = 0;
  97. SPI_TxRx(addr);
  98. SPI_TxRx(dat);
  99. while(index--)
  100. {
  101. SPI_TxRx(addr);
  102. SPI_TxRx(dat);
  103. }
  104. MAX7219_CS = 1;
  105. }
  106. void MAX7219_multiWrite(uint8_t addr, uint8_t len, uint8_t* dat)
  107. {
  108. MAX7219_CS = 0;
  109. while (len--)
  110. {
  111. SPI_TxRx(addr);
  112. SPI_TxRx(*dat++);
  113. }
  114. MAX7219_CS = 1;
  115. }
  116. void MAX7219_init(void)
  117. {
  118. for (uint8_t i = 0; i < MAX7219_BLOCKS; i++)
  119. {
  120. MAX7219_singeWrite(i, SHUT_DOWN, 0x01); // 0x00:shutdown, 0x01:normal
  121. MAX7219_singeWrite(i, DECODE_MODE, 0x00); // Bypass code B decoder, no-decode operation
  122. MAX7219_singeWrite(i, SCAN_LIMIT, 0x07); // Scan-limit, 0:1-digit, 1:2-digits, ..., 7:8-digits
  123. MAX7219_singeWrite(i, INTENSITY, 0x00); // 0x00:min, 0xFF:max
  124. MAX7219_singeWrite(i, DISPLAY_TEST, 0x00); // 0x00:normal, 0x01:test mode
  125. }
  126. }
  127. void SPI_init(void)
  128. {
  129. // MAX7219 can work with frequency up to 20MHz
  130. SPI_SetClockPrescaler(SPI_ClockPreScaler_4);
  131. // Clock idles low
  132. SPI_SetClockPolarity(HAL_State_OFF);
  133. // Data transfer is driven by lower SS pin
  134. SPI_SetClockPhase(SPI_ClockPhase_LeadingEdge);
  135. // MSB first
  136. SPI_SetDataOrder(SPI_DataOrder_MSB);
  137. // Define the output pins
  138. SPI_SetPort(SPI_AlterPort_P12P54_P13_P14_P15);
  139. // Ignore SS pin, use MSTR to swith between master/slave mode
  140. SPI_IgnoreSlaveSelect(HAL_State_ON);
  141. // Master mode
  142. SPI_SetMasterMode(HAL_State_ON);
  143. // Start SPI
  144. SPI_SetEnabled(HAL_State_ON);
  145. }
  146. void main()
  147. {
  148. /**
  149. * ________________________
  150. * | |
  151. * |_______________________|
  152. * A B
  153. *
  154. * pos: point to the bit for boundary A
  155. * lpos: point to the bit for boundary B
  156. */
  157. uint16_t pos = 0, lpos = 0;
  158. uint8_t i, j, cpos = 0, bpos = 0, tcpos = 0;
  159. SYS_SetClock();
  160. // Configure GPIO pins before SPI and device
  161. // DIN(P13)
  162. GPIO_P1_SetMode(GPIO_Pin_3, GPIO_Mode_InOut_QBD);
  163. // SCLK(P15), CS(P17)
  164. GPIO_P1_SetMode(GPIO_Pin_5|GPIO_Pin_7, GPIO_Mode_Output_PP);
  165. // Configure SPI and device
  166. SPI_init();
  167. MAX7219_init();
  168. while(1)
  169. {
  170. lpos = pos + sizeof(numbers) - MAX7219_BLOCKS * 8;
  171. cpos = lpos / 8; // char position
  172. bpos = lpos % 8; // bit position
  173. for (i = 0; i < 8; i++) // fill each line
  174. {
  175. for (j = 0; j < MAX7219_BLOCKS; j++)
  176. {
  177. tcpos = (cpos + j) % character_len;
  178. val[j] = numbers[tcpos * 8 + i] << bpos;
  179. tcpos = (cpos + j + 1) % character_len;
  180. val[j] |= numbers[tcpos * 8 + i] >> (8 - bpos);
  181. }
  182. MAX7219_multiWrite(i + 1, MAX7219_BLOCKS, val);
  183. }
  184. pos = (pos + 1) % sizeof(numbers);
  185. SYS_Delay(50);
  186. }
  187. }