ssd1306.lst 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. C51 COMPILER V9.54 SSD1306 09/19/2022 22:36:48 PAGE 1
  2. C51 COMPILER V9.54, COMPILATION OF MODULE SSD1306
  3. OBJECT MODULE PLACED IN .\Objects\ssd1306.obj
  4. COMPILER INVOKED BY: D:\Keil5 C51\C51\BIN\C51.EXE ssd1306.c OPTIMIZE(8,SPEED) BROWSE DEBUG OBJECTEXTEND PRINT(.\Listings
  5. -\ssd1306.lst) TABS(2) OBJECT(.\Objects\ssd1306.obj)
  6. line level source
  7. 1 /*
  8. 2 ssd1306.c
  9. 3
  10. 4 Driver for SSD1306 IC with SPI Interface
  11. 5
  12. 6 Copyright (c) 2020 Creative Lau (creativelaulab@gmail.com)
  13. 7
  14. 8 Permission is hereby granted, free of charge, to any person obtaining a copy
  15. 9 of this software and associated documentation files (the "Software"), to deal
  16. 10 in the Software without restriction, including without limitation the rights
  17. 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. 12 copies of the Software, and to permit persons to whom the Software is
  19. 13 furnished to do so, subject to the following conditions:
  20. 14
  21. 15 The above copyright notice and this permission notice shall be included in all
  22. 16 copies or substantial portions of the Software.
  23. 17
  24. 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. 24 SOFTWARE.
  31. 25
  32. 26 Note:
  33. 27
  34. 28 版本:V0.2
  35. 29 作者:老刘爱捣鼓
  36. 30 时间:2020-04-24
  37. 31 老刘爱捣鼓(全网同名)期待您的关注!
  38. 32
  39. 33 说明:
  40. 34 为Mini DSO这个项目临时编写的SSD1306 128x64驱动,并不完善
  41. 35 有写字符,字符串,数字,16x16中文字符,画水平线,垂直线,任意两点线段,绘制图片等功能
  42. 36 主要参考了Arduino中Adafruit SSD1306的库函数
  43. 37 采用全屏buf驱动,需占用128x8个uint8内存空间
  44. 38 全屏缓存操控屏幕内容比较方便,刷新速度快,但对单片机的内存大小有要求
  45. 39 F6x8字体来自中景园电子的DEMO
  46. 40
  47. 41 2020-04-30
  48. 42 1. 更新OLED_Draw_Byte函数,修正以覆盖方式跨页写入时会同时修改两页内容,上下页的其他字符被覆盖,现在可
  49. -以在任意点写入字符,不会影响上下页的内容
  50. 43 2. 优化算法/8改为>>3,%8改为&7
  51. 44 3. 修正OLED初始化错误,行模式要设置0x21和0x22设置显示范围,并用0x40设置起始行,
  52. 45 0xB0-0xB7设置起始页是页面模式专用,在行模式下使用会造成设置的起始页第一次到达结尾时无法自动换页
  53. 46 4. 删除OLED_Set_Pos中多余的设置内存位置命令
  54. 47 5. 画线或像素时,置位OLED_Reverse则进行擦除
  55. 48 */
  56. 49 #include "ssd1306.h"
  57. *** WARNING C318 IN LINE 33 OF ssd1306.h: can't open file 'delay.h'
  58. 50 #include "ssd1306font.h"
  59. *** WARNING C318 IN LINE 50 OF ssd1306.c: can't open file 'ssd1306font.h'
  60. 51
  61. C51 COMPILER V9.54 SSD1306 09/19/2022 22:36:48 PAGE 2
  62. 52 //OLED的显存
  63. 53 //存放格式如下.
  64. 54 //[0]0 1 2 3 ... 127
  65. 55 //[1]0 1 2 3 ... 127
  66. 56 //[2]0 1 2 3 ... 127
  67. 57 //[3]0 1 2 3 ... 127
  68. 58 //[4]0 1 2 3 ... 127
  69. 59 //[5]0 1 2 3 ... 127
  70. 60 //[6]0 1 2 3 ... 127
  71. 61 //[7]0 1 2 3 ... 127
  72. 62
  73. 63 #define uint8 unsigned char;
  74. *** WARNING C317 IN LINE 63 OF ssd1306.c: attempt to redefine macro 'uint8'
  75. 64 #define uint16 unsigned int;
  76. *** WARNING C317 IN LINE 64 OF ssd1306.c: attempt to redefine macro 'uint16'
  77. 65
  78. 66 #ifndef _swap_char
  79. 67 #define _swap_char(a, b) \
  80. 68 { \
  81. 69 uint8 t = a; \
  82. 70 a = b; \
  83. 71 b = t; \
  84. 72 }
  85. 73 #endif
  86. 74
  87. 75 bit _OLED_Reverse = 0;
  88. 76 bit _OLED_Overlap = 1;
  89. 77 uint8 _buf[WIDTH * PAGES]; //全屏缓存,横向WIDTH个像素,纵向PAGES页,页内每8个像素作为一个字节,共WIDTH * P
  90. -AGES个字节
  91. 78
  92. 79 static char _x, _y;
  93. 80 static uint8 _Font_Width = 6;
  94. 81
  95. 82
  96. 83
  97. 84 /* 绘制一个像素至缓存
  98. 85 Draw one pixel to buffer */
  99. 86 void OLED_DrawPixel(uint8 x, uint8 y)
  100. 87 {
  101. 88 1 uint8 mask;
  102. 89 1 uint8 *pBuf;
  103. 90 1
  104. 91 1 if (_x > WIDTH - 1)
  105. 92 1 {
  106. 93 2 _x = 0;
  107. 94 2 _y += 1;
  108. 95 2 }
  109. 96 1 if (_y > HEIGHT - 1)
  110. 97 1 {
  111. 98 2 _y = 0;
  112. 99 2 }
  113. 100 1
  114. 101 1 pBuf = &_buf[(y >> 3) * WIDTH + x];
  115. 102 1 mask = 1 << (y & 7);
  116. 103 1 if (_OLED_Reverse)
  117. 104 1 {
  118. 105 2 *pBuf++ &= ~mask;
  119. 106 2 }
  120. 107 1 else
  121. 108 1 {
  122. 109 2 *pBuf++ |= mask;
  123. 110 2 }
  124. C51 COMPILER V9.54 SSD1306 09/19/2022 22:36:48 PAGE 3
  125. 111 1 }
  126. 112
  127. 113
  128. 114 /* 绘制两点线段至缓存
  129. 115 Draw line between two points to buffer */
  130. 116 void OLED_DrawLine(uint8 x0, uint8 y0, uint8 x1, uint8 y1)
  131. 117 {
  132. 118 1 char dx, dy, ystep;
  133. 119 1 int err;
  134. 120 1 bit swapxy = 0;
  135. 121 1
  136. 122 1 if (x0 > WIDTH - 1)
  137. 123 1 x0 = WIDTH - 1;
  138. 124 1
  139. 125 1 if (y0 > HEIGHT - 1)
  140. 126 1 y0 = HEIGHT - 1;
  141. 127 1
  142. 128 1 if (x1 > WIDTH - 1)
  143. 129 1 x1 = WIDTH - 1;
  144. 130 1
  145. 131 1 if (y1 > HEIGHT - 1)
  146. 132 1 y1 = HEIGHT - 1;
  147. 133 1
  148. 134 1 dx = abs(x1 - x0);
  149. 135 1 dy = abs(y1 - y0);
  150. 136 1
  151. 137 1 if (dy > dx)
  152. 138 1 {
  153. 139 2 swapxy = 1;
  154. 140 2 _swap_char(dx, dy);
  155. 141 2 _swap_char(x0, y0);
  156. 142 2 _swap_char(x1, y1);
  157. 143 2 }
  158. 144 1
  159. 145 1 if (x0 > x1)
  160. 146 1 {
  161. 147 2 _swap_char(x0, x1);
  162. 148 2 _swap_char(y0, y1);
  163. 149 2 }
  164. 150 1
  165. 151 1 err = dx >> 1;
  166. 152 1
  167. 153 1 if (y0 < y1)
  168. 154 1 {
  169. 155 2 ystep = 1;
  170. 156 2 }
  171. 157 1 else
  172. 158 1 {
  173. 159 2 ystep = -1;
  174. 160 2 }
  175. 161 1
  176. 162 1 for (; x0 <= x1; x0++)
  177. 163 1 {
  178. 164 2 if (swapxy == 0)
  179. 165 2 OLED_DrawPixel(x0, y0);
  180. 166 2 else
  181. 167 2 OLED_DrawPixel(y0, x0);
  182. 168 2
  183. 169 2 err -= dy;
  184. 170 2
  185. 171 2 if (err < 0)
  186. 172 2 {
  187. C51 COMPILER V9.54 SSD1306 09/19/2022 22:36:48 PAGE 4
  188. 173 3 y0 += ystep;
  189. 174 3 err += dx;
  190. 175 3 }
  191. 176 2 }
  192. 177 1 }
  193. 178
  194. 179 /* 绘制垂直线至缓存
  195. 180 Draw vertical line to buffer*/
  196. 181 void OLED_DrawVLine(uint8 x, uint8 y, uint8 w)
  197. 182 {
  198. 183 1 uint8 mask;
  199. 184 1 uint8 *pBuf;
  200. 185 1
  201. 186 1 if (x > WIDTH - 1)
  202. 187 1 x = WIDTH - 1;
  203. 188 1
  204. 189 1 if (y + w > HEIGHT)
  205. 190 1 w = HEIGHT - y;
  206. 191 1
  207. 192 1 while (w--)
  208. 193 1 {
  209. 194 2 pBuf = &_buf[(y >> 3) * WIDTH + x];
  210. 195 2 mask = 1 << (y & 7);
  211. 196 2 if (_OLED_Reverse)
  212. 197 2 {
  213. 198 3 *pBuf++ &= ~mask;
  214. 199 3 }
  215. 200 2 else
  216. 201 2 {
  217. 202 3 *pBuf++ |= mask;
  218. 203 3 }
  219. 204 2 y++;
  220. 205 2 }
  221. 206 1 }
  222. 207
  223. 208 /* 绘制水平线至缓存
  224. 209 Draw horizontal line to buffer */
  225. 210 void OLED_DrawHLine(uint8 x, uint8 y, uint8 w)
  226. 211 {
  227. 212 1 uint8 *pBuf;
  228. 213 1 uint8 mask;
  229. 214 1
  230. 215 1 if (x + w > WIDTH)
  231. 216 1 w = WIDTH - x;
  232. 217 1
  233. 218 1 if (y > HEIGHT - 1)
  234. 219 1 y = HEIGHT - 1;
  235. 220 1
  236. 221 1 pBuf = &_buf[(y >> 3) * WIDTH + x];
  237. 222 1 mask = 1 << (y & 7);
  238. 223 1
  239. 224 1 while (w--)
  240. 225 1 {
  241. 226 2 if (_OLED_Reverse)
  242. 227 2 {
  243. 228 3 *pBuf++ &= ~mask;
  244. 229 3 }
  245. 230 2 else
  246. 231 2 {
  247. 232 3 *pBuf++ |= mask;
  248. 233 3 }
  249. 234 2 }
  250. C51 COMPILER V9.54 SSD1306 09/19/2022 22:36:48 PAGE 5
  251. 235 1 }
  252. 236
  253. 237
  254. 238 /* 将缓存内容显示到屏幕上
  255. 239 Send buffer to display */
  256. 240 void OLED_Display(void)
  257. 241 {
  258. 242 1 uint8 i, j;
  259. 243 1 uint8 *pBuf;
  260. 244 1 pBuf = _buf;
  261. 245 1
  262. 246 1 for (j = 0; j < PAGES; j++)
  263. 247 1 {
  264. 248 2 for (i = 0; i < WIDTH; i++)
  265. 249 2 {
  266. 250 3 OLED_Write_Data(*pBuf++);
  267. *** WARNING C206 IN LINE 250 OF ssd1306.c: 'OLED_Write_Data': missing function-prototype
  268. *** ERROR C267 IN LINE 250 OF ssd1306.c: 'OLED_Write_Data': requires ANSI-style prototype
  269. 251 3 }
  270. 252 2 }
  271. 253 1 }
  272. 254
  273. 255 /* 初始化SSD1306
  274. 256 Initialize SSD1306 */
  275. 257 void OLED_Init(void)
  276. 258 {
  277. 259 1 OLED_RST_Set();
  278. *** ERROR C202 IN LINE 259 OF ssd1306.c: 'OLED_RST': undefined identifier
  279. 260 1 Delay50ms();
  280. 261 1 OLED_RST_Clr();
  281. 262 1 Delay50ms();
  282. 263 1 OLED_RST_Set();
  283. 264 1
  284. 265 1 OLED_Write_Command(0xAE); //--Turn off oled panel
  285. 266 1
  286. 267 1 /*
  287. 268 1 以下三条命令是给页面模式用的,行模式和列模式不要设置,会引起问题
  288. 269 1 行模式或列模式,要用0x21和0x22设置范围
  289. 270 1 Following three commands are for Page Addressing Mode. Do not set them in Horizontal addressing mo
  290. -de or Vertical addressing mode, will rise problem.
  291. 271 1 For Horizontal addressing mode or Vertical addressing mode, should use 0x21 and 0x22 set column an
  292. -d page address
  293. 272 1 */
  294. 273 1 // OLED_Write_Command(0x00); //-Set Lower Column Start Address for Page Addressing Mode
  295. 274 1 // OLED_Write_Command(0x10); //-Set Higher Column Start Address for Page Addressing Mode
  296. 275 1 // OLED_Write_Command(0xB0); //-Set the page start address of the target display location by command f
  297. -or Page Addressing Mode
  298. 276 1
  299. 277 1 OLED_Write_Command(0x20); //-Set Page Addressing Mode (0x00/0x01/0x02)
  300. 278 1 OLED_Write_Command(0x00); //--0x00: Horizontal addressing mode, 0x01: Vertical addressing mode, 0x02:
  301. -Page addressing mode
  302. 279 1
  303. 280 1 OLED_Write_Command(0x21); //-Set Column Address
  304. 281 1 OLED_Write_Command(0x00); //--Start address
  305. 282 1 OLED_Write_Command(0x7f); //--End address
  306. 283 1
  307. 284 1 OLED_Write_Command(0x22); //-Set Page Address
  308. 285 1 OLED_Write_Command(0x00); //---Start address
  309. 286 1 OLED_Write_Command(0x07); //--End address
  310. 287 1
  311. 288 1 OLED_Write_Command(0x40); //-Set Display Start Line (0x40h~0x7F)
  312. 289 1
  313. C51 COMPILER V9.54 SSD1306 09/19/2022 22:36:48 PAGE 6
  314. 290 1 OLED_Write_Command(0x81); //-Set Contrast Control for BANK0
  315. 291 1 OLED_Write_Command(OLED_Brightness * 10); // -0x00 to 0xFF, The segment output current increases as
  316. - the contrast step value increases
  317. 292 1
  318. 293 1 OLED_Write_Command(0xA1); //-Set Segment Re-map. 0xA1: Normal, 0xA0: Re-map left and right
  319. 294 1 OLED_Write_Command(0xC8); //-Set COM Output Scan Direction. 0xC8: Normal, 0xC0: Re-map up and down
  320. 295 1 OLED_Write_Command(0xA6); //-Set Normal/Inverse Display, 0xA6:Normal, 0xA7: Inverse
  321. 296 1
  322. 297 1 OLED_Write_Command(0xA8); //-Set Multiplex Ratio (16~63)
  323. 298 1 OLED_Write_Command(0x3F); //--63 multiplex mode
  324. 299 1
  325. 300 1 OLED_Write_Command(0xD3); //-Set Display Offset (0x00~0x3F)
  326. 301 1 OLED_Write_Command(0x00); //--No offset
  327. 302 1
  328. 303 1 OLED_Write_Command(0xD5); //-Set display clock divide ratio/oscillator frequency
  329. 304 1 OLED_Write_Command(0x20); //--Set Clock as 60 Frames/Sec
  330. 305 1
  331. 306 1 OLED_Write_Command(0xD9); //-Set pre-charge period
  332. 307 1 OLED_Write_Command(0xF2); //--Set Pre-Charge as 15 Clocks & Discharge as 2 Clock
  333. 308 1
  334. 309 1 OLED_Write_Command(0xDA); //-Set com pins hardware configuration
  335. 310 1 OLED_Write_Command(0x12); //
  336. 311 1
  337. 312 1 OLED_Write_Command(0xDB); //-Set VCOM Deselect Level
  338. 313 1 OLED_Write_Command(0x30); //--0.83xVcc
  339. 314 1
  340. 315 1 OLED_Write_Command(0x8D); //-Set Charge Pump enable/disable
  341. 316 1 OLED_Write_Command(0x14); //--0x14: Enable, 0x10: Disable
  342. 317 1
  343. 318 1 OLED_Write_Command(0xA4); //-Entire Display ON, 0xA4: Disable, 0xA5: Enable
  344. 319 1 OLED_Write_Command(0xAF); //-Turn on oled panel
  345. 320 1 }
  346. C51 COMPILATION COMPLETE. 5 WARNING(S), 2 ERROR(S)