查看: 1357|回复: 0

GD32F207驱动0.96寸OLED

[复制链接]
  • TA的每日心情

    2023-7-25 22:49
  • 签到天数: 385 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2016-2-17 09:48:59 | 显示全部楼层 |阅读模式
    分享到:
    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);      //设置显示位置—列低地址        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],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开发板
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-26 00:20 , Processed in 0.126389 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.