找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4008|回复: 0
收起左侧

STM32 OLED例程

[复制链接]
ID:384158 发表于 2018-8-8 13:27 | 显示全部楼层 |阅读模式
STM32  OLED例程

单片机源程序如下:
  1. #include "oled.h"
  2. #include "stdlib.h"
  3. #include "delay.h"
  4. #include "oledfont.h"

  5. //OLED的显存
  6. //存放格式如下.
  7. //[0]0 1 2 3 ... 127       
  8. //[1]0 1 2 3 ... 127       
  9. //[2]0 1 2 3 ... 127       
  10. //[3]0 1 2 3 ... 127       
  11. //[4]0 1 2 3 ... 127       
  12. //[5]0 1 2 3 ... 127       
  13. //[6]0 1 2 3 ... 127       
  14. //[7]0 1 2 3 ... 127                   
  15. u8 OLED_GRAM[128][8];         

  16. //更新显存到LCD                 
  17. void OLED_Refresh_Gram(void)
  18. {
  19.         u8 i,n;                    
  20.         for(i=0;i<8;i++)  
  21.         {  
  22.                 OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
  23.                 OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
  24.                 OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
  25.                 for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
  26.         }   
  27. }
  28. #if OLED_MODE==1        //8080并口

  29. //向SSD1306写入一个字节。
  30. //dat:要写入的数据/命令
  31. //cmd:数据/命令标志 0,表示命令;1,表示数据;
  32. void OLED_WR_Byte(u8 dat,u8 cmd)
  33. {
  34.         DATAOUT(dat);       
  35.         OLED_RS=cmd;
  36.         OLED_CS=0;       
  37.         OLED_WR=0;          
  38.         OLED_WR=1;   
  39.         OLED_CS=1;   
  40.         OLED_RS=1;   
  41. }                         
  42. #else
  43. //向SSD1306写入一个字节。
  44. //dat:要写入的数据/命令
  45. //cmd:数据/命令标志 0,表示命令;1,表示数据;
  46. void OLED_WR_Byte(u8 dat,u8 cmd)
  47. {       
  48.         u8 i;                          
  49.         OLED_RS=cmd; //写命令
  50.         OLED_CS=0;                  
  51.         for(i=0;i<8;i++)
  52.         {                          
  53.                 OLED_SCLK=0;
  54.                 if(dat&0x80)OLED_SDIN=1;
  55.                 else OLED_SDIN=0;
  56.                 OLED_SCLK=1;
  57.                 dat<<=1;   
  58.         }                                 
  59.         OLED_CS=1;                  
  60.         OLED_RS=1;             
  61. }
  62. #endif
  63.                     
  64. //开启OLED显示   
  65. void OLED_Display_On(void)
  66. {
  67.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  68.         OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
  69.         OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
  70. }
  71. //关闭OLED显示     
  72. void OLED_Display_Off(void)
  73. {
  74.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  75.         OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
  76.         OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
  77. }                                            
  78. //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!          
  79. void OLED_Clear(void)  
  80. {  
  81.         u8 i,n;  
  82.         for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X00;  
  83.         OLED_Refresh_Gram();//更新显示
  84. }
  85. //画点
  86. //x:0~127
  87. //y:0~63
  88. //t:1 填充 0,清空                                  
  89. void OLED_DrawPoint(u8 x,u8 y,u8 t)
  90. {
  91.         u8 pos,bx,temp=0;
  92.         if(x>127||y>63)return;//超出范围了.
  93.         pos=7-y/8;
  94.         bx=y%8;
  95.         temp=1<<(7-bx);
  96.         if(t)OLED_GRAM[x][pos]|=temp;
  97.         else OLED_GRAM[x][pos]&=~temp;            
  98. }
  99. //x1,y1,x2,y2 填充区域的对角坐标
  100. //确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63                  
  101. //dot:0,清空;1,填充          
  102. void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot)  
  103. {  
  104.         u8 x,y;  
  105.         for(x=x1;x<=x2;x++)
  106.         {
  107.                 for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,dot);
  108.         }                                                                                                            
  109.         OLED_Refresh_Gram();//更新显示
  110. }
  111. //在指定位置显示一个字符,包括部分字符
  112. //x:0~127
  113. //y:0~63
  114. //mode:0,反白显示;1,正常显示                                 
  115. //size:选择字体 12/16/24
  116. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
  117. {                                  
  118.         u8 temp,t,t1;
  119.         u8 y0=y;
  120.         u8 csize=(size/8+((size%8)?1:0))*(size/2);                //得到字体一个字符对应点阵集所占的字节数
  121.         chr=chr-' ';//得到偏移后的值                 
  122.     for(t=0;t<csize;t++)
  123.     {   
  124.                 if(size==12)temp=asc2_1206[chr][t];                  //调用1206字体
  125.                 else if(size==16)temp=asc2_1608[chr][t];        //调用1608字体
  126.                 else if(size==24)temp=asc2_2412[chr][t];        //调用2412字体
  127.                 else return;                                                                //没有的字库
  128.         for(t1=0;t1<8;t1++)
  129.                 {
  130.                         if(temp&0x80)OLED_DrawPoint(x,y,mode);
  131.                         else OLED_DrawPoint(x,y,!mode);
  132.                         temp<<=1;
  133.                         y++;
  134.                         if((y-y0)==size)
  135.                         {
  136.                                 y=y0;
  137.                                 x++;
  138.                                 break;
  139.                         }
  140.                 }           
  141.     }         
  142. }
  143. //m^n函数
  144. u32 mypow(u8 m,u8 n)
  145. {
  146.         u32 result=1;         
  147.         while(n--)result*=m;   
  148.         return result;
  149. }                                  
  150. //显示2个数字
  151. //x,y :起点坐标         
  152. //len :数字的位数
  153. //size:字体大小
  154. //mode:模式        0,填充模式;1,叠加模式
  155. //num:数值(0~4294967295);                           
  156. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
  157. {                
  158.         u8 t,temp;
  159.         u8 enshow=0;                                                  
  160.         for(t=0;t<len;t++)
  161.         {
  162.                 temp=(num/mypow(10,len-t-1))%10;
  163.                 if(enshow==0&&t<(len-1))
  164.                 {
  165.                         if(temp==0)
  166.                         {
  167.                                 OLED_ShowChar(x+(size/2)*t,y,' ',size,1);
  168.                                 continue;
  169.                         }else enshow=1;
  170.                           
  171.                 }
  172.                  OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1);
  173.         }
  174. }
  175. //显示字符串
  176. //x,y:起点坐标  
  177. //size:字体大小
  178. //*p:字符串起始地址
  179. void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)
  180. {       
  181.     while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
  182.     {      
  183.         if(x>(128-(size/2))){x=0;y+=size;}
  184.         if(y>(64-size)){y=x=0;OLED_Clear();}
  185.         OLED_ShowChar(x,y,*p,size,1);         
  186.         x+=size/2;
  187.         p++;
  188.     }  
  189.        
  190. }       
  191. //初始化SSD1306                                            
  192. void OLED_Init(void)
  193. {                           
  194.     GPIO_InitTypeDef  GPIO_Initure;
  195.        
  196.     __HAL_RCC_GPIOC_CLK_ENABLE();   //使能GPIOC时钟
  197.     __HAL_RCC_GPIOD_CLK_ENABLE();   //使能GPIOD时钟
  198.     __HAL_RCC_GPIOG_CLK_ENABLE();   //使能GPIOG时钟
  199.        
  200.         //GPIO初始化设置      
  201.     GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_6;        //PD3、PD6推挽输出
  202.     GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;        //推挽输出
  203.     GPIO_Initure.Pull=GPIO_PULLUP;                //上拉
  204.     GPIO_Initure.Speed=GPIO_SPEED_HIGH;           //快速
  205.     HAL_GPIO_Init(GPIOD,&GPIO_Initure);           //初始化
  206.          
  207.         //PD3,PD6 输出高
  208.         HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_SET);
  209.         HAL_GPIO_WritePin(GPIOD,GPIO_PIN_6,GPIO_PIN_SET);
  210.        
  211. #if OLED_MODE==1                //使用8080并口模式               
  212.        
  213.         //PC0~7 OUT推挽输出   
  214.     GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|\
  215.                                          GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;        
  216.     HAL_GPIO_Init(GPIOC,&GPIO_Initure);           //初始化
  217.        
  218.         //PG13,14,15 OUT推挽输出
  219.         GPIO_Initure.Pin=GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;       
  220.         HAL_GPIO_Init(GPIOG,&GPIO_Initure);//初始化       
  221.        
  222.         OLED_WR=1;
  223.           OLED_RD=1;
  224. #else                                        //使用4线SPI 串口模式

  225.         //GPIO初始化设置      
  226.     GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1;        //PC0,1 OUT推挽输出
  227.     GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;        //推挽输出
  228.     GPIO_Initure.Pull=GPIO_PULLUP;                //上拉
  229.     GPIO_Initure.Speed=GPIO_SPEED_HIGH;           //高速
  230.     HAL_GPIO_Init(GPIOC,&GPIO_Initure);           //初始化
  231.        
  232.         //PG15
  233.     GPIO_Initure.Pin=GPIO_PIN_15;       
  234.         HAL_GPIO_Init(GPIOG,&GPIO_Initure);//初始化
  235.        
  236.         OLED_SDIN=1;
  237.         OLED_SCLK=1;
  238. #endif
  239.         OLED_CS=1;
  240.         OLED_RS=1;         
  241.        
  242.         OLED_RST=0;
  243.         delay_ms(100);
  244.         OLED_RST=1;
  245.                                           
  246.         OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
  247.         OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
  248.         OLED_WR_Byte(80,OLED_CMD);   //[3:0],分频因子;[7:4],震荡频率
  249.         OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
  250.         OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64)
  251.         OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
  252.         OLED_WR_Byte(0X00,OLED_CMD); //默认为0
  253.         OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.                                                                                    
  254.         OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
  255.         OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
  256.         OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式
  257.         OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
  258.         OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
  259.         OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
  260.         OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
  261.         OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置         
  262.         OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
  263.         OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
  264.         OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
  265.         OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
  266.         OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
  267.         OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
  268.         OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
  269.         OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示                                                              
  270.         OLED_WR_Byte(0xAF,OLED_CMD); //开启显示         
  271.         OLED_Clear();
  272. }  
复制代码

所有资料51hei提供下载:
OLED.rar (9.29 KB, 下载次数: 63)


评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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