找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2034|回复: 0
打印 上一主题 下一主题
收起左侧

STM32F103的0.96 OLED iic驱动程序

[复制链接]
跳转到指定楼层
楼主
ID:872287 发表于 2021-6-24 19:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #ifndef __OLED_H
  2. #define __OLED_H

  3. #include "sys.h"
  4. #include "stdlib.h"        

  5. //-----------------测试LED端口定义----------------

  6. #define LED_ON GPIO_ResetBits(GPIOB,GPIO_Pin_8)
  7. #define LED_OFF GPIO_SetBits(GPIOB,GPIO_Pin_8)

  8. //-----------------OLED端口定义----------------

  9. #define OLED_SCLK_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_6)
  10. #define OLED_SCLK_Set() GPIO_SetBits(GPIOB,GPIO_Pin_6)

  11. #define OLED_SDIN_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_7)//DIN
  12. #define OLED_SDIN_Set() GPIO_SetBits(GPIOB,GPIO_Pin_7)

  13. #define OLED_RST_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_0)//RES
  14. #define OLED_RST_Set() GPIO_SetBits(GPIOB,GPIO_Pin_0)

  15. #define OLED_DC_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_1)//DC
  16. #define OLED_DC_Set() GPIO_SetBits(GPIOB,GPIO_Pin_1)
  17.                      
  18. #define OLED_CS_Clr()  GPIO_ResetBits(GPIOA,GPIO_Pin_4)//CS
  19. #define OLED_CS_Set()  GPIO_SetBits(GPIOA,GPIO_Pin_4)

  20. #define OLED_CMD  0        //写命令
  21. #define OLED_DATA 1        //写数据
  22. #define u8 unsigned char
  23. #define u32 unsigned int

  24. void OLED_ClearPoint(u8 x,u8 y);
  25. void OLED_ColorTurn(u8 i);
  26. void OLED_DisplayTurn(u8 i);
  27. void OLED_WR_Byte(u8 dat,u8 cmd);
  28. void OLED_DisPlay_On(void);
  29. void OLED_DisPlay_Off(void);
  30. void OLED_Refresh(void);
  31. void OLED_Clear(void);
  32. void OLED_DrawPoint(u8 x,u8 y);
  33. void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2);
  34. void OLED_DrawCircle(u8 x,u8 y,u8 r);
  35. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1);
  36. void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1);
  37. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1);
  38. void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1);
  39. void OLED_ScrollDisplay(u8 num,u8 space);
  40. void OLED_WR_BP(u8 x,u8 y);
  41. void OLED_ShowPicture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]);
  42. void OLED_Init(void);

  43. #endif
复制代码
  1. #include "oled.h"
  2. #include "stdlib.h"
  3. #include "oledfont.h"           
  4. #include "delay.h"

  5. u8 OLED_GRAM[144][8];

  6. //反显函数
  7. void OLED_ColorTurn(u8 i)
  8. {
  9.         if(i==0)
  10.                 {
  11.                         OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
  12.                 }
  13.         if(i==1)
  14.                 {
  15.                         OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
  16.                 }
  17. }

  18. //屏幕旋转180度
  19. void OLED_DisplayTurn(u8 i)
  20. {
  21.         if(i==0)
  22.                 {
  23.                         OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
  24.                         OLED_WR_Byte(0xA1,OLED_CMD);
  25.                 }
  26.         if(i==1)
  27.                 {
  28.                         OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
  29.                         OLED_WR_Byte(0xA0,OLED_CMD);
  30.                 }
  31. }


  32. void OLED_WR_Byte(u8 dat,u8 cmd)
  33. {        
  34.         u8 i;                          
  35.         if(cmd)
  36.           OLED_DC_Set();
  37.         else
  38.           OLED_DC_Clr();
  39.         OLED_CS_Clr();
  40.         for(i=0;i<8;i++)
  41.         {
  42.                 OLED_SCLK_Clr();
  43.                 if(dat&0x80)
  44.                    OLED_SDIN_Set();
  45.                 else
  46.                    OLED_SDIN_Clr();
  47.                 OLED_SCLK_Set();
  48.                 dat<<=1;   
  49.         }                                                   
  50.         OLED_CS_Set();
  51.         OLED_DC_Set();            
  52. }

  53. //开启OLED显示
  54. void OLED_DisPlay_On(void)
  55. {
  56.         OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
  57.         OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵
  58.         OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕
  59. }

  60. //关闭OLED显示
  61. void OLED_DisPlay_Off(void)
  62. {
  63.         OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
  64.         OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵
  65.         OLED_WR_Byte(0xAF,OLED_CMD);//关闭屏幕
  66. }

  67. //更新显存到OLED        
  68. void OLED_Refresh(void)
  69. {
  70.         u8 i,n;
  71.         for(i=0;i<8;i++)
  72.         {
  73.            OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址
  74.            OLED_WR_Byte(0x00,OLED_CMD);   //设置低列起始地址
  75.            OLED_WR_Byte(0x10,OLED_CMD);   //设置高列起始地址
  76.            for(n=0;n<128;n++)
  77.                  OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
  78.   }
  79. }
  80. //清屏函数
  81. void OLED_Clear(void)
  82. {
  83.         u8 i,n;
  84.         for(i=0;i<8;i++)
  85.         {
  86.            for(n=0;n<128;n++)
  87.                         {
  88.                          OLED_GRAM[n][i]=0;//清除所有数据
  89.                         }
  90.   }
  91.         OLED_Refresh();//更新显示
  92. }

  93. //画点
  94. //x:0~127
  95. //y:0~63
  96. void OLED_DrawPoint(u8 x,u8 y)
  97. {
  98.         u8 i,m,n;
  99.         i=y/8;
  100.         m=y%8;
  101.         n=1<<m;
  102.         OLED_GRAM[x][i]|=n;
  103. }

  104. //清除一个点
  105. //x:0~127
  106. //y:0~63
  107. void OLED_ClearPoint(u8 x,u8 y)
  108. {
  109.         u8 i,m,n;
  110.         i=y/8;
  111.         m=y%8;
  112.         n=1<<m;
  113.         OLED_GRAM[x][i]=~OLED_GRAM[x][i];
  114.         OLED_GRAM[x][i]|=n;
  115.         OLED_GRAM[x][i]=~OLED_GRAM[x][i];
  116. }


  117. //画线
  118. //x:0~128
  119. //y:0~64
  120. void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2)
  121. {
  122.         u8 i,k,k1,k2,y0;
  123.         if((x1<0)||(x2>128)||(y1<0)||(y2>64)||(x1>x2)||(y1>y2))return;
  124.         if(x1==x2)    //画竖线
  125.         {
  126.                         for(i=0;i<(y2-y1);i++)
  127.                         {
  128.                                 OLED_DrawPoint(x1,y1+i);
  129.                         }
  130.   }
  131.         else if(y1==y2)   //画横线
  132.         {
  133.                         for(i=0;i<(x2-x1);i++)
  134.                         {
  135.                                 OLED_DrawPoint(x1+i,y1);
  136.                         }
  137.   }
  138.         else      //画斜线
  139.         {
  140.                 k1=y2-y1;
  141.                 k2=x2-x1;
  142.                 k=k1*10/k2;
  143.                 for(i=0;i<(x2-x1);i++)
  144.                         {
  145.                           OLED_DrawPoint(x1+i,y1+i*k/10);
  146.                         }
  147.         }
  148. }
  149. //x,y:圆心坐标
  150. //r:圆的半径
  151. void OLED_DrawCircle(u8 x,u8 y,u8 r)
  152. {
  153.         int a, b,num;
  154.     a = 0;
  155.     b = r;
  156.     while(2 * b * b >= r * r)      
  157.     {
  158.         OLED_DrawPoint(x + a, y - b);
  159.         OLED_DrawPoint(x - a, y - b);
  160.         OLED_DrawPoint(x - a, y + b);
  161.         OLED_DrawPoint(x + a, y + b);

  162.         OLED_DrawPoint(x + b, y + a);
  163.         OLED_DrawPoint(x + b, y - a);
  164.         OLED_DrawPoint(x - b, y - a);
  165.         OLED_DrawPoint(x - b, y + a);
  166.         
  167.         a++;
  168.         num = (a * a + b * b) - r*r;//计算画的点离圆心的距离
  169.         if(num > 0)
  170.         {
  171.             b--;
  172.             a--;
  173.         }
  174.     }
  175. }



  176. //在指定位置显示一个字符,包括部分字符
  177. //x:0~127
  178. //y:0~63
  179. //size:选择字体 12/16/24
  180. //取模方式 逐列式
  181. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1)
  182. {
  183.         u8 i,m,temp,size2,chr1;
  184.         u8 y0=y;
  185.         size2=(size1/8+((size1%8)?1:0))*(size1/2);  //得到字体一个字符对应点阵集所占的字节数
  186.         chr1=chr-' ';  //计算偏移后的值
  187.         for(i=0;i<size2;i++)
  188.         {
  189.                 if(size1==12)
  190.         {temp=asc2_1206[chr1][i];} //调用1206字体
  191.                 else if(size1==16)
  192.         {temp=asc2_1608[chr1][i];} //调用1608字体
  193.                 else if(size1==24)
  194.         {temp=asc2_2412[chr1][i];} //调用2412字体
  195.                 else return;
  196.                                 for(m=0;m<8;m++)           //写入数据
  197.                                 {
  198.                                         if(temp&0x80)OLED_DrawPoint(x,y);
  199.                                         else OLED_ClearPoint(x,y);
  200.                                         temp<<=1;
  201.                                         y++;
  202.                                         if((y-y0)==size1)
  203.                                         {
  204.                                                 y=y0;
  205.                                                 x++;
  206.                                                 break;
  207.           }
  208.                                 }
  209.   }
  210. }


  211. //显示字符串
  212. //x,y:起点坐标  
  213. //size1:字体大小
  214. //*chr:字符串起始地址
  215. void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1)
  216. {
  217.         while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
  218.         {
  219.                 OLED_ShowChar(x,y,*chr,size1);
  220.                 x+=size1/2;
  221.                 if(x>128-size1)  //换行
  222.                 {
  223.                         x=0;
  224.                         y+=2;
  225.     }
  226.                 chr++;
  227.   }
  228. }

  229. //m^n
  230. u32 OLED_Pow(u8 m,u8 n)
  231. {
  232.         u32 result=1;
  233.         while(n--)
  234.         {
  235.           result*=m;
  236.         }
  237.         return result;
  238. }

  239. ////显示2个数字
  240. ////x,y :起点坐标         
  241. ////len :数字的位数
  242. ////size:字体大小
  243. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1)
  244. {
  245.         u8 t,temp;
  246.         for(t=0;t<len;t++)
  247.         {
  248.                 temp=(num/OLED_Pow(10,len-t-1))%10;
  249.                         if(temp==0)
  250.                         {
  251.                                 OLED_ShowChar(x+(size1/2)*t,y,'0',size1);
  252.       }
  253.                         else
  254.                         {
  255.                           OLED_ShowChar(x+(size1/2)*t,y,temp+'0',size1);
  256.                         }
  257.   }
  258. }

  259. //显示汉字
  260. //x,y:起点坐标
  261. //num:汉字对应的序号
  262. //取模方式 列行式
  263. void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1)
  264. {
  265.         u8 i,m,n=0,temp,chr1;
  266.         u8 x0=x,y0=y;
  267.         u8 size3=size1/8;
  268.         while(size3--)
  269.         {
  270.                 chr1=num*size1/8+n;
  271.                 n++;
  272.                         for(i=0;i<size1;i++)
  273.                         {
  274.                                 if(size1==16)
  275.                                                 {temp=Hzk1[chr1][i];}//调用16*16字体
  276.                                 else if(size1==24)
  277.                                                 {temp=Hzk2[chr1][i];}//调用24*24字体
  278.                                 else if(size1==32)      
  279.                                                 {temp=Hzk3[chr1][i];}//调用32*32字体
  280.                                 else if(size1==64)
  281.                                                 {temp=Hzk4[chr1][i];}//调用64*64字体
  282.                                 else return;
  283.                                                         
  284.                                                 for(m=0;m<8;m++)
  285.                                                         {
  286.                                                                 if(temp&0x01)OLED_DrawPoint(x,y);
  287.                                                                 else OLED_ClearPoint(x,y);
  288.                                                                 temp>>=1;
  289.                                                                 y++;
  290.                                                         }
  291.                                                         x++;
  292.                                                         if((x-x0)==size1)
  293.                                                         {x=x0;y0=y0+8;}
  294.                                                         y=y0;
  295.                          }
  296.         }
  297. }

  298. //num 显示汉字的个数
  299. //space 每一遍显示的间隔
  300. void OLED_ScrollDisplay(u8 num,u8 space)
  301. {
  302.         u8 i,n,t=0,m=0,r;
  303.         while(1)
  304.         {
  305.                 if(m==0)
  306.                 {
  307.             OLED_ShowChinese(128,24,t,16); //写入一个汉字保存在OLED_GRAM[][]数组中
  308.                         t++;
  309.                 }
  310.                 if(t==num)
  311.                         {
  312.                                 for(r=0;r<16*space;r++)      //显示间隔
  313.                                  {
  314.                                         for(i=0;i<144;i++)
  315.                                                 {
  316.                                                         for(n=0;n<8;n++)
  317.                                                         {
  318.                                                                 OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
  319.                                                         }
  320.                                                 }
  321.            OLED_Refresh();
  322.                                  }
  323.         t=0;
  324.       }
  325.                 m++;
  326.                 if(m==16){m=0;}
  327.                 for(i=0;i<144;i++)   //实现左移
  328.                 {
  329.                         for(n=0;n<8;n++)
  330.                         {
  331.                                 OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
  332.                         }
  333.                 }
  334.                 OLED_Refresh();
  335.         }
  336. }

  337. //配置写入数据的起始位置
  338. void OLED_WR_BP(u8 x,u8 y)
  339. {
  340.         OLED_WR_Byte(0xb0+y,OLED_CMD);//设置行起始地址
  341.         OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
  342.         OLED_WR_Byte((x&0x0f),OLED_CMD);
  343. }

  344. //x0,y0:起点坐标
  345. //x1,y1:终点坐标
  346. //BMP[]:要写入的图片数组
  347. void OLED_ShowPicture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[])
  348. {
  349.         u32 j=0;
  350.         u8 x=0,y=0;
  351.         if(y%8==0)y=0;
  352.         else y+=1;
  353.         for(y=y0;y<y1;y++)
  354.          {
  355.                  OLED_WR_BP(x0,y);
  356.                  for(x=x0;x<x1;x++)
  357.                  {
  358.                          OLED_WR_Byte(BMP[j],OLED_DATA);
  359.                          j++;
  360.      }
  361.          }
  362. }
  363. //OLED的初始化
  364. void OLED_Init(void)
  365. {
  366.         GPIO_InitTypeDef  GPIO_InitStructure;
  367.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);         //使能A端口时钟
  368.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7;         
  369.          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  370.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
  371.          GPIO_Init(GPIOA, &GPIO_InitStructure);          //初始化GPIOD3,6
  372.          GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_4);        
  373.         
  374.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);         //使能A端口时钟
  375.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8|GPIO_Pin_6|GPIO_Pin_7;
  376.          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
  377.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
  378.          GPIO_Init(GPIOB, &GPIO_InitStructure);          //初始化GPIOD3,6
  379.          GPIO_SetBits(GPIOB,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8|GPIO_Pin_6|GPIO_Pin_7);
  380.         
  381.         
  382.         OLED_RST_Set();
  383.         delay_ms(100);
  384.         OLED_RST_Clr();//复位
  385.         delay_ms(200);
  386.         OLED_RST_Set();
  387.         
  388.         OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
  389.         OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  390.         OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  391.         OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
  392.         OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
  393.         OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
  394.         OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
  395.         OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
  396.         OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
  397.         OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  398.         OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
  399.         OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset        Shift Mapping RAM Counter (0x00~0x3F)
  400.         OLED_WR_Byte(0x00,OLED_CMD);//-not offset
  401.         OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
  402.         OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
  403.         OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
  404.         OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  405.         OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
  406.         OLED_WR_Byte(0x12,OLED_CMD);
  407.         OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
  408.         OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
  409.         OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
  410.         OLED_WR_Byte(0x02,OLED_CMD);//
  411.         OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
  412.         OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
  413.         OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
  414.         OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
  415.         OLED_WR_Byte(0xAF,OLED_CMD);
  416.         OLED_Clear();
  417. }
复制代码
代码下载: 02-0.96OLED显示屏STM32F103RCT6_IIC例程.zip (309.65 KB, 下载次数: 37)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表