学习目标
- 掌握移植方法
- 掌握调试方式
学习内容
需求
官方测试示例
选择对应的平台
测试示例中,找到芯片对应平台,我们选择的是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自己环境
切换自己的环境,进行测试。
- 拷贝oled文件
- 拷贝main中的核心逻辑
- 修改不兼容的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++)