display_driver.ino 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include <SoftI2C.h>
  2. #include "display_char.h"
  3. // Address of the I2C OLED
  4. #define OLED_I2C_ADDRESS 0x3C
  5. // Commands for SSD1306
  6. #define SSD1306_DISPLAYOFF 0xAE
  7. #define SSD1306_SETDISPLAYCLOCKDIV 0xD5
  8. #define SSD1306_SETMULTIPLEX 0xA8
  9. #define SSD1306_SETDISPLAYOFFSET 0xD3
  10. #define SSD1306_SETSTARTLINE 0x40
  11. #define SSD1306_CHARGEPUMP 0x8D
  12. #define SSD1306_MEMORYMODE 0x20
  13. #define SSD1306_SEGREMAP 0xA1
  14. #define SSD1306_COMSCANDEC 0xC8
  15. #define SSD1306_SETCOMPINS 0xDA
  16. #define SSD1306_SETCONTRAST 0x81
  17. #define SSD1306_SETPRECHARGE 0xD9
  18. #define SSD1306_SETVCOMDETECT 0xDB
  19. #define SSD1306_DISPLAYALLON_RESUME 0xA4
  20. #define SSD1306_NORMALDISPLAY 0xA6
  21. #define SSD1306_DISPLAYON 0xAF
  22. //Global Variables
  23. static uint16_t display_num[10][16] = display16X16_number_R;
  24. static uint16_t display_A[16] = display16X16_A_R;
  25. static uint16_t display_C[16] = display16X16_C_R;
  26. static uint16_t display_V[16] = display16X16_V_R;
  27. static uint16_t display_blank[16] = display16X16_blank;
  28. uint8_t voltage_dec_3;
  29. uint8_t voltage_dec_2;
  30. uint8_t voltage_dec_1;
  31. uint8_t voltage_dec_0;
  32. uint8_t current_dec_2;
  33. uint8_t current_dec_1;
  34. uint8_t current_dec_0;
  35. uint16_t* display_addr_list[16];
  36. void I2CWriteCommand(uint8_t command) {
  37. I2CStart();
  38. I2CSend(OLED_I2C_ADDRESS << 1); // I2C address + Write bit
  39. I2CSend(0x00); // Co = 0, D/C# = 0
  40. I2CSend(command);
  41. I2CStop();
  42. }
  43. void I2CWriteData(uint8_t data) {
  44. I2CStart();
  45. I2CSend(OLED_I2C_ADDRESS << 1); // I2C address + Write bit
  46. I2CSend(0x40); // Co = 0, D/C# = 1
  47. I2CSend(data);
  48. I2CStop();
  49. }
  50. //Setup the OLED SoftI2C Config, call to initializeOLED to start connection
  51. void setupOLED() {
  52. scl_pin = OLED_SCL; // Default: P3.0
  53. sda_pin = OLED_SDA; // Default: P3.1
  54. I2CInit();
  55. //Setup static locations for display array
  56. display_addr_list[2] = display_blank;
  57. display_addr_list[7] = display_V;
  58. display_addr_list[10] = display_blank;
  59. display_addr_list[11] = display_blank;
  60. display_addr_list[15] = display_A;
  61. }
  62. //Start the OLED screen in desired mode
  63. void initializeOLED() {
  64. I2CWriteCommand(SSD1306_DISPLAYOFF);
  65. I2CWriteCommand(SSD1306_SETDISPLAYCLOCKDIV);
  66. I2CWriteCommand(0x80); // Suggested value
  67. I2CWriteCommand(SSD1306_SETMULTIPLEX);
  68. I2CWriteCommand(0x3F);
  69. I2CWriteCommand(SSD1306_SETDISPLAYOFFSET);
  70. I2CWriteCommand(0x00);
  71. I2CWriteCommand(SSD1306_SETSTARTLINE | 0x0);
  72. I2CWriteCommand(SSD1306_CHARGEPUMP);
  73. I2CWriteCommand(0x14);
  74. I2CWriteCommand(SSD1306_MEMORYMODE);
  75. I2CWriteCommand(0x00);
  76. I2CWriteCommand(SSD1306_SEGREMAP | 0x1);
  77. I2CWriteCommand(SSD1306_COMSCANDEC);
  78. I2CWriteCommand(SSD1306_SETCOMPINS);
  79. I2CWriteCommand(0x12);
  80. I2CWriteCommand(SSD1306_SETCONTRAST);
  81. I2CWriteCommand(0xCF);
  82. I2CWriteCommand(SSD1306_SETPRECHARGE);
  83. I2CWriteCommand(0xF1);
  84. I2CWriteCommand(SSD1306_SETVCOMDETECT);
  85. I2CWriteCommand(0x40);
  86. I2CWriteCommand(SSD1306_DISPLAYALLON_RESUME);
  87. I2CWriteCommand(SSD1306_NORMALDISPLAY);
  88. I2CWriteCommand(SSD1306_DISPLAYON);
  89. }
  90. //Clear the screen with setting all bits to 0
  91. void clearScreen() {
  92. for (uint8_t i = 0; i < 8; i++) {
  93. I2CWriteCommand(0xB0 + i); // Set page address
  94. I2CWriteCommand(0x00); // Set lower column address
  95. I2CWriteCommand(0x10); // Set higher column address
  96. for (uint8_t j = 0; j < 128; j++) {
  97. I2CWriteData(0x00);
  98. }
  99. }
  100. }
  101. //Clear the screen with setting all bits to 1
  102. void lightScreen() {
  103. for (uint8_t i = 0; i < 8; i++) {
  104. I2CWriteCommand(0xB0 + i); // Set page address
  105. I2CWriteCommand(0x00); // Set lower column address
  106. I2CWriteCommand(0x10); // Set higher column address
  107. for (uint8_t j = 0; j < 128; j++) {
  108. I2CWriteData(0xFF);
  109. }
  110. }
  111. }
  112. //Print the current power information to the screen
  113. void PS_Screen(uint16_t voltage_num, uint16_t current_num, bool CC_mode) {
  114. voltage_dec_3 = (voltage_num / 1000) % 10;
  115. voltage_dec_2 = (voltage_num / 100) % 10;
  116. voltage_dec_1 = (voltage_num / 10) % 10;
  117. voltage_dec_0 = voltage_num % 10;
  118. current_dec_2 = (current_num / 100) % 10;
  119. current_dec_1 = (current_num / 10) % 10;
  120. current_dec_0 = current_num % 10;
  121. if (!CC_mode) {
  122. display_addr_list[0] = display_C;
  123. display_addr_list[1] = display_V;
  124. display_addr_list[8] = display_blank;
  125. display_addr_list[9] = display_blank;
  126. } else {
  127. display_addr_list[0] = display_blank;
  128. display_addr_list[1] = display_blank;
  129. display_addr_list[8] = display_C;
  130. display_addr_list[9] = display_C;
  131. }
  132. display_addr_list[3] = display_num[voltage_dec_3];
  133. display_addr_list[4] = display_num[voltage_dec_2];
  134. display_addr_list[5] = display_num[voltage_dec_1];
  135. display_addr_list[6] = display_num[voltage_dec_0];
  136. display_addr_list[12] = display_num[current_dec_2];
  137. display_addr_list[13] = display_num[current_dec_1];
  138. display_addr_list[14] = display_num[current_dec_0];
  139. uint8_t push_temp;
  140. uint8_t readed_byte;
  141. for (uint8_t i = 0; i < 8; i++) {
  142. //Set editing page number
  143. I2CStart();
  144. I2CSend(OLED_I2C_ADDRESS << 1); // I2C address + Write bit
  145. I2CSend(0xB0 + i); // Set page address
  146. //I2CSend(0x00); // Set lower column address
  147. //I2CSend(0x10); // Set higher column address
  148. //Start sending page data
  149. I2CRestart();
  150. I2CSend(OLED_I2C_ADDRESS << 1); // I2C address + Write bit
  151. I2CSend(0x40); // Co = 0, D/C# = 1
  152. for (uint8_t j = 0; j < 128; j++) {
  153. if (i % 4 == 3 && (j == 79 || j == 80)) {
  154. I2CSend(0xA0);
  155. } else {
  156. push_temp = 0;
  157. readed_byte = display_addr_list[(j >> 4) + (i / 4 * 8)][j % 16] >> (i % 4 << 2);
  158. push_temp |= ((readed_byte >> 3) & 0x01) << 7;
  159. push_temp |= ((readed_byte >> 2) & 0x01) << 5;
  160. push_temp |= ((readed_byte >> 1) & 0x01) << 3;
  161. push_temp |= (readed_byte & 0x01) << 1;
  162. I2CSend(push_temp);
  163. }
  164. }
  165. I2CStop();
  166. }
  167. }