ARM-SPI屏幕案例

发布于:2025-09-02 ⋅ 阅读:(15) ⋅ 点赞:(0)

学习目标

  1. 掌握移植方法
  2. 掌握调试方式

学习内容

需求

官方测试示例

选择对应的平台

测试示例中,找到芯片对应平台,我们选择的是STM32F407

修改例程

已知错误修改:

oled.h中类型未定义错误

#ifndef u8
#define u8 uint8_t
#endif

#ifndef u16
#define u16 uint16_t
#endif

#ifndef u32
#define u32 uint32_t
#endif

引脚定义修改:

oled.h中引脚定义修改

#define CLK_RCU		RCC_AHB1Periph_GPIOA
#define CLK_PORT	GPIOA
#define CLK_PIN		GPIO_Pin_5

#define MOSI_RCU	RCC_AHB1Periph_GPIOA
#define MOSI_PORT	GPIOB
#define MOSI_PIN	GPIO_Pin_7

#define DC_RCU		RCC_AHB1Periph_GPIOA
#define DC_PORT		GPIOB
#define DC_PIN		GPIO_Pin_2

#define CS1_RCU		RCC_AHB1Periph_GPIOA
#define CS1_PORT	GPIOA
#define CS1_PIN		GPIO_Pin_3

#define MISO_RCU	RCC_AHB1Periph_GPIOA
#define MISO_PORT	GPIOB
#define MISO_PIN	GPIO_Pin_6

#define CS2_RCU		RCC_AHB1Periph_GPIOC
#define CS2_PORT	GPIOA
#define CS2_PIN		GPIO_Pin_5

#define OLED_SCL_Clr() GPIO_ResetBits(CLK_PORT, CLK_PIN)//SCL
#define OLED_SCL_Set() GPIO_SetBits(CLK_PORT, CLK_PIN)

#define OLED_SDA_Clr() GPIO_ResetBits(MOSI_PORT,MOSI_PIN)//SDA
#define OLED_SDA_Set() GPIO_SetBits(MOSI_PORT,MOSI_PIN)

#define OLED_DC_Clr()  GPIO_ResetBits(DC_PORT,DC_PIN)//DC
#define OLED_DC_Set()  GPIO_SetBits(DC_PORT,DC_PIN)

#define OLED_CS_Clr()  GPIO_ResetBits(CS1_PORT,CS1_PIN)//CS1
#define OLED_CS_Set()  GPIO_SetBits(CS1_PORT,CS1_PIN)

#define OLED_READ_FS0()    GPIO_ReadInputDataBit(MISO_PORT,MISO_PIN)//FS0

#define OLED_ROM_CS_Clr()  GPIO_ResetBits(CS2_PORT,CS2_PIN)//CS2
#define OLED_ROM_CS_Set()  GPIO_SetBits(CS2_PORT,CS2_PIN)

初始化逻辑修改:

oled.c的OLED_Init函数修改

GPIO_InitTypeDef  GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(CLK_RCU,ENABLE);//使能A端口时钟
GPIO_InitStructure.GPIO_Pin = CLK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(CLK_PORT, &GPIO_InitStructure);	 

RCC_AHB1PeriphClockCmd(CLK_RCU,ENABLE);
GPIO_InitStructure.GPIO_Pin = MOSI_PIN;
GPIO_Init(MOSI_PORT, &GPIO_InitStructure);

RCC_AHB1PeriphClockCmd(DC_RCU,ENABLE);
GPIO_InitStructure.GPIO_Pin = DC_PIN;
GPIO_Init(DC_PORT, &GPIO_InitStructure);

RCC_AHB1PeriphClockCmd(CS1_RCU,ENABLE);
GPIO_InitStructure.GPIO_Pin = CS1_PIN;
GPIO_Init(CS1_PORT, &GPIO_InitStructure);

RCC_AHB1PeriphClockCmd(CS2_RCU,ENABLE);
GPIO_InitStructure.GPIO_Pin = CS2_PIN;
GPIO_Init(CS2_PORT, &GPIO_InitStructure);

RCC_AHB1PeriphClockCmd(MISO_RCU,ENABLE);
GPIO_InitStructure.GPIO_Pin = MISO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(MISO_PORT, &GPIO_InitStructure);	  //初始化GPIOA

// 全部拉高
GPIO_SetBits(CLK_PORT, CLK_PIN);
GPIO_SetBits(MOSI_PORT, MOSI_PIN);
GPIO_SetBits(DC_PORT, DC_PIN);
GPIO_SetBits(CS1_PORT, CS1_PIN);
GPIO_SetBits(CS2_PORT, CS2_PIN);
烧录测试

STM32自己环境

切换自己的环境,进行测试。

  1. 拷贝oled文件
  2. 拷贝main中的核心逻辑
  3. 修改不兼容的api
完整代码

oled.h

#ifndef __OLED_H
#define __OLED_H 

#include "stm32f4xx.h"
#include "systick.h"

//SCL=SCLK 
//SDA=MOSI
//DC=DC
//CS=CS1
//FS0=MOSI
//CS2=CS2

#ifndef u8
#define u8 uint8_t
#endif

#ifndef u16
#define u16 uint16_t
#endif

#ifndef u32
#define u32 uint32_t
#endif

//-----------------OLED端口定义---------------- 
#define CLK_RCU		RCC_AHB1Periph_GPIOA
#define CLK_PORT	GPIOA
#define CLK_PIN		GPIO_Pin_5

#define MOSI_RCU	RCC_AHB1Periph_GPIOA
#define MOSI_PORT	GPIOB
#define MOSI_PIN	GPIO_Pin_7

#define DC_RCU		RCC_AHB1Periph_GPIOA
#define DC_PORT		GPIOB
#define DC_PIN		GPIO_Pin_2

#define CS1_RCU		RCC_AHB1Periph_GPIOA
#define CS1_PORT	GPIOA
#define CS1_PIN		GPIO_Pin_3

#define MISO_RCU	RCC_AHB1Periph_GPIOA
#define MISO_PORT	GPIOB
#define MISO_PIN	GPIO_Pin_6

#define CS2_RCU		RCC_AHB1Periph_GPIOC
#define CS2_PORT	GPIOA
#define CS2_PIN		GPIO_Pin_5

#define OLED_SCL_Clr() GPIO_ResetBits(CLK_PORT, CLK_PIN)//SCL
#define OLED_SCL_Set() GPIO_SetBits(CLK_PORT, CLK_PIN)

#define OLED_SDA_Clr() GPIO_ResetBits(MOSI_PORT,MOSI_PIN)//SDA
#define OLED_SDA_Set() GPIO_SetBits(MOSI_PORT,MOSI_PIN)

#define OLED_DC_Clr()  GPIO_ResetBits(DC_PORT,DC_PIN)//DC
#define OLED_DC_Set()  GPIO_SetBits(DC_PORT,DC_PIN)

#define OLED_CS_Clr()  GPIO_ResetBits(CS1_PORT,CS1_PIN)//CS1
#define OLED_CS_Set()  GPIO_SetBits(CS1_PORT,CS1_PIN)

#define OLED_READ_FS0()    GPIO_ReadInputDataBit(MISO_PORT,MISO_PIN)//FS0

#define OLED_ROM_CS_Clr()  GPIO_ResetBits(CS2_PORT,CS2_PIN)//CS2
#define OLED_ROM_CS_Set()  GPIO_SetBits(CS2_PORT,CS2_PIN)

#define OLED_CMD  0	//写命令
#define OLED_DATA 1	//写数据

void OLED_ColorTurn(u8 i);
void OLED_DisplayTurn(u8 i);
void OLED_WR_Byte(u8 dat,u8 cmd);
void OLED_Clear(void);
void OLED_address(u8 x,u8 y);
void OLED_Display_128x64(u8 *dp);
void OLED_Display_16x16(u8 x,u8 y,u8 *dp);
void OLED_Display_8x16(u8 x,u8 y,u8 *dp);
void OLED_Display_5x7(u8 x,u8 y,u8 *dp);
void Send_Command_to_ROM(u8 dat);
u8 Get_data_from_ROM(void);
void OLED_get_data_from_ROM(u8 addrHigh,u8 addrMid,u8 addrLow,u8 *pbuff,u8 DataLen);
void OLED_Display_GB2312_string(u8 x,u8 y,u8 *text);
void OLED_Display_string_5x7(u8 x,u8 y,u8 *text);
void OLED_ShowNum(u8 x,u8 y,float num,u8 len);
void OLED_Init(void);
#endif

oled.c

#include "oled.h"
#include "stdlib.h"


//反显函数
void OLED_ColorTurn(u8 i)
{
    if(i==0)
    {
        OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
    }
    if(i==1)
    {
        OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
    }
}

//屏幕旋转180度
void OLED_DisplayTurn(u8 i)
{
    if(i==0)
    {
        OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
        OLED_WR_Byte(0xA1,OLED_CMD);
    }
    if(i==1)
    {
        OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
        OLED_WR_Byte(0xA0,OLED_CMD);
    }
}

//开启OLED显示 
void OLED_DisPlay_On(void)
{
    OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
    OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵
    OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕
}

//关闭OLED显示 
void OLED_DisPlay_Off(void)
{
    OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
    OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵
    OLED_WR_Byte(0xAE,OLED_CMD);//关闭屏幕
}


//向SSD1306写入一个字节。
//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{	
    u8 i;			  
    if(cmd)
        OLED_DC_Set();
    else 
        OLED_DC_Clr();		  
    OLED_CS_Clr();
    for(i=0;i<8;i++)
    {			  
        OLED_SCL_Clr();
        if(dat&0x80)
            OLED_SDA_Set();
        else 
            OLED_SDA_Clr();
        OLED_SCL_Set();
        dat<<=1;   
    }				 		  
    OLED_CS_Set();
    OLED_DC_Set();   	  
}

//清屏函数
void OLED_Clear(void)
{
    u8 i,n;
    for(i=0;i<8;i++)
    {
        OLED_WR_Byte(0xb0+i,OLED_CMD);//设置页地址
        OLED_WR_Byte(0x10,OLED_CMD);  //设置列地址的高4位
        OLED_WR_Byte(0x00,OLED_CMD);  //设置列地址的低4位
        for(n=0;n<128;n++)
        {
            OLED_WR_Byte(0x00,OLED_DATA);//清除所有数据
        }
    }
}

//设置起始地址
void OLED_address(u8 x,u8 y)
{
    OLED_WR_Byte(0xb0+y,OLED_CMD);              //设置页地址
    OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);  //设置列地址的高4位
    OLED_WR_Byte((x&0x0f),OLED_CMD);            //设置列地址的低4位
}

//显示128x64点阵图像
void OLED_Display_128x64(u8 *dp)
{
    u8 i,j;
    for(i=0;i<8;i++)
    {
        OLED_address(0,i);
        for(j=0;j<128;j++)
        {
            OLED_WR_Byte(*dp,OLED_DATA); //写数据到OLED,每写完一个8位的数据后列地址自动加1
            dp++;
        }
    }
}

//显示16x16点阵图像、汉字、生僻字或16x16点阵的其他图标
void OLED_Display_16x16(u8 x,u8 y,u8 *dp)
{
    u8 i,j;
    for(j=0;j<2;j++)

网站公告

今日签到

点亮在社区的每一天
去签到