oled.c 12 KB

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