本文通过运用CW32F030芯片的SPI来实现0.96寸的oled屏幕显示。接下来我们一共分为这几个步骤进行配置。
首先我们需要配置相关的IO口以及SPI的初始化:
void OLED_Init_GPIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2, ENABLE); //使能A端口时钟
GPIO_InitStructure.Pins = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5; //GPIOA3,4,5
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;//高速度输出
GPIO_Init(CW_GPIOA, &GPIO_InitStructure); //初始化GPIOA3,4,5
GPIO_WritePin(CW_GPIOA,GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5,GPIO_Pin_SET);
} //要注意这个时钟使能是GPIOA的,选择pin口,记得调试
#define PAGE_SIZE 8
#define XLevelL 0x00
#define XLevelH 0x10
#define YLevel 0xB0
#define Brightness 0xFF
#define WIDTH 128
#define HEIGHT 64
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
#define OLED_CS GPIO_PIN_3 //片选信号 PA03 我们的cw32需要改成自己的cs,dc和rst
#define OLED_DC GPIO_PIN_4 //数据/命令控制信号 PA04
#define OLED_RST GPIO_PIN_5 //复位信号 PA05
//-----------------OLED端口操作定义----------------
#define OLED_CS_Clr() GPIO_WritePin(CW_GPIOA,OLED_CS,GPIO_Pin_RESET)
#define OLED_CS_Set() GPIO_WritePin(CW_GPIOA,OLED_CS,GPIO_Pin_SET)
#define OLED_DC_Clr() GPIO_WritePin(CW_GPIOA,OLED_DC,GPIO_Pin_RESET)
#define OLED_DC_Set() GPIO_WritePin(CW_GPIOA,OLED_DC,GPIO_Pin_SET)
#define OLED_RST_Clr() GPIO_WritePin(CW_GPIOA,OLED_RST,GPIO_Pin_RESET)
#define OLED_RST_Set() GPIO_WritePin(CW_GPIOA,OLED_RST,GPIO_Pin_SET)
这里我们将GPIOA的PIN3模拟设置成cs片选引脚,PA04设置为DC,PA05设置成RST引脚,并且配置其操作宏定义。配置完IO口以后,我们需要配置SPI的相关初始化。
#include "cw32f030_spi.h"
#include "cw32f030_gpio.h"
#include "cw32f030_rcc.h"
#define SPI_MASTER //主机模式
//#define SPI_SLAVE //从机模式
//SPI
#define SPIx CW_SPI2
#define SPIx_CLK RCC_APB1_PERIPH_SPI2
#define SPIx_APBClkENx RCC_APBPeriphClk_Enable1
//SPI GPIO
#define SPIx_SCK_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define SPIx_SCK_GPIO_PORT CW_GPIOA
#define SPIx_SCK_GPIO_PIN GPIO_PIN_2
#define SPIx_SCK_AF() PA02_AFx_SPI2SCK()
#define SPIx_MISO_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define SPIx_MISO_GPIO_PORT CW_GPIOA
#define SPIx_MISO_GPIO_PIN GPIO_PIN_0
#define SPIx_MISO_AF() PA00_AFx_SPI2MISO()
#define SPIx_MOSI_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define SPIx_MOSI_GPIO_PORT CW_GPIOA
#define SPIx_MOSI_GPIO_PIN GPIO_PIN_1
#define SPIx_MOSI_AF() PA01_AFx_SPI2MOSI()
#define SPIx_CS_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define SPIx_CS_GPIO_PORT CW_GPIOA
#define SPIx_CS_GPIO_PIN GPIO_PIN_3
#define SPIx_CS_AF() PA03_AFx_SPI2CS()
//CS LOW or HIGH
#define SPIx_CS_LOW() PA03_SETLOW()
#define SPIx_CS_HIGH() PA03_SETHIGH()
void SPI2_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//配置SPI2管脚
RCC_AHBPeriphClk_Enable( SPIx_MISO_GPIO_CLK|SPIx_SCK_GPIO_CLK | SPIx_MOSI_GPIO_CLK |
SPIx_CS_GPIO_CLK, ENABLE);
SPIx_APBClkENx(SPIx_CLK,ENABLE);
SPIx_SCK_AF();
SPIx_MOSI_AF();
SPIx_MISO_AF();
// SPIx_CS_AF();
GPIO_InitStructure.Pins = GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.Pins = GPIO_PIN_0;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
(CW_GPIOA->BSRR = bv3);
//SPI2配置选项
RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2,ENABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Speed = SPI_Speed_Low;
SPI_Init(CW_SPI2, &SPI_InitStructure);
//使能SPI2
SPI_Cmd(CW_SPI2, ENABLE);
}
可以看到我们在这里用SPI2作为我们的传输通道,并且根据OLED屏的性质将其时钟极性和时钟边沿,配置完IO口以及SPI的初始性质之后,我们接下来就是配置OLED的传输函数以及相关配置
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
OLED_DC_Set();
}
else
{
OLED_DC_Clr();
}
OLED_CS_Clr();
//这边的是spi.c的文件
SPI_SendData(CW_SPI2,dat);
while(SPI_GetFlagStatus(CW_SPI2,SPI_FLAG_RXNE) == RESET);
SPI_ReceiveData(CW_SPI2);//这三行代码是配置数据的传输
} //看DC也就是我们的spi数据命令选择脚是根据调用时候输入的cmd来控制,cmd是0的时候是控制,1的时候是数据
通过这个初始的传输函数,我们能将数据从主机传输到从机。通过以上配置我们就能自己配置相关的我们想要在OLED屏幕上显示的内容。下面是主函数的配置
#include "main.h"
#include "system_cw32f030.h"
#include "interrupts_cw32f030.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
#include "core_cm0plus.h"
void RCC_Configuration(void);
void NVIC_Configuration(void);
int main(void)
{
RCC_Configuration();
OLED_Init(); //初始化OLED
OLED_Clear(0); //使oled屏清空
while(1)
{
TEST_MainPage(); //主界面显示测试
OLED_Clear(0);
Test_Color(); //刷屏测试
OLED_Clear(0);
Test_Rectangular(); //矩形绘制测试
OLED_Clear(0);
Test_Circle(); //圆形绘制测试
OLED_Clear(0);
Test_Triangle(); //三角形绘制测试
OLED_Clear(0);
TEST_English(); //英文显示测试
OLED_Clear(0);
TEST_Number_Character(); //数字和符号显示测试
OLED_Clear(0);
}
}
void RCC_Configuration(void)
{
//SYSCLK = HSI = 24MHz = HCLK = PCLK
RCC_HSI_Enable(RCC_HSIOSC_DIV2);
//外设时钟使能
RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA, ENABLE);
RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2, ENABLE);
}
|