stm32 ssD1306 OLED驱动架构

发布者:等放假的zr0最新更新时间:2019-08-10 来源: eefocus关键字:stm32  ssD1306  OLED  驱动架构 手机看文章 扫描二维码
随时随地手机看文章

#include "oled.h"

#include "stdlib.h"

#include "oledfont.h"    

#include "delay.h"




//OLED的显存

//存放格式如下.

//[0]0 1 2 3 ... 127    

//[1]0 1 2 3 ... 127    

//[2]0 1 2 3 ... 127    

//[3]0 1 2 3 ... 127    

//[4]0 1 2 3 ... 127    

//[5]0 1 2 3 ... 127    

//[6]0 1 2 3 ... 127    

//[7]0 1 2 3 ... 127           

u8 OLED_GRAM[128][8];    


//更新显存到LCD       

void OLED_Refresh_Gram(void)

{

    u8 i,n;         

    for(i=0;i<8;i++)  

    {  

        OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)    //设置开始的页地址

        OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址    设置起始显示的列低地址

        OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址    设置起始显示的列高地址

        for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); 

    }   

}

#if OLED_MODE==1    //8080并口 

//向SSD1306写入一个字节。

//dat:要写入的数据/命令

//cmd:数据/命令标志 0,表示命令;1,表示数据;

void OLED_WR_Byte(u8 dat,u8 cmd)

{

    DATAOUT(dat);       

    OLED_RS=cmd;

    OLED_CS=0;     

    OLED_WR=0;   

    OLED_WR=1;

    OLED_CS=1;    

    OLED_RS=1;   

}               

#else

//向SSD1306写入一个字节。

//dat:要写入的数据/命令

//cmd:数据/命令标志 0,表示命令;1,表示数据;

void OLED_WR_Byte(u8 dat,u8 cmd)

{   

    u8 i;             

    OLED_RS=cmd; //写命令 

    OLED_CS=0;        

    for(i=0;i<8;i++)

    {             

        OLED_SCLK=0;

        if(dat&0x80)OLED_SDIN=1;

        else OLED_SDIN=0;

        OLED_SCLK=1;

        dat<<=1;   

    }                

    OLED_CS=1;        

    OLED_RS=1;        

#endif


//开启OLED显示    

void OLED_Display_On(void)

{

    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令

    OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON      开启电荷泵

    OLED_WR_Byte(0XAF,OLED_CMD);  // PLAY ON     开启显示命令

}

//关闭OLED显示     

void OLED_Display_Off(void)

{

    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令  

    OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF    0x8D指令后的指令是设置的命令值  关闭电荷泵

    OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF   关闭显示命令

}                    

//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!     

void OLED_Clear(void)  

{  

    u8 i,n;  

    for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X00;  

    OLED_Refresh_Gram();//更新显示

}

//画点 

//x:0~127

//y:0~63

//t:1 填充 0,清空                  

void OLED_DrawPoint(u8 x,u8 y,u8 mode)

{

    u8 pos,bx,temp=0;

    if(x>127||y>63)return;//超出范围了.

    pos=7-y/8;

    bx=y%8;

    temp=1<<(7-bx);

    if(mode)OLED_GRAM[x][pos]|=temp;

    else OLED_GRAM[x][pos]&=~temp;     

}

//x1,y1,x2,y2 填充区域的对角坐标

//确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63       

//dot:0,清空;1,填充   

void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 mode)  

{  

    u8 x,y;  

    for(x=x1;x<=x2;x++)

    {

        for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,mode);

    }                                                       

    OLED_Refresh_Gram();//更新显示

}

//在指定位置显示一个字符,包括部分字符

//x:0~127

//y:0~63

//mode:0,反白显示;1,正常显示                 

//size:选择字体 12/16/24

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)

{                   

    u8 temp,t,t1;

    u8 y0=y;

    u8 csize=(size/8+((size%8)?1:0))*(size/2);      //得到字体一个字符对应点阵集所占的字节数

    chr=chr-' ';//得到偏移后的值   因为点阵的第0行是" ",所以这里需要减去' ' 

    for(t=0;t    {   

        if(size==12)temp=asc2_1206[chr][t];         //调用1206字体

        else if(size==16)temp=asc2_1608[chr][t];    //调用1608字体

        else if(size==24)temp=asc2_2412[chr][t];    //调用2412字体

        else return;                                //没有的字库

        for(t1=0;t1<8;t1++)

        {

            if(temp&0x80)OLED_DrawPoint(x,y,mode);

            else OLED_DrawPoint(x,y,!mode);

            temp<<=1;

            y++;

            if((y-y0)==size)//判断一列是否画点完成

            {

                y=y0;

                x++;       //进入下一列画点

                break;

            }

        }    

    }          

}

//m^n函数

u32 mypow(u8 m,u8 n)

{

    u32 result=1;    

    while(n--)result*=m;    

    return result;

}                 

//显示2个数字

//x,y :起点坐标  

//len :数字的位数

//size:字体大小

//mode:模式   0,填充模式;1,叠加模式

//num:数值(0~4294967295);              

void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)

{           

    u8 t,temp;

    u8 enshow=0;                           

    for(t=0;t    {

        temp=(num/mypow(10,len-t-1))%10;

        if(enshow==0&&t<(len-1))

        {

            if(temp==0)

            {

                OLED_ShowChar(x+(size/2)*t,y,' ',size,1);

                continue;

            }else enshow=1;     //第一个temp为最高位数,如果为0则不显示,enshow为1,防止后面个位数的数字为零也不显示,

                                //个位的数字为零应该显示0


        }

        OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1); 

    }

//显示字符串

//x,y:起点坐标  

//size:字体大小 

//*p:字符串起始地址 

void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)

{   

    while((*p<='~')&&(*p>=' '))//判断是不是非法字符!

    {       

        if(x>(128-(size/2))){x=0;y+=size;}   //

        if(y>(64-size)){y=x=0;OLED_Clear();}

        OLED_ShowChar(x,y,*p,size,1);   //*p指向的是字符串的第一个字符

        x+=size/2;

        p++;

    }  


}      

//初始化SSD1306                        

void OLED_Init(void)

{   


    GPIO_InitTypeDef  GPIO_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE);  //使能PC,D,G端口时钟


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_6;     //PD3,PD6推挽输出  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz

    GPIO_Init(GPIOD, &GPIO_InitStructure);    //初始化GPIOD3,6

    GPIO_SetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_6);  //PD3,PD6 输出高


 #if OLED_MODE==1


    GPIO_InitStructure.GPIO_Pin =0xFF; //PC0~7 OUT推挽输出

    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_SetBits(GPIOC,0xFF); //PC0~7输出高


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;               //PG13,14,15 OUT推挽输出

    GPIO_Init(GPIOG, &GPIO_InitStructure);

    GPIO_SetBits(GPIOG,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);                         //PG13,14,15 OUT  输出高


 #else

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;                 //PC0,1 OUT推挽输出

    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_SetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1);                       //PC0,1 OUT  输出高

[1] [2]
关键字:stm32  ssD1306  OLED  驱动架构 引用地址:stm32 ssD1306 OLED驱动架构

上一篇:stm32f0 TIM1实现输出PWM波形
下一篇:stm32 NRF24L01

推荐阅读最新更新时间:2024-11-08 20:48

STM32基础知识2-分享PWM输入模式捕捉4路PWM波形的周期和占空比
前几天分享过一个帖子,因为网速原因没有上传源码,看到有人回复我说实验不成功,那么好吧!这是我的错误,这次就将源码和我的心得体会分享出来,供大家下载测试和成长。我其实也是菜鸟一个,如果讲解的地方有啥不对,或是程序设计的不好,欢迎大家提出意见,让我们一起来学习进步。 PWM输入是输入捕获的一个特殊应用,输入捕获就是当连接到定时器的引脚上产生电平变化时对应的捕获装置会立即将当前计数值复制到另一个寄存器中。你可以开启捕获中断然后在中断处理函数中读出保存的计数值。 与输入捕获不同的是PWM输入模式会将同一个输入信号(TI1或TI2)连接到两个捕获装置(IC1和IC2)。这两个捕获装置一个捕获上升沿一个捕获下降沿。TI1FP1、TI2
[单片机]
<font color='red'>STM32</font>基础知识2-分享PWM输入模式捕捉4路PWM波形的周期和占空比
LGD否认OLED项目落户广州
    北京商报讯(记者 陈维)5月10日,韩国面板厂商LG Display(以下简称“LGD”)针对将在广州上马OLED项目的传闻,进行了澄清。LGD广州工厂负责对外传播的乐金显示(中国)有限公司对外协力副部长闽东植也表示:“我们目前没有这个想法。”   随着OLED技术的不断发展,OLED电视近年来也备受业界关注,OLED因为自发光、色彩炫丽、可折叠弯曲等特点,更是被认为是下一代显示技术。而LGD目前是全球惟一一家供应大尺寸OLED电视面板的供应商,同时中国作为全球彩电主要生产地,对OLED面板需求旺盛。这也引发了业界对LGD将在国内增设OLED面板厂商的猜测。   LGD已在广州投资建设了8.5代液晶面板生产线,这曾是广州外
[手机便携]
WitsView:明年OLED电视出货年增66%
  WitsView最新研究预期,高阶电视采用 OLED 技术已难撼动,QLED阵营若往8K电视发展,也许可以重拾竞争力。下面就随手机便携小编一起来了解一下相关内容吧。   据研究机构WitsView最新研究,明年 OLED 技术将站稳高阶电视背光市场,随着愈多电视品牌加入 OLED 行列, 预期高阶电视采用OLED技术已难撼动,预期明年OLED电视出货数将达250万台新高,较今年的150万台,年增66%。   WitsView表示,今年OLED市场因 SONY 等国际大厂导入推出,且产品在终端市场获得好评,OLED电视出货表现超乎预期;虽然OLED有机材料有色衰问题,长时间使用也可能会出现残影, 但OLED不管在色饱和度与对比
[手机便携]
STM32 基于串口RS485双机通信原理浅析
RS485通信想必大家都知道,在学习RS232时,都会拿485(RS485下文就用485代替)和其作对比。485优缺点不说,网上有 我用的是STM32库函数学的485通信,所以接下来就讲讲STM32串口实现485双机通信的原理: 485和232都是基于串口的通讯接口,在数据的收发操作上都是一致的。但是他两的通讯模式却大不相同~!232是全双工(例:A- B的同时B- A,瞬时同步)工作模式,而485是半双工(发时不能收,收时不能发)工作模式。在232通信中,主机在发送数据的同时可以收到从机发过来的数据;但在485通信中,收发要经过模式位的切换来进行,譬如,发送数据时,会把模式为置‘1’,表示为发送模式,此时不能接收;当接收数据时
[单片机]
<font color='red'>STM32</font> 基于串口RS485双机通信原理浅析
STM32定时器的输入滤波机制
STM32的定时器输入通道都有一个滤波单元,分别位于每个输入通路上(下图中的黄色框)和外部触发输入通路上(下图中的兰色框),它们的作用是滤除输入信号上的高频干扰。 具体操作原理如下: 在TIMx_CR1中的CKD 可以由用户设置对输入信号的采样频率基准,有三种选择: 1)采样频率基准fDTS=定时器输入频率fCK_INT 2)采样频率基准fDTS=定时器输入频率fCK_INT/2 3)采样频率基准fDTS=定时器输入频率fCK_INT/4 然后使用上述频率作为基准对输入信号进行采样,当连续采样到N次个有效电平时,认为一次有效的输入电平。 实际的采样频率和采样次数可以由用户程序根据需要选择;外部触发输入通道的滤波参数
[模拟电子]
<font color='red'>STM32</font>定时器的输入滤波机制
stm32adc多通道数据采集
word文档链接: http://download.csdn.net/detail/mjlsuccess/6031351 ,免费的 工程连接: http://download.csdn.net/detail/mjlsuccess/6202155 /** @date 2013/8/28 @author Mei Jilin @brief ADC1的配置完成3通道的数据采集 @attention 1 ----------- adc_config(); //配置adc 2 ----------- adc_start(); //启动adc,开始转换 3 -----
[单片机]
STM32定时器中断应用实例
本文将介绍:通过STM32cube mx配置工程文件,实现定时器中断的功能; 实例中使用的是STM32F407芯片 ①STM32cube mx配置工程文件 ②代码实现 ①STM32cube mx配置工程文件 Step1:使能RCC、选择外部晶振 Step2:配置时钟树 Step3:使能TIM6、配置TIM6 ,1秒产生一次定时器中断 Step4:配置中断的优先级分组、中断优先级 Step4:使能串口、用于调试使用 Step5:生成工程文件 ②代码实现 Step1:编写串口输出重定向函数,用于调试使用;记得添加头文件stdio.h Step2:开启定时器中断 Step3:自定义定时器中断服务函数 先在
[单片机]
<font color='red'>STM32</font>定时器中断应用实例
英飞凌推出新型PSoC™汽车多点触控控制器, 为OLED和超大屏幕提供卓越的触控性能
【2024年10月22日, 德国慕尼黑讯】 在不断发展的汽车行业,车载信息娱乐应用需要提供丝滑的人机界面(HMI)体验。客户往往偏好具有先进功能的大型触控屏,并将OLED和Micro OLED作为首选的显示屏。 OLED因支持灵活的设计和自由的形状,而被视为智能移动应用的未来趋势。想要给终端用户带来丝滑的使用过程,就需要兼顾最佳客户体验和功能安全标准。为了应对这些挑战,全球功率系统和物联网领域的半导体领导者英飞凌科技股份公司推出新一代触控控制器——PSoC™ GEN8XL汽车多点触控控制器(IAAT818X)。 该触控控制器专为24英寸及以下的OLED和Micro-LED 显示屏设计,其性能和帧速率均能满足当今的需求 。它能够在触
[汽车电子]
英飞凌推出新型PSoC™汽车多点触控控制器,  为<font color='red'>OLED</font>和超大屏幕提供卓越的触控性能
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved