oled.c 12 KB

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