STM32CUBEMX(12)--IIC,12864OLED(0.96寸)移植

2023-09-28  

概述

I2C总线硬件简单,资源消耗少,只有时钟和数据线。本例程主要讲解如何点亮0.96寸的OLED屏幕,本例程采用的是STM32F030R8T6,64K大小的Flash。


硬件准备

首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:

在这里插入图片描述

OLED显示屏就是淘宝上IIC接口的12864模块。在这里插入图片描述

选择芯片型号

使用STM32CUBEMX选择芯片stm32f030r8,如下所示:

在这里插入图片描述

配置时钟源

HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:

在这里插入图片描述

配置时钟树

STM32F0的最高主频到48M,所以配置48即可:

在这里插入图片描述

IIC配置

本次实验使用的IIC与显示屏通信,配置如下。

在这里插入图片描述

生成工程设置

注意在生产工程设置中不能出现中文,不然会报错。

在这里插入图片描述

生成代码

在这里插入图片描述

配置keil

在这里插入图片描述


驱动代码

oled.c

#include "oled.h"

#include "i2c.h"

#include "oledfont.h"          //头文件


uint8_t CMD_Data[]={

0xAE,    

0x00,    

0x10,    

0x40,    

0xB0,

0x81,

0xFF,

0xA1,

0xA6,

0xA8,

0x3F,                    

0xC8,

0xD3,

0x00,

0xD5,

0x80,

0xD8,

0x05,

0xD9,

0xF1,

0xDA,

0x12,

0xD8,

0x30,

0x8D,

0x14,    

0xAF    

};      //初始化命令



void WriteCmd(void)

{

    uint8_t i = 0;

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

    {

        HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,CMD_Data+i,1,0x100);

    }

}

//向设备写控制命令

void OLED_WR_CMD(uint8_t cmd)

{

    HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100);

}

//向设备写数据

void OLED_WR_DATA(uint8_t data)

{

    HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100);

}

//初始化oled屏幕

void OLED_Init(void)

{     

    HAL_Delay(200);


    WriteCmd();

}

//清屏

void OLED_Clear(void)

{

    uint8_t i,n;            

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

    {  

        OLED_WR_CMD(0xb0+i);//设置页地址(0~7)

        OLED_WR_CMD (0x00); //设置显示位置—列低地址

        OLED_WR_CMD (0x10); //设置显示位置—列高地址

        for(n=0;n<128;n++)

            OLED_WR_DATA(0);//更新显示

    } 

}

//开启OLED显示    

void OLED_Display_On(void)

{

    OLED_WR_CMD(0X8D);  //SET DCDC命令

    OLED_WR_CMD(0X14);  //DCDC ON

    OLED_WR_CMD(0XAF);  //DISPLAY ON

}

//关闭OLED显示     

void OLED_Display_Off(void)

{

    OLED_WR_CMD(0X8D);  //SET DCDC命令

    OLED_WR_CMD(0X10);  //DCDC OFF

    OLED_WR_CMD(0XAE);  //DISPLAY OFF

}    

//坐标设置 

void OLED_Set_Pos(uint8_t x, uint8_t y) 

{     

    OLED_WR_CMD(0xb0+y);

    OLED_WR_CMD(((x&0xf0)>>4)|0x10);

    OLED_WR_CMD(x&0x0f);


void OLED_On(void)  

{  

    uint8_t i,n;            

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

    {  

        OLED_WR_CMD(0xb0+i);    //设置页地址(0~7)

        OLED_WR_CMD(0x00);      //设置显示位置—列低地址

        OLED_WR_CMD(0x10);      //设置显示位置—列高地址   

        for(n=0;n<128;n++)

            OLED_WR_DATA(1); 

    } //更新显示

}

unsigned int oled_pow(uint8_t m,uint8_t n)

{

    unsigned int result=1;   

    while(n--)result*=m;    

    return result;

}

//显示2个数字

//x,y :起点坐标     

//len :数字的位数

//size:字体大小

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

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

void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2)

{             

    uint8_t t,temp;

    uint8_t enshow=0;                          

    for(t=0;t10,len-t-1))%10;

        if(enshow==0&&t        {

            if(temp==0)

            {

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

                continue;

            }else enshow=1; 


        }

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

    }

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

//x:0~127

//y:0~63

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

//size:选择字体 16/12 

void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)

{          

    unsigned char c=0,i=0;  

        c=chr-' ';//得到偏移后的值         

        if(x>128-1)

        {

            x=0;

            y=y+2;

        }

        if(Char_Size ==16)

            {

            OLED_Set_Pos(x,y);  

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

                OLED_WR_DATA(F8X16[c*16+i]);

            OLED_Set_Pos(x,y+1);

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

                OLED_WR_DATA(F8X16[c*16+i+8]);

            }

            else {  

                OLED_Set_Pos(x,y);

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

                OLED_WR_DATA(F6x8[c][i]);


            }

}


//显示一个字符号串

void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)

{

    unsigned char j=0;

    while (chr[j]!='')

    {       

        OLED_ShowChar(x,y,chr[j],Char_Size);//一次显示一个字符

            x+=8;

        if(x>120){x=0;y+=2;}

            j++;

    }

}

//显示汉字

//hzk 用取模软件得出的数组

void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)

{                      

    uint8_t t,adder=0;

//定位(0xbx,x为第几行。0x1x ,x为列地址 高四位;0x0x,x为列地址第4位。

//比如你想定 位到第3行,第126(0x7e)列,就要写WrCmd(0xb3);WrCmd(0x17);WrCmd(0x0e);)    

    OLED_Set_Pos(x,y);  

    for(t=0;t<16;t++)

        {

                OLED_WR_DATA(Hzk[2*no][t]);

                adder+=1;

     }    

        OLED_Set_Pos(x,y+1);    

    for(t=0;t<16;t++)

            {   

                OLED_WR_DATA(Hzk[2*no+1][t]);

                adder+=1;

      }                    

}

oled.h

#ifndef __OLED_H__

#define __OLED_H__


#include "stm32f0xx_hal.h"


///

#define   OLED_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOA_CLK_ENABLE()


#define   GPIOx_OLED_PORT               GPIOB

#define   OLED_SCK_PIN                  GPIO_PIN_6

#define   OLED_SCK_ON()                 HAL_GPIO_WritePin(GPIOx_OLED_PORT, OLED_SCK_PIN, GPIO_PIN_SET)

#define   OLED_SCK_OFF()                HAL_GPIO_WritePin(GPIOx_OLED_PORT, OLED_SCK_PIN, GPIO_PIN_RESET)

#define   OLED_SCK_TOGGLE()             HAL_GPIO_TogglePin(GPIOx_OLED_PORT, OLED_SCK_PIN)

#define   OLED_SDA_PIN                  GPIO_PIN_7

#define   OLED_SDA_ON()                 HAL_GPIO_WritePin(GPIOx_OLED_PORT, OLED_SDA_PIN, GPIO_PIN_SET)

#define   OLED_SDA_OFF()                HAL_GPIO_WritePin(GPIOx_OLED_PORT, OLED_SDA_PIN, GPIO_PIN_RESET)

#define   OLED_SDA_TOGGLE()             HAL_GPIO_TogglePin(GPIOx_OLED_PORT, OLED_SDA_PIN)

///


void WriteCmd(void);

void OLED_WR_CMD(uint8_t cmd);

void OLED_WR_DATA(uint8_t data);

void OLED_Init(void);

void OLED_Clear(void);

void OLED_Display_On(void);

void OLED_Display_Off(void);

void OLED_Set_Pos(uint8_t x, uint8_t y);

void OLED_On(void);

void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2);

void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size);

void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size);

void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no);


#endif

oledfont.h

#ifndef __OLEDFONT_H__

#define __OLEDFONT_H__


#include "stm32f0xx_hal.h"


//8*6 ASCII字符集点阵

const unsigned char F6x8[][6] =        

{

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp

    0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !

    0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "

    0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #

    0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $

    0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %

    0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &

    0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '

    0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (

    0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )

    0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *

    0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。