关于CW32的oled屏的显示实现(SPI)

本文通过运用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);
  
}

下面是实现OLED屏后的相关现象

oled屏幕的显示

如果有需要具体例程的小伙伴可以后台私信我。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值