ssd1306.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #include "../i2c/ad0x0_i2c1.h"
  2. #include "../i2c/ad0x0_i2c2.h"
  3. #include "../i2c/ad0x0_i2c_ext.h"
  4. #include <string.h>
  5. #include "ssd1306.h"
  6. //unsigned char vbuf[100];
  7. #include "font.h"
  8. void OLED_Init(oled_desc_s *p_desc);
  9. void OLED_test(oled_desc_s *p_desc);
  10. void OLED_Printf(oled_desc_s *p_desc,unsigned char* buf, unsigned char size); /* ïå÷àòàåò ñòðîêó ñ ðàçìåðàìè - 0 ñàìûé ìåëêèé 2 - óâåëè÷èíûé - 3 ñàìûé áîëüøîé(òîëüêî äëÿ öèôð) */
  11. void OLED_DrawImage(unsigned char num_image); /* âûâîäèò êàðòèíêó èç ôëåø */
  12. void OLED_Bat(unsigned char y,unsigned char x, unsigned char z); /* ðèñóåò áàòàðåéêó ïî êîîðäèíàòàì z - îò 0 äî 10 äåëåíèé */
  13. void OLED_Mode(oled_desc_s *p_desc, char set_mode); /* 1 - inverted / 0 - normal */
  14. void OLED_Sleep(oled_desc_s *p_desc, char set); /* 1 - on sleep / 0 - off sleep */
  15. void OLED_Command(oled_desc_s *p_desc, unsigned char ControByte, unsigned char DataByte);
  16. void OLED_Commmand(oled_desc_s *p_desc,unsigned char ControByte, unsigned char DataByte); /* eiiaiau aeniea? eee aaiiua */
  17. void OLED_Commmand2(oled_desc_s *p_desc,unsigned char ControByte, unsigned char DataByte); /* eiiaiau aeniea? eee aaiiua */
  18. void OLED_PrintAt(oled_desc_s *p_desc, unsigned char x, unsigned char y,unsigned char* buf, unsigned char size);
  19. void OLED_Char2x(oled_desc_s *p_desc, unsigned int c); /* auaia neiaiea ia 2 no?iee*/
  20. void OLED_GotoXY(oled_desc_s *p_desc, unsigned char x, unsigned char y);
  21. void OLED_GotoXYWH(oled_desc_s *p_desc, unsigned char x, unsigned char y,unsigned char w, unsigned char h);
  22. void OLED_Clear(oled_desc_s *p_desc); /* i?enoea anaai aenieay */
  23. // void OLED_BigNum(unsigned char num); /* auaia aieuoeo oeo? */
  24. void OLED_Char(oled_desc_s *p_desc, unsigned int c); /* auaia neiaiea */
  25. oled_desc_s *p_desc_i2c1=NULL,*p_desc_i2c2=NULL;//æîïîé ÷óþ, ÷òî ïîæàëåþ, ÷òî ñóíóë âñå â îäèí ñè ôàéë
  26. //
  27. void commmand_i2c1(unsigned char ControByte, unsigned char DataByte){
  28. OLED_Command(p_desc_i2c1,ControByte,DataByte);
  29. }
  30. void commmand_i2c2(unsigned char ControByte, unsigned char DataByte){
  31. OLED_Command(p_desc_i2c2,ControByte,DataByte);
  32. }
  33. void OLED_PrintAt_i2c1(unsigned char x, unsigned char y,unsigned char* buf, unsigned char size){
  34. OLED_PrintAt(p_desc_i2c1,x,y,buf,size);
  35. }
  36. void OLED_PrintAt_i2c2(unsigned char x, unsigned char y,unsigned char* buf, unsigned char size){
  37. OLED_PrintAt(p_desc_i2c2,x,y,buf,size);
  38. }
  39. void OLED_test_i2c1(void){
  40. OLED_test(p_desc_i2c1);
  41. }
  42. void OLED_test_i2c2(void){
  43. OLED_test(p_desc_i2c2);
  44. }
  45. void OLED_clear_i2c1(void){
  46. OLED_Clear(p_desc_i2c1);
  47. }
  48. void OLED_clear_i2c2(void){
  49. OLED_Clear(p_desc_i2c2);
  50. }
  51. void OLED_Init2(I2C_TypeDef * _I2C_BASE, oled_desc_s *p_desc){
  52. memset(p_desc,0,sizeof(oled_desc_s));
  53. if(_I2C_BASE == (I2C_TypeDef *)I2C1_BASE){
  54. p_desc_i2c1=p_desc;
  55. p_desc->ad0x0_i2c_get_ext_async2=ad0x0_i2c1_get_ext_async2;
  56. p_desc->ad0x0_i2c_push=ad0x0_i2c1_push;
  57. p_desc->commmand=commmand_i2c1;
  58. p_desc->print_at=OLED_PrintAt_i2c1;
  59. p_desc->OLED_test=OLED_test_i2c1;
  60. p_desc->clear=OLED_clear_i2c1;
  61. OLED_Init(p_desc_i2c1);
  62. }else
  63. if(_I2C_BASE == (I2C_TypeDef *)I2C2_BASE){
  64. p_desc_i2c2=p_desc;
  65. p_desc->ad0x0_i2c_get_ext_async2=ad0x0_i2c2_get_ext_async2;
  66. p_desc->ad0x0_i2c_push=ad0x0_i2c2_push;
  67. p_desc->commmand=commmand_i2c2;
  68. p_desc->print_at=OLED_PrintAt_i2c2;
  69. p_desc->OLED_test=OLED_test_i2c2;
  70. p_desc->clear=OLED_clear_i2c2;
  71. OLED_Init(p_desc_i2c2);
  72. }else{
  73. ad0x0_err();
  74. }
  75. }
  76. /* ---------------------------------------------------------
  77. * OLED_init
  78. * ---------------------------------------------------------
  79. */
  80. void OLED_Init(oled_desc_s *p_desc)
  81. {
  82. //OLED_Sleep(0);
  83. p_desc->commmand(COMAND, SSD1306_DISPLAYOFF);
  84. //HAL_Delay(10);
  85. ad0x0_i2c1_push(ADQ_DELAY_MS,100);
  86. p_desc->commmand(COMAND, SSD1306_DISPLAYON);
  87. ad0x0_i2c1_push(ADQ_DELAY_MS,100);
  88. p_desc->commmand(COMAND, SSD1306_SETCONTRAST);
  89. p_desc->commmand(COMAND, 0x7f);
  90. p_desc->commmand(COMAND, SSD1306_SETDISPLAYCLOCKDIV);
  91. p_desc->commmand(COMAND, 0x80);
  92. p_desc->commmand(COMAND, SSD1306_SETMULTIPLEX);
  93. p_desc->commmand(COMAND, 0x3F);
  94. p_desc->commmand(COMAND, SSD1306_SETDISPLAYOFFSET);
  95. p_desc->commmand(COMAND, 0x00);
  96. p_desc->commmand(COMAND, SSD1306_SETSTARTLINE | 0x00);
  97. /* We use internal charge pump */
  98. p_desc->commmand(COMAND, SSD1306_CHARGEPUMP);
  99. p_desc->commmand(COMAND, 0x14);
  100. /* Horizontal memory mode */
  101. p_desc->commmand(COMAND, SSD1306_MEMORYMODE);
  102. p_desc->commmand(COMAND, 0x00);
  103. //p_desc->commmand(COMAND, SSD1306_SEGREMAP | 0x1);//ad0x0
  104. p_desc->commmand(COMAND, SSD1306_SEGREMAP | 0x0);//ad0x0
  105. //p_desc->commmand(COMAND, SSD1306_COMSCANDEC);//ad0x0
  106. p_desc->commmand(COMAND, SSD1306_COMSCANINC);
  107. p_desc->commmand(COMAND, SSD1306_SETCOMPINS);
  108. //p_desc->commmand(COMAND, 0x12);
  109. p_desc->commmand(COMAND, 0x2);//ad0x0
  110. /* Max contrast */
  111. p_desc->commmand(COMAND, SSD1306_SETCONTRAST);
  112. p_desc->commmand(COMAND, 0xCF);
  113. p_desc->commmand(COMAND, SSD1306_SETPRECHARGE);
  114. p_desc->commmand(COMAND, 0xF1);
  115. p_desc->commmand(COMAND, SSD1306_SETVCOMDETECT);
  116. //p_desc->commmand(COMAND, 0x40);
  117. p_desc->commmand(COMAND, 0x20);
  118. p_desc->commmand(COMAND, SSD1306_DISPLAYALLON_RESUME);
  119. /* Non-inverted display */
  120. OLED_Mode(p_desc, 0);
  121. /* Turn display back on */
  122. OLED_Sleep(p_desc, 1);
  123. OLED_Clear(p_desc);
  124. OLED_GotoXY(p_desc, 0,0);
  125. }
  126. /* ---------------------------------------------------------
  127. * OLED_Mode
  128. * ---------------------------------------------------------
  129. */
  130. void OLED_Mode(oled_desc_s *p_desc, char set_mode)
  131. {
  132. if(set_mode==0)
  133. {
  134. p_desc->commmand(COMAND, SSD1306_NORMALDISPLAY);
  135. }
  136. if(set_mode==1)
  137. {
  138. p_desc->commmand(COMAND, SSD1306_INVERTDISPLAY);
  139. }
  140. }
  141. /* ---------------------------------------------------------
  142. * OLED_Sleep
  143. * ---------------------------------------------------------
  144. */
  145. void OLED_Sleep(oled_desc_s *p_desc, char set)
  146. {
  147. if(set==0)
  148. {
  149. p_desc->commmand(COMAND,SSD1306_DISPLAYOFF);
  150. }
  151. if(set==1)
  152. {
  153. p_desc->commmand(COMAND,SSD1306_DISPLAYON);
  154. }
  155. }
  156. void OLED_GotoXY(oled_desc_s *p_desc, unsigned char x, unsigned char y)
  157. {
  158. p_desc->OLED_X = x;
  159. p_desc->OLED_Y = y;
  160. p_desc->commmand(COMAND, SSD1306_COLUMNADDR);
  161. p_desc->commmand(COMAND, x);
  162. p_desc->commmand(COMAND, 127);
  163. p_desc->commmand(COMAND, SSD1306_PAGEADDR);
  164. p_desc->commmand(COMAND, y);
  165. p_desc->commmand(COMAND, 0x3);
  166. }
  167. void OLED_GotoXYWH(oled_desc_s *p_desc, unsigned char x, unsigned char y,unsigned char w, unsigned char h){
  168. p_desc->OLED_X = x;
  169. p_desc->OLED_Y = y;
  170. p_desc->commmand(COMAND, SSD1306_COLUMNADDR);
  171. p_desc->commmand(COMAND, x); //íà÷àëî ñòðîêè
  172. p_desc->commmand(COMAND, x+w); //êîíåö (ïîñëå ïåðåïîëåíåíèÿ ñëåä.ñòîëá.+íà÷àëî ñòðîêè)
  173. p_desc->commmand(COMAND, SSD1306_PAGEADDR);
  174. p_desc->commmand(COMAND, y);//ñòîëáåö ñòàðò
  175. p_desc->commmand(COMAND, 0x3);//4é ñòîëáåö ïîñëåäíèé
  176. }
  177. void OLED_Char2x(oled_desc_s *p_desc, unsigned int c)
  178. {
  179. unsigned char x = 0;
  180. uint8_t suka=4,v,nv;
  181. //âûçîâ OLED_GotoXYWH(x,y,10,2) äîëæåí óñòàíîâèòü îêíî ðàçìåðîì 10ïèêñ õ 2ñòðîêè
  182. //òèïà áûëî 10110111 => 1100111100111111
  183. for (x=0; x<5; x++)
  184. {
  185. v=OLED_Buffer[c*5+x];
  186. nv=0;
  187. suka=4;
  188. while(suka--){
  189. if(v & 0x8){nv|=0x3;}
  190. if(suka)nv<<=2;
  191. v<<=1;
  192. }
  193. p_desc->commmand(DATA, nv);
  194. p_desc->commmand(DATA, nv);
  195. //p_desc->commmand(DATA, 0x0);
  196. }
  197. for (x=0; x<5; x++)
  198. {
  199. v=OLED_Buffer[c*5+x];
  200. nv=0;
  201. suka=4;
  202. while(suka--){
  203. if(v & 0x80){nv|=0x3;}
  204. if(suka)nv<<=2;
  205. v<<=1;
  206. }
  207. p_desc->commmand(DATA, nv);
  208. p_desc->commmand(DATA, nv);
  209. //p_desc->commmand(DATA, 0x0);
  210. }
  211. p_desc->OLED_X += 11;
  212. if(p_desc->OLED_X>SSD1306_LCDWIDTH)
  213. {
  214. p_desc->OLED_X = SSD1306_DEFAULT_SPACE;
  215. }
  216. }
  217. /* ---------------------------------------------------------
  218. * OLED_Clear
  219. * ---------------------------------------------------------
  220. */
  221. void OLED_Clear(oled_desc_s *p_desc)
  222. {
  223. unsigned short i;
  224. unsigned short x = 0;
  225. unsigned short y = 0;
  226. OLED_GotoXY(p_desc, 0,0);
  227. for (i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) /* (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8) */
  228. {
  229. OLED_Char(p_desc, ' ');
  230. x ++;
  231. if(x>SSD1306_LCDWIDTH)
  232. {
  233. x = 0;
  234. y++;
  235. OLED_GotoXY(p_desc, 0,y);
  236. }
  237. }
  238. p_desc->OLED_X = SSD1306_DEFAULT_SPACE;
  239. p_desc->OLED_Y = 0;
  240. }
  241. /* ---------------------------------------------------------
  242. * OLED_Char
  243. * ---------------------------------------------------------
  244. */
  245. void OLED_Char(oled_desc_s *p_desc, unsigned int c)
  246. {
  247. unsigned char x = 0;
  248. for (x=0; x<5; x++)
  249. {
  250. p_desc->commmand(DATA, OLED_Buffer[c*5+x]);
  251. }
  252. p_desc->OLED_X += 8;
  253. if(p_desc->OLED_X>SSD1306_LCDWIDTH)
  254. {
  255. p_desc->OLED_X = SSD1306_DEFAULT_SPACE;
  256. }
  257. }
  258. /* ---------------------------------------------------------
  259. * OLED_CharBig
  260. * ---------------------------------------------------------
  261. */
  262. void OLED_CharBig(oled_desc_s *p_desc, unsigned int c)
  263. {
  264. unsigned char x = 0;
  265. unsigned int m = 0;
  266. for (x=0; x<5; x++)
  267. {
  268. m = OLED_Buffer[c*5+x];
  269. p_desc->commmand(DATA, m);
  270. p_desc->commmand(DATA, m);
  271. }
  272. p_desc->commmand(DATA,0x00); /* ïðîáåî â îäíó òî÷êó ìåæäó ñèìâîëàìè */
  273. p_desc->OLED_X += 11;
  274. if(p_desc->OLED_X>SSD1306_LCDWIDTH)
  275. {
  276. p_desc->OLED_X = SSD1306_DEFAULT_SPACE;
  277. }
  278. }
  279. /* ---------------------------------------------------------
  280. * OLED_Printf
  281. * ---------------------------------------------------------
  282. */
  283. void OLED_Printf(oled_desc_s *p_desc, unsigned char* buf, unsigned char size) /* âûâîäèì ñòðîêó èç áóôåðà */
  284. {
  285. while (*buf!=0)
  286. {
  287. if(size==0)
  288. {
  289. if((p_desc->OLED_X>SSD1306_LCDWIDTH)||(p_desc->OLED_X<5))
  290. {
  291. p_desc->OLED_X=SSD1306_DEFAULT_SPACE;
  292. }
  293. OLED_Char(p_desc, *buf++);
  294. }
  295. if(size==1)
  296. {
  297. if((p_desc->OLED_X>SSD1306_LCDWIDTH)||(p_desc->OLED_X<5))
  298. {
  299. p_desc->OLED_X=SSD1306_DEFAULT_SPACE;
  300. }
  301. OLED_CharBig(p_desc, *buf++);
  302. }
  303. }
  304. }
  305. void OLED_PrintAt(oled_desc_s *p_desc, unsigned char x, unsigned char y,unsigned char* buf, unsigned char size){
  306. if(size==0)OLED_GotoXY(p_desc, x,y);else
  307. if(size==1)OLED_GotoXY(p_desc, x,y);
  308. while (*buf!=0)
  309. {
  310. if(size==0)
  311. {
  312. if((p_desc->OLED_X>SSD1306_LCDWIDTH)||(p_desc->OLED_X<5))
  313. {
  314. p_desc->OLED_X=SSD1306_DEFAULT_SPACE;
  315. }
  316. OLED_Char(p_desc, *buf++);
  317. }
  318. if(size==1)
  319. {
  320. if((p_desc->OLED_X>SSD1306_LCDWIDTH)||(p_desc->OLED_X<5))
  321. {
  322. p_desc->OLED_X=SSD1306_DEFAULT_SPACE;
  323. }
  324. OLED_CharBig(p_desc, *buf++);
  325. }
  326. if(size==2)
  327. {
  328. if((p_desc->OLED_X>SSD1306_LCDWIDTH))
  329. {
  330. p_desc->OLED_X=SSD1306_DEFAULT_SPACE;
  331. }
  332. OLED_GotoXYWH(p_desc, x,y,9,2);
  333. OLED_Char2x(p_desc, *buf++);
  334. x+=11;
  335. }
  336. }
  337. }
  338. void OLED_Command(oled_desc_s *p_desc, unsigned char ControByte, unsigned char DataByte){
  339. /*if(ad0x0_i2c_isovrflow()){
  340. asm("nop");
  341. }else
  342. {
  343. asm("nop");
  344. }*/
  345. //ad0x0_i2c1_push(0x1,0);
  346. //ad0x0_i2c1_push(0x3,SSD1306_I2C_ADDRESS & 0xFE);
  347. /*ad0x0_i2c1_push(ADQ_START_ADDR,SSD1306_I2C_ADDRESS & 0xFE);//v2 start+addr
  348. ad0x0_i2c1_push(ADQ_TX,ControByte);
  349. ad0x0_i2c1_push(ADQ_TX_STOP,DataByte);
  350. ad0x0_i2c2_push(ADQ_START_ADDR,SSD1306_I2C_ADDRESS & 0xFE);//v2 start+addr
  351. ad0x0_i2c2_push(ADQ_TX,ControByte);
  352. ad0x0_i2c2_push(ADQ_TX_STOP,DataByte);*/
  353. uint8_t h_ext;
  354. ad0x0_i2c_ext_t *p_ext_t=NULL;
  355. p_desc->ad0x0_i2c_get_ext_async2(&h_ext,(void**)&p_ext_t);
  356. p_ext_t->addr_w=SSD1306_I2C_ADDRESS;
  357. p_ext_t->user_data0=ControByte | (uint32_t)(DataByte<<8);
  358. p_ext_t->pbuf_count=2;
  359. p_ext_t->pbuf_tx=(uint8_t*)&p_ext_t->user_data0;//TX!!!!!!!
  360. p_ext_t->p_pre_SetTXRXBuf=EXT_SetTXRXBuf_i2c;
  361. p_desc->ad0x0_i2c_push(ADQ_HAL_ADDR_TX_BUF_STOP_EXT,h_ext);
  362. }
  363. /* ---------------------------------------------------------
  364. * OLED_test
  365. * ---------------------------------------------------------
  366. */
  367. void OLED_test(oled_desc_s *p_desc)
  368. {
  369. OLED_Clear(p_desc);
  370. OLED_PrintAt(p_desc, 0,0,(unsigned char*)"Øðèôò ðàçìåð = 0",0);
  371. HAL_Delay(500);
  372. OLED_PrintAt(p_desc, 0,1,(unsigned char*)"Øðèôò s = 1",1);
  373. HAL_Delay(500);
  374. OLED_PrintAt(p_desc, 0,2,(unsigned char*)"Øðèôò s = 2",2);
  375. HAL_Delay(500);
  376. OLED_Clear(p_desc);
  377. }
  378. unsigned char * i16_2s(int16_t value, unsigned char *buffer)
  379. {
  380. memset(buffer,' ',6);
  381. buffer += 7;
  382. char m=(value<0)?'-':' ';
  383. if(value<0)value=-value;
  384. // 11 áàéò äîñòàòî÷íî äëÿ äåñÿòè÷íîãî ïðåäñòàâëåíèÿ 32-õ áàéòíîãî ÷èñëà
  385. // è çàâåðøàþùåãî íóëÿ
  386. *--buffer = 0;
  387. do
  388. {
  389. *--buffer = value % 10 + '0';
  390. value /= 10;
  391. }
  392. while (value != 0);
  393. *--buffer=m;
  394. return buffer;
  395. }
  396. unsigned char * i32_2s(int32_t value, unsigned char *buffer)
  397. {
  398. memset(buffer,' ',8);
  399. buffer += 7;
  400. char m=(value<0)?'-':' ';
  401. if(value<0)value=-value;
  402. // 11 áàéò äîñòàòî÷íî äëÿ äåñÿòè÷íîãî ïðåäñòàâëåíèÿ 32-õ áàéòíîãî ÷èñëà
  403. // è çàâåðøàþùåãî íóëÿ
  404. *--buffer = 0;
  405. do
  406. {
  407. *--buffer = value % 10 + '0';
  408. value /= 10;
  409. }
  410. while (value != 0);
  411. *--buffer=m;
  412. return buffer;
  413. }
  414. /* EOF "ssd1306.c" */