TA的每日心情 | 怒 2023-7-25 22:49 |
---|
签到天数: 385 天 连续签到: 1 天 [LV.9]以坛为家II
|
1、OLED介绍
0.96’ OLED 显示模块, 分辨率为 128*64,采用SSD1306 驱动 IC,该芯片内部集成 DCDC 升压,仅需 3.3V 供电,即可正常工作。实际上就是由一个SSD1306控制器和一个128X64的有机发光二极管点阵组成。OLD模块具有和12864LCD相同的分辨率,但其在单位面积上具有更多的像素点。该模块的驱动芯片是SSD1306Z,它是一款专门用于驱动OLED点阵屏的COMS芯片,其包含128个段和64个公共端。为了能够通过外部控制器向其写入用于显示的数字信息,其对外提供了8个数据引脚和5个控制脚,并向用户提供了4种总线接口。文中所采用的OLED模块可实现SPI和IIC两种总线接口模式,默认为SPI模式。在SPI模式下,仅有数据引脚的低2位和控制引脚的CS#,D/C#和RES#与单片机进行接口。为了能让OLED具有丰富的显示效果和灵活简便的操作方式,SSD1306Z向用户提供了丰富的操作指令集,另外还向用户提供了128x64位的GDDRAM(Graphic Display Data RAM)。由于所采用的OLED不带字库,因此无论是显示图形还是显示汉字,均需通过取模软件进行编码,然后按SPI协议,将对应的编码按照所确定的地址模式写入对应的CDDRAM中。编码原理如图1所示。图1给出了16*8编码格式的字符‘A’,由于8行为一页,因此其占据2页的高度,而宽度则占据8列。图1中的每一个方格代表一位,若要显示则置1,反之置0。向GDDRAM当中送数据时,先通过指令确定操作所需的地址模式及存储器的地址,然后先写‘A’的第2页的编码,再写其第3页的编码,即可完成编码的写入操作。图1所对应的编码为0x00,0x00,0xe0,0x9c,0xf0,0x80,0x00,0x00,0x08,0x0f,0x08,0x00,0x00,0x0b,0xoe,0x08,编码时高位在下,低位在上。同理,可得对任意汉字的编码。
图1
2、模块的接口原理图
3、管脚说明:
GND:电源地
VCC:2.2V~5.5V
D0: CLK时钟 (高电平2.2V~5.5V)
D1: MOSI数据 (高电平2.2V~5.5V)
RST: 复位 (高电平2.2V~5.5V)
DC: 数据/命令 (高电平2.2V~5.5V)
在COLIBRI_GD32F207开发板上,我们使用SPI1来驱动,所以D0接PA5,D1接PA7,RST接PC3,DC接PC2,CS接地。
4、驱动代码:
oled.h
/** **************************************************************************************** * * @file oled.h * * @brief Header file of lcd_oled. * * Copyright (C) TChip 2012-2015 * * $Rev: 1.0 $ * **************************************************************************************** */ #ifndef __OLED_H__ #define __OLED_H__ /* * INCLUDE FILES **************************************************************************************** */ #include "stdint.h" /* * MARCO VARIABLE DECLARATION **************************************************************************************** */ #define OLED_DC_PIN GPIO_PIN_2#define OLED_CS_PIN GPIO_PIN_0#define OLED_RST_PIN GPIO_PIN_3#define OLED_SCLK_PIN GPIO_PIN_5#define OLED_SDIN_PIN GPIO_PIN_7#define OLED_DC GPIOC#define OLED_RST GPIOC#define OLED_CS GPIOA#define OLED_SCLK GPIOA#define OLED_SDIN GPIOA #define ZEROPAD 1 // Pad with zero#define SIGN 2 // Unsigned/signed long#define PLUS 4 // Show plus#define SPACE 8 // Space if plus#define LEFT 16 // Left justified#define SPECIAL 32 // 0x#define LARGE 64 // Use 'ABCDEF' instead of 'abcdef'#define OLED_CMD 0 //写命令#define OLED_DATA 1 //写数据#define OLED_MODE 0#define SIZE 16#define XLevelL 0x00#define XLevelH 0x10#define Max_Column 128#define Max_Row 64#define Brightness 0xFF #define X_WIDTH 128#define Y_WIDTH 64 //-----------------OLED端口定义---------------- //#define OLED_CS_Clr() gpio_write_pin(OLED_CS_PIN,GPIO_LOW)//CS//#define OLED_CS_Set() gpio_write_pin(OLED_CS_PIN,GPIO_HIGH)//#define OLED_DC_Clr() gpio_write_pin(OLED_RS_PIN,GPIO_LOW)//DC//#define OLED_DC_Set() gpio_write_pin(OLED_RS_PIN,GPIO_HIGH)//-----------------OLED端口定义---------------- #define OLED_CS_Clr() GPIO_ResetBits(OLED_CS,OLED_CS_PIN)//CS#define OLED_CS_Set() GPIO_SetBits(OLED_CS,OLED_CS_PIN)#define OLED_RST_Clr() GPIO_ResetBits(OLED_RST,OLED_RST_PIN)//RES#define OLED_RST_Set() GPIO_SetBits(OLED_RST,OLED_RST_PIN)#define OLED_DC_Clr() GPIO_ResetBits(OLED_DC,OLED_DC_PIN)//DC#define OLED_DC_Set() GPIO_SetBits(OLED_DC,OLED_DC_PIN) /* * EXTERN FUNCTION DECLARATION **************************************************************************************** */ void OLED_WR_Byte(uint8_t dat,uint8_t cmd); void OLED_Display_On(void);void OLED_Display_Off(void); void OLED_Init(void);void OLED_Clear(void);void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t);void OLED_Fill(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t dot);void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr);void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size);void OLED_ShowString(uint8_t x,uint8_t y, uint8_t *p); void OLED_Set_Pos(unsigned char x, unsigned char y);void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no);void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);#endif/// endoled.c
/** **************************************************************************************** * * @file lcd_12864.c * * @brief lcd_12864 driver. * * Copyright (C) TChip 2014 * * $Rev: 1.0 $ * **************************************************************************************** *//** **************************************************************************************** * @addtogroup SPI * @{ **************************************************************************************** *//* * INCLUDE FILES **************************************************************************************** */#include "gd32f20x_gpio.h" // Keil:evice:StdPeriph Drivers:GPIO#include "gd32f20x_spi.h" // Keil:evice:StdPeriph Drivers:SPI#include "delay.h"#include "oled.h"#include "oledfont.h"/* * MARCO VARIABLE DECLARATION **************************************************************************************** */#define TRANSFER_SIZE (1) /*! Transfer size */#define TRANSFER_BAUDRATE (1000000U) /*! Transfer baudrate - 500k */#define MASTER_TRANSFER_TIMEOUT (5000U) /*! Transfer timeout of master - 5s *//* * LOCAL VARIABLE DECLARATION **************************************************************************************** *///check spi statusvolatile uint8_t oled_rx_flag = 0;volatile uint8_t oled_tx_flag = 0;//uint8_t i;uint8_t buffer[32];//Init the OLED//static uint8_t Init_buffer[] =//{// 0xAE ,//--turn off oled panel// 0x00 ,//---set low column address// 0x10 ,//---set high column address// 0x40 ,//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)// 0x81 ,//--set contrast control register// 0xCF , // Set SEG Output Current Brightness// 0xA1 ,//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常// 0xC8 ,//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常// 0xA6 ,//--set normal display// 0xA8 ,//--set multiplex ratio(1 to 64)// 0x3f ,//--1/64 duty// 0xD3 ,//-set display offset Shift Mapping RAM Counter (0x00~0x3F)// 0x00 ,//-not offset// 0xd5 ,//--set display clock divide ratio/oscillator frequency// 0x80 ,//--set divide ratio, Set Clock as 100 Frames/Sec// 0xD9 ,//--set pre-charge period// 0xF1 ,//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock// 0xDA ,//--set com pins hardware configuration// 0x12 ,// 0xDB ,//--set vcomh// 0x40 ,//Set VCOM Deselect Level// 0x20 ,//-Set Page Addressing Mode (0x00/0x01/0x02)// 0x02 ,//// 0x8D ,//--set Charge Pump enable/disable// 0x14 ,//--set(0x10) disable// 0xA4 ,// Disable Entire Display On (0xa4/0xa5)// 0xA6 ,// Disable Inverse Display On (0xa6/a7)// 0xAF ,//--turn on oled panel//// 0xAF , /*display ON*///};/* * GLOBAL VARIABLE DECLARATION **************************************************************************************** */#if (GD32_OLED)/** **************************************************************************************** * @brief SPI RX CALLBACK FUNCTION. * @description * **************************************************************************************** */void oled_read_done(void){ oled_rx_flag = 0;}/** **************************************************************************************** * @brief SPI TX CALLBACK FUNCTION. * @description * **************************************************************************************** */void oled_write_done(void){ oled_tx_flag = 0;}/** **************************************************************************************** * @brief Configure the SPI GPIO and set RS 、 RST GPIO output,Init them. * @description * **************************************************************************************** */void oled_io_config(void){ GPIO_InitPara GPIO_InitStructure; /* Configure SPI_MASTER pins: SCK and MOSI */ GPIO_InitStructure.GPIO_Pin = GPIO_PIN_5| GPIO_PIN_7; GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ; GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //Init Gpio with a callback,it's necessary //set the LCD_RS_PIN and LCD_RST_PIN an output GPIO_InitStructure.GPIO_Pin = OLED_DC_PIN| OLED_RST_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ; GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_ResetBits(GPIOC,OLED_DC_PIN); GPIO_SetBits(GPIOC,OLED_RST_PIN);}void OLED_Set_Pos(unsigned char x, unsigned char y){ OLED_WR_Byte(0xb0+y,OLED_CMD); OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);}//开启OLED显示void OLED_Display_On(void){ OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令 OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON}//关闭OLED显示void OLED_Display_Off(void){ OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令 OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF}//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!void OLED_Clear(void){ uint8_t i,n; for(i=0; i<8; i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7) OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置&mdash;列低地址 OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置&mdash;列高地址 for(n=0; n<128; n++) OLED_WR_Byte(0,OLED_DATA); } //更新显示}void OLED_WR_Byte(uint8_t dat,uint8_t cmd){ if(cmd) OLED_DC_Set(); else OLED_DC_Clr(); OLED_CS_Clr(); //spi_write(QN_SPI1, buffer, 1, oled_write_done); SPI_I2S_SendData(SPI1,dat); oled_write_done(); DelayUs(100); OLED_CS_Set(); OLED_DC_Set();}//void OLED_WR_Byte(uint8_t dat,uint8_t cmd)//{// //uint8_t i;// uint8_t buffer[1];// buffer[0] = dat;// if(cmd)// OLED_DC_Set();// else// OLED_DC_Clr();// OLED_CS_Clr();// spi_write(QN_SPI1, buffer, 1, lcd_write_done);// delay(100);//// OLED_CS_Set();// OLED_DC_Set();//}void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr){ unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>Max_Column-1) { x=0; y=y+2; } if(SIZE ==16) { OLED_Set_Pos(x,y); for(i=0; i<8; i++) OLED_WR_Byte(F8X16[c*16+i],OLED_DATA); OLED_Set_Pos(x,y+1); for(i=0; i<8; i++) OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); } else { OLED_Set_Pos(x,y+1); for(i=0; i<6; i++) OLED_WR_Byte(F6x8[c],OLED_DATA); }}//m^n函数uint32_t oled_pow(uint8_t m,uint8_t n){ uint32_t 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,uint32_t num,uint8_t len,uint8_t size){ uint8_t t,temp; uint8_t enshow=0; for(t=0; t<len; t++) { temp=(num/oled_pow(10,len-t-1)); if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_ShowChar(x+(size/2)*t,y,' '); continue; } else enshow=1; } OLED_ShowChar(x+(size/2)*t,y,temp+'0'); }}//显示一个字符号串void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr){ unsigned char j=0; while (chr[j]!='\0') { OLED_ShowChar(x,y,chr[j]); x+=8; if(x>120) { x=0; y+=2; } j++; }}//显示汉字void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no){ uint8_t t,adder=0; OLED_Set_Pos(x,y); for(t=0; t<16; t++) { OLED_WR_Byte(Hzk[2*no][t],OLED_DATA); adder+=1; } OLED_Set_Pos(x,y+1); for(t=0; t<16; t++) { OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA); adder+=1; }}/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]){ unsigned int j=0; unsigned char x,y; if(y1%8==0) y=y1/8; else y=y1/8+1; for(y=y0; y<y1; y++) { OLED_Set_Pos(x0,y); for(x=x0; x<x1; x++) { OLED_WR_Byte(BMP[j++],OLED_DATA); } }}//初始化SSD1306void OLED_Init(void){ oled_io_config(); OLED_RST_Set(); DelayMs(10); OLED_RST_Clr(); DelayMs(10); OLED_RST_Set(); OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel OLED_WR_Byte(0x00,OLED_CMD);//---set low column address OLED_WR_Byte(0x10,OLED_CMD);//---set high column address OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F) OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) OLED_WR_Byte(0x00,OLED_CMD);//-not offset OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration OLED_WR_Byte(0x12,OLED_CMD); OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02) OLED_WR_Byte(0x02,OLED_CMD);// OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5) OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ OLED_Clear(); OLED_Set_Pos(0,0);}#endif///end主程序:main.c
#include <stdio.h>#include "gd32f20x.h" // Device header#include "cmsis_os.h" // ARM::CMSIS:RTOS:Keil RTX#include "delay.h"#include "oled.h"void RCC_config(void);void SPI_config(void);int main(){ osKernelInitialize(); RCC_config(); SPI_config(); osKernelStart(); while(1) { OLED_ShowString(32,0,(uint8_t*)"WELCOME"); OLED_ShowString(0,2,"Hello EEBoard!"); OLED_ShowString(0,4,"COLIBRI_GD32F207"); osDelay(1000); }}void RCC_config(void){ RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOA|RCC_APB2PERIPH_GPIOD|RCC_APB2PERIPH_GPIOC,ENABLE); RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_SPI1,ENABLE); RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_ADC1,ENABLE); RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_USART2,ENABLE); RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER6,ENABLE); RCC_ADCCLKConfig(RCC_ADCCLK_APB2_DIV6);}void SPI_config(void){ SPI_InitPara spi_stru; spi_stru.SPI_FirstBit = SPI_FIRSTBIT_MSB; spi_stru.SPI_FrameFormat = SPI_FRAMEFORMAT_8BIT; spi_stru.SPI_Mode = SPI_MODE_MASTER; spi_stru.SPI_PSC = SPI_PSC_64; spi_stru.SPI_SCKPH = SPI_SCKPH_1EDGE; spi_stru.SPI_SCKPL = SPI_SCKPL_LOW; spi_stru.SPI_SWNSSEN = SPI_SWNSS_SOFT; spi_stru.SPI_TransType = SPI_TRANSTYPE_BDMTX; spi_stru.SPI_CRCPOL = 7; SPI_Init(SPI1,&spi_stru); SPI_CRC_Enable(SPI1,DISABLE); SPI_Enable(SPI1,ENABLE);}复制代码
实验结果:
热门推荐:
轻轻松松入门GD32F207开发板 |
|