oled.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. #include "oled.h"
  2. #include "oledfont.h"
  3. //#include "delay.h"
  4. #include <stdarg.h> // 标准头文件
  5. #include "stdio.h"
  6. void OLED_WR_Byte(unsigned dat,unsigned cmd);
  7. void OLED_Display_On(void);
  8. void OLED_Display_Off(void);
  9. void OLED_Init(void);//初始化SSD1306
  10. void OLED_Clear(void);//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
  11. void OLED_DrawPoint(u8 x,u8 y,u8 t);
  12. void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
  13. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);//在指定位置显示一个字符,包括部分字符
  14. void OLED_ShowString(char x,char y,char *chr,char Char_Size);
  15. void OLED_Set_Pos(unsigned char x, unsigned char y);
  16. void OLED_ShowCHinese(u8 x,u8 y,u8 no);//显示汉字
  17. void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);
  18. void Delay_50ms(unsigned int Del_50ms);
  19. void Delay_1ms(unsigned int Del_1ms);
  20. void fill_picture(unsigned char fill_Data);
  21. void Picture();
  22. void oledIIC_Start(void);
  23. void IIC_Stop(void);
  24. void Write_IIC_Command(unsigned char IIC_Command);
  25. void Write_IIC_Data(unsigned char IIC_Data);
  26. void Write_IIC_Byte(unsigned char IIC_Byte);
  27. void oled_printf(char x,char y,char *p,...);
  28. void IIC_Wait_Ack(void);
  29. void OLED_On(void);
  30. u32 oled_pow(u8 m,u8 n);
  31. //OLED的显存
  32. //存放格式如下.
  33. //[0]0 1 2 3 ... 127
  34. //[1]0 1 2 3 ... 127
  35. //[2]0 1 2 3 ... 127
  36. //[3]0 1 2 3 ... 127
  37. //[4]0 1 2 3 ... 127
  38. //[5]0 1 2 3 ... 127
  39. //[6]0 1 2 3 ... 127
  40. //[7]0 1 2 3 ... 127
  41. /**********************************************
  42. //IIC Start
  43. **********************************************/
  44. /**********************************************
  45. //IIC Start
  46. **********************************************/
  47. void oledIIC_Start(void)
  48. {
  49. OLED_SCLK_Set() ;
  50. OLED_SDIN_Set();
  51. OLED_SDIN_Clr();
  52. OLED_SCLK_Clr();
  53. }
  54. /**********************************************
  55. //IIC Stop
  56. **********************************************/
  57. void IIC_Stop(void)
  58. {
  59. OLED_SCLK_Set() ;
  60. // OLED_SCLK_Clr();
  61. OLED_SDIN_Clr();
  62. OLED_SDIN_Set();
  63. }
  64. void IIC_Wait_Ack(void)
  65. {
  66. OLED_SCLK_Set() ;
  67. OLED_SCLK_Clr();
  68. }
  69. /**********************************************
  70. // IIC Write byte
  71. **********************************************/
  72. void Write_IIC_Byte(unsigned char IIC_Byte)
  73. {
  74. unsigned char i;
  75. unsigned char m,da;
  76. da=IIC_Byte;
  77. OLED_SCLK_Clr();
  78. for(i=0;i<8;i++)
  79. {
  80. m=da;
  81. // OLED_SCLK_Clr();
  82. m=m&0x80;
  83. if(m==0x80)
  84. {OLED_SDIN_Set();}
  85. else OLED_SDIN_Clr();
  86. da=da<<1;
  87. OLED_SCLK_Set();
  88. OLED_SCLK_Clr();
  89. }
  90. }
  91. /**********************************************
  92. // IIC Write Command
  93. **********************************************/
  94. void Write_IIC_Command(unsigned char IIC_Command)
  95. {
  96. oledIIC_Start();
  97. Write_IIC_Byte(0x78); //Slave address,SA0=0
  98. IIC_Wait_Ack();
  99. Write_IIC_Byte(0x00); //write command
  100. IIC_Wait_Ack();
  101. Write_IIC_Byte(IIC_Command);
  102. IIC_Wait_Ack();
  103. IIC_Stop();
  104. }
  105. /**********************************************
  106. // IIC Write Data
  107. **********************************************/
  108. void Write_IIC_Data(unsigned char IIC_Data)
  109. {
  110. oledIIC_Start();
  111. Write_IIC_Byte(0x78); //D/C#=0; R/W#=0
  112. IIC_Wait_Ack();
  113. Write_IIC_Byte(0x40); //write data
  114. IIC_Wait_Ack();
  115. Write_IIC_Byte(IIC_Data);
  116. IIC_Wait_Ack();
  117. IIC_Stop();
  118. }
  119. void OLED_WR_Byte(unsigned dat,unsigned cmd)
  120. {
  121. if(cmd)
  122. {
  123. Write_IIC_Data(dat);
  124. }
  125. else {
  126. Write_IIC_Command(dat);
  127. }
  128. }
  129. /********************************************
  130. // fill_Picture
  131. ********************************************/
  132. void fill_picture(unsigned char fill_Data)
  133. {
  134. unsigned char m,n;
  135. for(m=0;m<8;m++)
  136. {
  137. OLED_WR_Byte(0xb0+m,0); //page0-page1
  138. OLED_WR_Byte(0x00,0); //low column start address
  139. OLED_WR_Byte(0x10,0); //high column start address
  140. for(n=0;n<128;n++)
  141. {
  142. OLED_WR_Byte(fill_Data,1);
  143. }
  144. }
  145. }
  146. //坐标设置
  147. void OLED_Set_Pos(unsigned char x, unsigned char y)
  148. {
  149. OLED_WR_Byte(0xb0+y,OLED_CMD);
  150. OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
  151. OLED_WR_Byte((x&0x0f),OLED_CMD);
  152. }
  153. //开启OLED显示
  154. void OLED_Display_On(void)
  155. {
  156. OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
  157. OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
  158. OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
  159. }
  160. //关闭OLED显示
  161. void OLED_Display_Off(void)
  162. {
  163. OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
  164. OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
  165. OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
  166. }
  167. //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
  168. void OLED_Clear(void)
  169. {
  170. u8 i,n;
  171. for(i=0;i<8;i++)
  172. {
  173. OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
  174. OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
  175. OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
  176. for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
  177. } //更新显示
  178. }
  179. void OLED_On(void)
  180. {
  181. u8 i,n;
  182. for(i=0;i<8;i++)
  183. {
  184. OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
  185. OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
  186. OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
  187. for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
  188. } //更新显示
  189. }
  190. //在指定位置显示一个字符,包括部分字符
  191. //x:0~127
  192. //y:0~63
  193. //mode:0,反白显示;1,正常显示
  194. //size:选择字体 16/12
  195. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
  196. {
  197. unsigned char c=0,i=0;
  198. c=chr-' ';//得到偏移后的值
  199. if(x>Max_Column-1){x=0;y=y+2;}
  200. if(Char_Size ==16)
  201. {
  202. OLED_Set_Pos(x,y);
  203. for(i=0;i<8;i++)
  204. OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
  205. OLED_Set_Pos(x,y+1);
  206. for(i=0;i<8;i++)
  207. OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
  208. }
  209. else {
  210. OLED_Set_Pos(x,y);
  211. for(i=0;i<6;i++)
  212. OLED_WR_Byte(F6x8[c][i],OLED_DATA);
  213. }
  214. }
  215. //m^n函数
  216. u32 oled_pow(u8 m,u8 n)
  217. {
  218. u32 result=1;
  219. while(n--)result*=m;
  220. return result;
  221. }
  222. //显示2个数字
  223. //x,y :起点坐标
  224. //len :数字的位数
  225. //size:字体大小
  226. //num:数值(0~4294967295);
  227. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
  228. {
  229. u8 t,temp;
  230. u8 enshow=0;
  231. for(t=0;t<len;t++)
  232. {
  233. temp=(num/oled_pow(10,len-t-1))%10;
  234. if(enshow==0&&t<(len-1))
  235. {
  236. if(temp==0)
  237. {
  238. OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
  239. continue;
  240. }else enshow=1;
  241. }
  242. OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
  243. }
  244. }
  245. /*显示一个字符号串
  246. x 取0 2 4 6 分为4行 y 每一个数字字母占9
  247. 汉字占18 Size字体的大小 可取12或者16
  248. */
  249. void OLED_ShowString(char x,char y,char *chr,char Char_Size)
  250. {
  251. unsigned char j=0;
  252. while (chr[j]!='\0')
  253. { OLED_ShowChar(x,y,chr[j],Char_Size);
  254. x+=8;
  255. if(x>120){x=0;y+=2;}
  256. j++;
  257. }
  258. }
  259. //显示汉字
  260. /*
  261. x 取0 2 4 6 分为4行 y 每一个数字字母占9
  262. 汉字占18 Size字体的大小 可取12或者16
  263. no为Hzk[]数组中的哪一个元素
  264. */
  265. //void OLED_ShowCHinese(u8 x,u8 y,u8 no)
  266. //{
  267. // u8 t,adder=0;
  268. // OLED_Set_Pos(x,y);
  269. // for(t=0;t<16;t++)
  270. // {
  271. // OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
  272. // adder+=1;
  273. // }
  274. // OLED_Set_Pos(x,y+1);
  275. // for(t=0;t<16;t++)
  276. // {
  277. // OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
  278. // adder+=1;
  279. // }
  280. //}
  281. //初始化SSD1306
  282. void OLED_Init(void)
  283. {
  284. OLED_SCLK_PIN_OUT();//设置为输出
  285. OLED_SDIN_PIN_OUT();
  286. OLED_WR_Byte(0xAE,OLED_CMD);//--display off
  287. OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  288. OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  289. OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
  290. OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
  291. OLED_WR_Byte(0x81,OLED_CMD); // contract control
  292. OLED_WR_Byte(0xFF,OLED_CMD);//--128
  293. OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
  294. OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
  295. OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  296. OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
  297. OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
  298. OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
  299. OLED_WR_Byte(0x00,OLED_CMD);//
  300. OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
  301. OLED_WR_Byte(0x80,OLED_CMD);//
  302. OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
  303. OLED_WR_Byte(0x05,OLED_CMD);//
  304. OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
  305. OLED_WR_Byte(0xF1,OLED_CMD);//
  306. OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
  307. OLED_WR_Byte(0x12,OLED_CMD);//
  308. OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
  309. OLED_WR_Byte(0x30,OLED_CMD);//
  310. OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
  311. OLED_WR_Byte(0x14,OLED_CMD);//
  312. OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
  313. }
  314. /********************************************************************************
  315. * @函数名: OLED_ShowCHineseWord
  316. * @函数描述: 在指定位置显示占宽16*16的单个 汉字
  317. * @函数作者: 小浩电子科技
  318. * @输入参数:
  319. 参数名 参数类型 参数描述
  320. @x: u8 列坐标,0~127
  321. @y: u8 行坐标,0~7
  322. @str: u8* 要显示的汉字
  323. @flag: u8 反白标志,非0时反白显示
  324. * @返回值: void
  325. * @其他:
  326. ********************************************************************************/
  327. void OLED_ShowCHineseWord(u8 x,u8 y,u8* str)
  328. {
  329. u8 t=0;
  330. u16 index;
  331. for(index=0; index<sizeof(Hzk)/35; index++)
  332. {
  333. if(Hzk[index].name[0] == str[0]&&Hzk[index].name[1] == str[1])//对比汉字区码位码
  334. {
  335. OLED_Set_Pos(x,y); //设置OLED光标位置
  336. for(t=0; t<16; t++)//先写汉字上半部分数据
  337. {
  338. OLED_WR_Byte(Hzk[index].dat[t],OLED_DATA);
  339. }
  340. OLED_Set_Pos(x,y+1);//设置OLED光标位置
  341. for(t=0; t<16; t++)//再写汉字下半部分数据
  342. {
  343. OLED_WR_Byte(Hzk[index].dat[t+16],OLED_DATA);
  344. }
  345. }
  346. }
  347. }
  348. /********************************************************************************
  349. * @函数名: OLED_ShowText
  350. * @函数描述: 在指定位置显示中英文字符串
  351. * @函数作者: 小浩电子科技
  352. * @输入参数:
  353. 参数名 参数类型 参数描述
  354. @x: u8 列坐标,0~127
  355. @y: u8 行坐标,0~7
  356. @str: u8* 要显示的字符串
  357. @flag: u8 反白标志,非0时反白显示
  358. * @返回值: void
  359. * @其他:
  360. ********************************************************************************/
  361. void OLED_ShowText(u8 x,u8 y,u8* str,u8 size)
  362. {
  363. u8 tempstr[3] = {'\0'};
  364. while(*str!='\0')
  365. {
  366. if(*str&0x80)
  367. {
  368. tempstr[0]=*str++;
  369. tempstr[1]=*str++;
  370. OLED_ShowCHineseWord(x,y,tempstr);
  371. x+=16;
  372. if(*str&0x80)//判断下一个字符是中文还是英文
  373. {
  374. if(x>=112){y++;y++;x=0;}//修改地址
  375. }
  376. else
  377. {
  378. if(x>=120){y++;y++;x=0;}//修改地址
  379. }
  380. }
  381. else
  382. {
  383. OLED_ShowChar(x,y,*str++,size);
  384. x+=8;
  385. if(*str&0x80)
  386. {
  387. if(x>=112){y++;y++;x=0;}//修改地址
  388. }
  389. else
  390. {
  391. if(x>=120){y++;y++;x=0;}//修改地址
  392. }
  393. }
  394. }
  395. }