oled.c.bak 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. #include "STC8XXXX.H"
  2. #include "oled.h"
  3. #include "oledfont.h"
  4. #include <math.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. unsigned char _buf[128*8]=0;
  8. unsigned char code height=8;
  9. unsigned char code width=128;
  10. bit _OLED_Reverse = 0;
  11. bit _OLED_Overlap = 1;
  12. static char __x, __y;
  13. void delay_ms(unsigned int ms)
  14. {
  15. unsigned int a;
  16. while(ms)
  17. {
  18. a=1800;
  19. while(a--);
  20. ms--;
  21. }
  22. return;
  23. }
  24. //反显函数
  25. void OLED_ColorTurn(u8 i)
  26. {
  27. if(i==0)
  28. {
  29. OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
  30. }
  31. if(i==1)
  32. {
  33. OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
  34. }
  35. }
  36. //屏幕旋转180度
  37. void OLED_DisplayTurn(u8 i)
  38. {
  39. if(i==0)
  40. {
  41. OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
  42. OLED_WR_Byte(0xA1,OLED_CMD);
  43. }
  44. if(i==1)
  45. {
  46. OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
  47. OLED_WR_Byte(0xA0,OLED_CMD);
  48. }
  49. }
  50. //延时
  51. void IIC_delay(void)
  52. {
  53. _nop_();
  54. }
  55. //起始信号
  56. void I2C_Start(void)
  57. {
  58. OLED_SDA_Set();
  59. OLED_SCL_Set();
  60. IIC_delay();
  61. OLED_SDA_Clr();
  62. IIC_delay();
  63. OLED_SCL_Clr();
  64. }
  65. //结束信号
  66. void I2C_Stop(void)
  67. {
  68. OLED_SDA_Clr();
  69. OLED_SCL_Set();
  70. IIC_delay();
  71. OLED_SDA_Set();
  72. }
  73. //等待信号响应
  74. void I2C_WaitAck(void) //测数据信号的电平
  75. {
  76. OLED_SDA_Set();
  77. IIC_delay();
  78. OLED_SCL_Set();
  79. IIC_delay();
  80. OLED_SCL_Clr();
  81. IIC_delay();
  82. }
  83. //写入一个字节
  84. void Send_Byte(u8 dat)
  85. {
  86. u8 i;
  87. for(i=0;i<8;i++)
  88. {
  89. OLED_SCL_Clr();//将时钟信号设置为低电平
  90. if(dat&0x80)//将dat的8位从最高位依次写入
  91. {
  92. OLED_SDA_Set();
  93. }
  94. else
  95. {
  96. OLED_SDA_Clr();
  97. }
  98. IIC_delay();
  99. OLED_SCL_Set();
  100. IIC_delay();
  101. OLED_SCL_Clr();
  102. dat<<=1;
  103. }
  104. }
  105. //发送一个字节
  106. //向SSD1306写入一个字节。
  107. //mode:数据/命令标志 0,表示命令;1,表示数据;
  108. void OLED_WR_Byte(u8 dat,u8 mode)
  109. {
  110. I2C_Start();
  111. Send_Byte(0x78);
  112. I2C_WaitAck();
  113. if(mode){Send_Byte(0x40);}
  114. else{Send_Byte(0x00);}
  115. I2C_WaitAck();
  116. Send_Byte(dat);
  117. I2C_WaitAck();
  118. I2C_Stop();
  119. }
  120. //坐标设置
  121. void OLED_Set_Pos(u8 x, u8 y)
  122. {
  123. OLED_WR_Byte(0xb0+y,OLED_CMD);
  124. OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
  125. OLED_WR_Byte((x&0x0f),OLED_CMD);
  126. }
  127. //开启OLED显示
  128. void OLED_Display_On(void)
  129. {
  130. OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
  131. OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
  132. OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
  133. }
  134. //关闭OLED显示
  135. void OLED_Display_Off(void)
  136. {
  137. OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
  138. OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
  139. OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
  140. }
  141. //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
  142. void OLED_Clear(void)
  143. {
  144. u8 i,n;
  145. for(i=0;i<8;i++)
  146. {
  147. OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
  148. OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
  149. OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
  150. for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
  151. } //更新显示
  152. }
  153. //在指定位置显示一个字符,包括部分字符
  154. //x:0~127
  155. //y:0~63
  156. //sizey:选择字体 6x8 8x16
  157. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey)
  158. {
  159. u8 c=0,sizex=sizey/2;
  160. u16 i=0,size1;
  161. if(sizey==8)size1=6;
  162. else size1=(sizey/8+((sizey%8)?1:0))*(sizey/2);
  163. c=chr-' ';//得到偏移后的值
  164. OLED_Set_Pos(x,y);
  165. for(i=0;i<size1;i++)
  166. {
  167. if(i%sizex==0&&sizey!=8) OLED_Set_Pos(x,y++);
  168. if(sizey==8) OLED_WR_Byte(asc2_0806[c][i],OLED_DATA);//6X8字号
  169. else if(sizey==16) OLED_WR_Byte(asc2_1608[c][i],OLED_DATA);//8x16字号
  170. // else if(sizey==xx) OLED_WR_Byte(asc2_xxxx[c][i],OLED_DATA);//用户添加字号
  171. else return;
  172. }
  173. }
  174. //m^n函数
  175. u32 oled_pow(u8 m,u8 n)
  176. {
  177. u32 result=1;
  178. while(n--)result*=m;
  179. return result;
  180. }
  181. //显示数字
  182. //x,y :起点坐标
  183. //num:要显示的数字
  184. //len :数字的位数
  185. //sizey:字体大小
  186. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey)
  187. {
  188. u8 t,temp,m=0;
  189. u8 enshow=0;
  190. if(sizey==8)m=2;
  191. for(t=0;t<len;t++)
  192. {
  193. temp=(num/oled_pow(10,len-t-1))%10;
  194. if(enshow==0&&t<(len-1))
  195. {
  196. if(temp==0)
  197. {
  198. OLED_ShowChar(x+(sizey/2+m)*t,y,' ',sizey);
  199. continue;
  200. }else enshow=1;
  201. }
  202. OLED_ShowChar(x+(sizey/2+m)*t,y,temp+'0',sizey);
  203. }
  204. }
  205. //显示一个字符号串
  206. void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 sizey)
  207. {
  208. u8 j=0;
  209. while (chr[j]!='\0')
  210. {
  211. OLED_ShowChar(x,y,chr[j++],sizey);
  212. if(sizey==8)x+=6;
  213. else x+=sizey/2;
  214. }
  215. }
  216. //显示汉字
  217. //void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey)
  218. //{
  219. // u16 i,size1=(sizey/8+((sizey%8)?1:0))*sizey;
  220. // for(i=0;i<size1;i++)
  221. // {
  222. // if(i%sizey==0) OLED_Set_Pos(x,y++);
  223. // if(sizey==16) OLED_WR_Byte(Hzk[no][i],OLED_DATA);//16x16字号
  224. //// else if(sizey==xx) OLED_WR_Byte(xxx[c][i],OLED_DATA);//用户添加字号
  225. // else return;
  226. // }
  227. //}
  228. //显示图片
  229. //x,y显示坐标
  230. //sizex,sizey,图片长宽
  231. //BMP:要显示的图片
  232. void OLED_DrawBMP(int x,int y,unsigned char sizex, unsigned char sizey,unsigned char BMP[])
  233. {
  234. int j=0;
  235. int i,m;
  236. sizey=sizey/8+((sizey%8)?1:0);
  237. for(i=0;i<sizey;i++)
  238. {
  239. OLED_Set_Pos(x,i+y);
  240. for(m=0;m<sizex;m++)
  241. {
  242. OLED_WR_Byte(BMP[j++],OLED_DATA);
  243. }
  244. }
  245. }
  246. //初始化
  247. void OLED_Init(void)
  248. {
  249. OLED_RES_Clr();
  250. delay_ms(200);
  251. OLED_RES_Set();
  252. delay_ms(200);
  253. OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
  254. OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  255. OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  256. OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
  257. OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
  258. OLED_WR_Byte(0xff,OLED_CMD); // Set SEG Output Current Brightness
  259. OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
  260. OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
  261. OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
  262. OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  263. OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
  264. OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
  265. OLED_WR_Byte(0x00,OLED_CMD);//-not offset
  266. OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
  267. OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
  268. OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
  269. OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  270. OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
  271. OLED_WR_Byte(0x12,OLED_CMD);
  272. OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
  273. OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
  274. OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
  275. OLED_WR_Byte(0x02,OLED_CMD);//
  276. OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
  277. OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
  278. OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
  279. OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
  280. OLED_Clear();
  281. OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
  282. OLED_Clear();
  283. OLED_ColorTurn(0);
  284. OLED_DisplayTurn(0);
  285. OLED_Display_On();
  286. }
  287. void OLED_DrawPixel(unsigned char x, unsigned char y,unsigned char color)
  288. {
  289. unsigned char mask;
  290. unsigned char *pBuf;
  291. if(y%2 == 0)
  292. {
  293. y++;
  294. }
  295. if (__x > width)
  296. {
  297. __x = 0;
  298. __y += 1;
  299. }
  300. if (__y > height * 8)
  301. {
  302. __y = 0;
  303. }
  304. pBuf = &_buf[(y >> 3) * width + x];
  305. mask = 1 << (y & 7);
  306. if (!color)
  307. {
  308. *pBuf++ &= ~mask;
  309. }
  310. else
  311. {
  312. *pBuf++ |= mask;
  313. }
  314. }
  315. void _swap_char(unsigned char* a,unsigned char* b)
  316. {
  317. unsigned char tmp = *a;
  318. *a = *b;
  319. *b = tmp;
  320. }
  321. /*========================================================
  322. *????: ?0.96Oled???
  323. *????: x1 -> ??x1?? y1 -> ??y1??
  324. * x2 -> ??x1?? y2 -> ??y1??
  325. *????: ?
  326. *========================================================*/
  327. void OLED_DrawLine(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2, unsigned char color)
  328. {
  329. unsigned char i = 0;
  330. char DeltaY = 0,DeltaX = 0;
  331. float k = 0,b = 0;
  332. if(x1>x2)
  333. {
  334. i = x2;x2 = x1;x1 = i;
  335. i = y2;y2 = y1;y1 = i;
  336. i = 0;
  337. }
  338. DeltaY = y2 - y1;
  339. DeltaX = x2 - x1;
  340. if(DeltaX == 0)
  341. {
  342. if(y1<=y2)
  343. {
  344. for(y1;y1<=y2;y1++)
  345. {
  346. OLED_DrawPixel(x1,y1,color);
  347. }
  348. }else if(y1>y2)
  349. {
  350. for(y2;y2<=y1;y2++)
  351. {
  352. OLED_DrawPixel(x1,y2,color);
  353. }
  354. }
  355. }
  356. else if(DeltaY == 0)
  357. {
  358. for(x1;x1<=x2;x1++)
  359. {
  360. OLED_DrawPixel(x1,y1,color);
  361. }
  362. }
  363. else
  364. {
  365. k = ((float)DeltaY)/((float)DeltaX);
  366. b = y2 - k * x2;
  367. if((k>-1&k<1))
  368. {
  369. for(x1;x1<=x2;x1++)
  370. {
  371. OLED_DrawPixel(x1,(int)(k * x1 + b),color);
  372. }
  373. }else if((k>=1)|(k<=-1))
  374. {
  375. if(y1<=y2)
  376. {
  377. for(y1;y1<=y2;y1++)
  378. {
  379. OLED_DrawPixel((int)((y1 - b) / k),y1,color);
  380. }
  381. }else if(y1>y2)
  382. {
  383. for(y2;y2<=y1;y2++)
  384. {
  385. OLED_DrawPixel((int)((y2 - b) / k),y2,color);
  386. }
  387. }
  388. }
  389. }
  390. }
  391. void OLED_display(void)
  392. {
  393. OLED_DrawBMP(0,0,128,64,_buf);
  394. //OLED_DrawBMP(0,6,width[1],heigth[1]*8,_buf1);
  395. }
  396. void OLED_display_clear()
  397. {
  398. memset(_buf, 0x00, width * height);
  399. }
  400. void OLED_Draw_Byte(unsigned char *pBuf, unsigned char mask, unsigned char offset, bit reserve_hl)
  401. {
  402. if (_OLED_Overlap)
  403. {
  404. if (_OLED_Reverse)
  405. *pBuf |= ~mask;
  406. else
  407. *pBuf |= mask;
  408. }
  409. else
  410. {
  411. if (_OLED_Reverse)
  412. {
  413. /* 保留高位
  414. Reserve upper */
  415. if (reserve_hl)
  416. {
  417. *pBuf &= (~mask) | (0xFF << (8 - offset));
  418. *pBuf |= (~mask) & (0xFF >> offset);
  419. }
  420. /* 保留低位
  421. Reserve lower */
  422. else
  423. {
  424. *pBuf &= (~mask) | (0xFF >> (8 - offset));
  425. *pBuf |= (~mask) & (0xFF << offset);
  426. }
  427. }
  428. else
  429. {
  430. /* 保留高位
  431. Reserve upper */
  432. if (reserve_hl)
  433. {
  434. *pBuf &= mask | (0xFF << (8 - offset));
  435. *pBuf |= mask & (0xFF >> offset);
  436. }
  437. /* 保留低位
  438. Reserve lower */
  439. else
  440. {
  441. *pBuf &= mask | (0xFF >> (8 - offset));
  442. *pBuf |= mask & (0xFF << offset);
  443. }
  444. }
  445. }
  446. }
  447. void OLED_DrawChar(unsigned char x, unsigned char y, unsigned char chr)
  448. {
  449. unsigned char c;
  450. unsigned char i;
  451. unsigned char mask;
  452. unsigned char *pBuf;
  453. unsigned char offset;
  454. offset = y & 7;
  455. c = chr - ' ';
  456. pBuf = &_buf[(y >> 3) * width + x];
  457. for (i = 0; i < 8; i++)
  458. {
  459. mask = asc2_1608[c][i] << offset;
  460. OLED_Draw_Byte(pBuf++, mask, offset, 0);
  461. }
  462. if (offset && y < 56 - 8)
  463. {
  464. pBuf = &_buf[((y >> 3) + 1) * 100 + x];
  465. for (i = 0; i < 6; i++)
  466. {
  467. mask = asc2_0806[c][i] >> (8 - offset);
  468. OLED_Draw_Byte(pBuf++, mask, 8 - offset, 1);
  469. }
  470. }
  471. }
  472. void OLED_Set_Posi(unsigned char x, unsigned char y)
  473. {
  474. __x = x;
  475. __y = y;
  476. }
  477. void OLED_DrawNum(unsigned char digit, unsigned char len)
  478. {
  479. unsigned char t, i, temp;
  480. unsigned char enshow = 0;
  481. i = 0;
  482. for (t = 0; t < len; t++)
  483. {
  484. temp = (digit / oled_pow(10, len - t - 1)) % 10;
  485. if (enshow == 0 && t < (len - 1))
  486. {
  487. if (temp == 0)
  488. {
  489. i++;
  490. continue;
  491. }
  492. else
  493. enshow = 1;
  494. }
  495. if (__x > 100 - 6)
  496. {
  497. __x = 0;
  498. __y += 8;
  499. }
  500. if (__y > 56 - 8)
  501. {
  502. __y = 0;
  503. }
  504. OLED_DrawChar(__x + (6) * (t - i), __y, temp + '0');
  505. }
  506. __x += len;
  507. }
  508. void OLED_DrawBMP_2(u8 x0, u8 page0, u8 xsize, u8 ysize, u8 *BMP)
  509. {
  510. u16 i, j, p;
  511. for(j = page0; j < page0+ysize/8; j++)
  512. {
  513. for(i = x0; i < x0+xsize; i++)
  514. {
  515. _buf[i+(j)*width]=BMP[(i-x0)+(j-page0)*xsize];
  516. }
  517. }
  518. }