TA的每日心情 | 怒 2023-7-25 22:49 |
---|
签到天数: 385 天 连续签到: 1 天 [LV.9]以坛为家II
|
本帖最后由 党国特派员 于 2016-2-5 01:09 编辑
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
- /// end
复制代码 oled.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::Device:StdPeriph Drivers:GPIO
- #include "gd32f20x_spi.h" // Keil::Device: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 status
- volatile 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); //设置显示位置—列低地址
- OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
- 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][i],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))%10;
- 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);
- }
- }
- }
- //初始化SSD1306
- void 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);
- }
复制代码 实验结果:
|
|