Display OLED na MPLAB Xpress Board

Este post faz parte da série Aplicações com a MPLAB Xpress Board

No artigo anterior aprendemos os primeiros passos com o MPLAB® Xpress Cloud-Based IDE e fizemos um Hello World com a placa MPLAB Xpress Evaluation Board. Continuaremos explorando os recursos dessa plataforma com o uso de algumas placas Click boards. Neste artigo vamos desenvolver uma aplicação para a OLED W click.

Click Boards

As Click Boards são placas criadas pela Mikroe com a finalidade de facilitar o uso de recursos externos através de um padrão de conexão chamado de mikroBUS. Com esse padrão é possível criar diversas placas de aplicações que possam ser usadas por diversas plataformas com configurações mínimas. O padrão mikroBUS é definido da seguinte forma:

Padrão mikroBUS
Figura 1 – Padrão mikroBUS

A partir desse padrão foram criadas diversas Click boards:

Algumas Click Boards
Figura 2 – Algumas Click Boards

A MPLAB Xpress Evaluation Board possui um conector padrão mikroBUS, o que permite explorar os recursos dessas fantásticas plaquinhas.

Conector com padrão mikroBus na MPLAB Xpress Board
Figura 3 – Conector com padrão mikroBus na MPLAB Xpress Board

Durante nossos estudos com essa ferramenta iremos explorar algumas Click Boards.

OLED W Click

A OLED W Click possui um display OLED de matriz passiva 96 x 39 px monocromático branco, sendo uma tela brilhante com um excelente ângulo de visão e de baixo consumo de energia. Já possui integrado o controlador SSD1306 responsável pela controle do display e interface com microcontrolador. Esse controlador possui diversas funcionalidades para controle de contraste, exposição de imagem normal ou inversa, funções de rolagem vertical e horizontal, entre outras.

Seguindo o padrão mikroBUS, a OLED W Click pode se comunicar com o microcontrolador através SPI ou I2C.

O circuito da OLED W Click é apresentado a seguir:

Esquemático da OLED W Click
Figura 4 – Esquemático da OLED W Click

O display OLED utilizado é o MI9639BO-W. Além disso, a placa possui o regulador linear AP7331-ADJ. É possível selecionar o tipo de comunicação entre SPI e I2C através dos jumpers J1, J2 e J3. Por padrão a placa vem com SPI, e nesse exemplo utilizaremos essa comunicação. A figura a seguir exibe os jumpers na placa:

Seleção da comunicação
Figura 5 – Seleção da comunicação

Exemplo de aplicação

Nesse exemplo vamos desenvolver uma aplicação para a escrita no display usando o MPLAB® Xpress Cloud-Based IDE, o MCC e o compilador XC8. Será lido o valor no potenciômetro disponível na Xpress Board e exibido o valor da conversão AD no display.

Antes de desenvolver os arquivos de interface com o display, vamos mapear os pinos da Xpress board que serão utilizados nessa aplicação. Começando pelo pino que será usado para leitura de tensão presente no potenciômetro, verificamos no esquemático da placa que é o pino RA4, conforme exibido na figura a seguir:

Ligação do potênciometro na Xpress Board
Figura 6 – Ligação do potênciometro na Xpress Board

Já pra interface com o display, iremos utilizar os seguintes pinos:

Tabela 1 – Pinos usados para interface com o display

OLED W Click

Microcontrolador

RST

RB1

CS

RB2

PWM

RC7

SCK

RB3/SCK1

MISO

RB4/SDI1

Com o mapa de pinos que serão utilizados na aplicação em mãos, vamos agora passar para o desenvolvimento do código fonte.

Acesse o MPLAB Xpress IDE e crie um novo projeto. Após criado o projeto, deve-se abrir o MCC e fazer a configuração do sistema.

Caso você ainda possui dúvidas para criar um novo projeto ou nas configurações para a Xpress Board usando o MCC, é recomendável a leitura do artigo Primeiros passos com a MPLAB Xpress Evaluation Board.

Agora vamos configurar o comunicação SPI. Para isso selecione o módulo MSSP:

Selecionando o módulo MSSP1 para configurar a SPI1
Figura 7 – Selecionando o módulo MSSP1 para configurar a SPI1

Com o módulo selecionado, vamos ajustar as configurações da seguinte forma:

Configuração da SPI
Figura 8 – Configuração da SPI

Próximo passo é fazer a configuração do conversor AD. Para isso seleciono o módulo ADC:

Selecionando o módulo ADC
Figura 9 – Selecionando o módulo ADC

Para essa aplicação, vamos configurar o ADC da seguinte forma:

Configuração do ADC
Figura 10 – Configuração do ADC

Por último, vamos configurar os pinos da seguinte forma:

Configuração dos pinos
Figura 11 – Configuração dos pinos

Pronto, agora é só dar o comando para o MCC gerar o código de configuração e drivers para os periféricos.

Para comunicação com o display, foi desenvolvida uma biblioteca simples para interface e escrita no display. O código a seguir apresenta as funções criadas para manipulação do display OLED usando o SSD1306:

/*
 * File:   SSD1306.c
 * Author: fabio.souza@embarcados.com.br
 *
 * Created on 8/10/2016 1:14:10 AM UTC
 * "Created in MPLAB Xpress"
 */

#include "SSD1306.h"

// SSD1306 microcontroller pins
#define SSD1306_CS         CS_LAT
#define SSD1306_PWM        PWM_LAT
#define SSD1306_RST        RST_LAT


const uint8_t font[] = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x07,0x00,0x07,0x00, //	'sp,!,"
    0x14,0x7F,0x14,0x7F,0x14,                                                   // #
    0x24,0x2A,0x7F,0x2A,0x12,0x23,0x13,0x08,0x64,0x62,0x36,0x49,0x56,0x20,0x50, //	'$,%,&
    0x00,0x08,0x07,0x03,0x00,0x00,0x1C,0x22,0x41,0x00,0x00,0x41,0x22,0x1C,0x00, //	'',(,)
    0x2A,0x1C,0x7F,0x1C,0x2A,0x08,0x08,0x3E,0x08,0x08,0x00,0x00,0x70,0x30,0x00, //	'*,+,,
    0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x60,0x60,0x00,0x20,0x10,0x08,0x04,0x02, //	'-,.,/
    0x3E,0x51,0x49,0x45,0x3E,0x00,0x42,0x7F,0x40,0x00,0x72,0x49,0x49,0x49,0x46, //	'0,1,2
    0x21,0x41,0x49,0x4D,0x33,0x18,0x14,0x12,0x7F,0x10,0x27,0x45,0x45,0x45,0x39, //	'3,4,5
    0x3C,0x4A,0x49,0x49,0x31,0x41,0x21,0x11,0x09,0x07,0x36,0x49,0x49,0x49,0x36, //	'6,7,8
    0x46,0x49,0x49,0x29,0x1E,0x00,0x00,0x14,0x00,0x00,0x00,0x40,0x34,0x00,0x00, //	'9,:,;
    0x00,0x08,0x14,0x22,0x41,0x14,0x14,0x14,0x14,0x14,0x00,0x41,0x22,0x14,0x08, //	'<,=,>
    0x02,0x01,0x59,0x09,0x06,0x3E,0x41,0x5D,0x59,0x4E,                          //  '?,@
    0x7C,0x12,0x11,0x12,0x7C,                                                   //	'A
    0x7F,0x49,0x49,0x49,0x36,0x3E,0x41,0x41,0x41,0x22,0x7F,0x41,0x41,0x41,0x3E, //	'B,C,D
    0x7F,0x49,0x49,0x49,0x41,0x7F,0x09,0x09,0x09,0x01,0x3E,0x41,0x41,0x51,0x73, //	'E,F,G
    0x7F,0x08,0x08,0x08,0x7F,0x00,0x41,0x7F,0x41,0x00,0x20,0x40,0x41,0x3F,0x01, //	'H,I,J
    0x7F,0x08,0x14,0x22,0x41,0x7F,0x40,0x40,0x40,0x40,0x7F,0x02,0x1C,0x02,0x7F, //	'K,L,M
    0x7F,0x04,0x08,0x10,0x7F,0x3E,0x41,0x41,0x41,0x3E,0x7F,0x09,0x09,0x09,0x06, //	'N,O,P
    0x3E,0x41,0x51,0x21,0x5E,0x7F,0x09,0x19,0x29,0x46,0x26,0x49,0x49,0x49,0x32, //	'Q,R,S
    0x03,0x01,0x7F,0x01,0x03,0x3F,0x40,0x40,0x40,0x3F,0x1F,0x20,0x40,0x20,0x1F, //	'T,U,V
    0x3F,0x40,0x38,0x40,0x3F,0x63,0x14,0x08,0x14,0x63,0x03,0x04,0x78,0x04,0x03, //	'W,X,Y
    0x61,0x59,0x49,0x4D,0x43,                                                   //  'Z
    0x00,0x7F,0x41,0x41,0x41,0x02,0x04,0x08,0x10,0x20,                          //	'[,\ 
    0x00,0x41,0x41,0x41,0x7F,0x04,0x02,0x01,0x02,0x04,0x40,0x40,0x40,0x40,0x40, //	'],^,_
    0x00,0x03,0x07,0x08,0x00,0x20,0x54,0x54,0x38,0x40,0x7F,0x28,0x44,0x44,0x38, //	'`,a,b
    0x38,0x44,0x44,0x44,0x28,0x38,0x44,0x44,0x28,0x7F,0x38,0x54,0x54,0x54,0x18, //	'c,d,e
    0x00,0x08,0x7E,0x09,0x02,0x0C,0x52,0x52,0x4A,0x3C,0x7F,0x08,0x04,0x04,0x78, //	'f,g,h
    0x00,0x44,0x7D,0x40,0x00,0x20,0x40,0x40,0x3D,0x00,0x7F,0x10,0x28,0x44,0x00, //	'i,j,k
    0x00,0x41,0x7F,0x40,0x00,0x7C,0x04,0x78,0x04,0x78,0x7C,0x08,0x04,0x04,0x78, //	'l,m,n
    0x38,0x44,0x44,0x44,0x38,0x7C,0x18,0x24,0x24,0x18,0x18,0x24,0x24,0x18,0x7C, //	'o,p,q
    0x7C,0x08,0x04,0x04,0x08,0x48,0x54,0x54,0x54,0x24,0x04,0x04,0x3F,0x44,0x24, //	'r,s,t
    0x3C,0x40,0x40,0x20,0x7C,0x1C,0x20,0x40,0x20,0x1C,0x3C,0x40,0x30,0x40,0x3C, //	'u,v,w
    0x44,0x28,0x10,0x28,0x44,0x4C,0x50,0x50,0x50,0x3C,0x44,0x64,0x54,0x4C,0x44, //	'x,y,z
    0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x41,0x36,0x08,0x00, //	'{,|,}
    0x02,0x01,0x02,0x04,0x02                                                    //  '~
    };

uint8_t _row, _column; //curso position memory


void SSD1306_Cmd( unsigned char cmd){
  SSD1306_CS = 0;
  SSD1306_PWM = 0;
  SPI_Write( cmd);
  SSD1306_CS = 1;
}

void SSD1306_Data( unsigned char data){
  SSD1306_CS = 0;
  SSD1306_PWM = 1;
  SPI_Write( data);
  SSD1306_CS = 1;
}

void SetRowDisplay( uint8_t y)
{
    _column = y;
    y = 0xB0 | y;
    SSD1306_Cmd( y);
}

void SetColumnDisplay( uint8_t x)
{
    _row = x;
    x*=5;
    x += 32;
    SSD1306_Cmd(( SSD1306_SETHIGHCOLUMN | (x >> 4))); // SET_HIGH_COLUMN
    SSD1306_Cmd(( 0x0f & x));                       // SET LOW_COLUMN    
}

void SetContrastDisplay( unsigned char value)
{
    SSD1306_Cmd( SSD1306_SETCONTRAST);  
    SSD1306_Cmd( value);                  // contrast from 1 to 256
}

void InitDisplay(void)
{
    SSD1306_RST = 0;
    __delay_ms(1000);
    SSD1306_RST = 1;
    __delay_ms(1000);
    SSD1306_Cmd(SSD1306_DISPLAYOFF);             //0xAE  Set OLED Display Off
    SSD1306_Cmd(SSD1306_SETDISPLAYCLOCKDIV);     //0xD5  Set Display Clock Divide Ratio/Oscillator Frequency
    SSD1306_Cmd(0x80);
    SSD1306_Cmd(SSD1306_SETMULTIPLEX);           //0xA8  Set Multiplex Ratio
    SSD1306_Cmd(39);
    
    SSD1306_Cmd(SSD1306_SETSEGMENTREMAP);        //0xA1  Set Segment Remap Inv
    SSD1306_Cmd(SSD1306_COMSCANDEC);             //0xC8  Set COM Output Scan Inv
    SSD1306_Cmd(SSD1306_SETSTARTLINE);           //0x40  Set Display Start Line
    
    SSD1306_Cmd(SSD1306_SETDISPLAYOFFSET);       //0xD3  Set Display Offset
    SSD1306_Cmd(0x00);
    SSD1306_Cmd(SSD1306_CHARGEPUMP);             //0x8D  Set Charge Pump
    SSD1306_Cmd(0x14);                           //0x14  Enable Charge Pump
    SSD1306_Cmd(SSD1306_SETCOMPINS);             //0xDA  Set COM Pins Hardware Configuration
    SSD1306_Cmd(0x12);
    SSD1306_Cmd(SSD1306_SETCONTRAST);            //0x81   Set Contrast Control
    SSD1306_Cmd(0xAF);
    SSD1306_Cmd(SSD1306_SETPRECHARGE);           //0xD9   Set Pre-Charge Period
    SSD1306_Cmd(0x25);
    SSD1306_Cmd(SSD1306_SETVCOMDETECT);          //0xDB   Set VCOMH Deselect Level
    SSD1306_Cmd(0x20);
    SSD1306_Cmd(SSD1306_DISPLAYALLON_RESUME);    //0xA4   Set Entire Display On/Off
    SSD1306_Cmd(SSD1306_NORMALDISPLAY);          //0xA6   Set Normal/Inverse Display
    SSD1306_Cmd(SSD1306_DISPLAYON);              //0xAF   Set OLED Display On
} 


void ClearDisplay(void)
{
    uint8_t i,j;
    
    for( i=0; i<5; i++)         //rows
    {
        SetRowDisplay(i);
        SetColumnDisplay(0);
        
        for( j=0; j<96; j++)    //column
            SSD1306_Data( 0);
    }
    
    _row = 0; _column = 0;
    
    SetRowDisplay(0);
    SetColumnDisplay(0);
}



void PutcharDisplay(char c)
{
    unsigned char i;
    
    const unsigned char *p = &font[(c-' ')*5];    
    
    for( i=0; i<5; i++)
        SSD1306_Data( *p++ << 1);

    
    SSD1306_Data(0);
    
    _row++;                           //colum ++
    
    if (_row >= 16) {                 // column >= 16
        _row = 0;                     //return to 0
        SetColumnDisplay(0);        //set column 0
        _column++;                       //increments Row
        if (_column >= 5) {              // line >= 5 
            _column = 0;                 //return to 0
        }
        SetRowDisplay(_column);          //se new row
    }
}

Para a leitura do potenciômetro e exibição do valor de conversão AD no display foi desenvolvido o seguinte código:

/* 
 * File:   main.c
 * Author: fabio.souza@embarcados.com.br
 *
 * Created on 8/10/2016 1:13:50 AM UTC
 * "Created in MPLAB Xpress"
 */

#include "mcc_generated_files/mcc.h"
#include "SSD1306.h"

extern const uint8_t font[];

void mainScreen(void);
void updateDisplay(unsigned int value);

/*
                         Main application
 */
void main(void)
{
    //variables
    bool inv = true;
    unsigned int ADCValue;
    
    // initialize the device
    SYSTEM_Initialize();
    InitDisplay();
    ClearDisplay();      
    mainScreen();
    
    
    
    while (1) {
    
    ADCValue = ADCC_GetSingleConversion(POT);
    
    updateDisplay(ADCValue);
            
    printf("\r\n Valor ADC = %i ", ADCValue);
    
    if(ADCValue>800){
        SSD1306_Cmd(SSD1306_INVERTDISPLAY);
    }
    else{
        SSD1306_Cmd(SSD1306_NORMALDISPLAY);
    }
  
    __delay_ms(1000);
    }
}

void mainScreen(void){
    
    SetRowDisplay(1);
    SetColumnDisplay(3);
    
    PutcharDisplay('E');
    PutcharDisplay('M');
    PutcharDisplay('B');
    PutcharDisplay('A');
    PutcharDisplay('R');
    PutcharDisplay('C');
    PutcharDisplay('A');
    PutcharDisplay('D');
    PutcharDisplay('O');
    PutcharDisplay('S');
    
    SetRowDisplay(3);
    SetColumnDisplay(7);
    
    PutcharDisplay('0');
    PutcharDisplay('0');
    PutcharDisplay('0');
    PutcharDisplay('0');
}

void updateDisplay(unsigned int value){
    
    SetRowDisplay(3);
    SetColumnDisplay(7);
    
    PutcharDisplay((value/1000) + 0x30);
    PutcharDisplay((value%1000)/100 + 0x30);
    PutcharDisplay((value%100)/10 + 0x30);
    PutcharDisplay((value%10) + 0x30);
    
}


/**
 End of File
*/

Resultado

Figura 12 - Valor da conversão AD exibido no display
Figura 12 – Valor da conversão AD exibido no display

Você pode acessar o código desse exemplo diretamente no MPLAB Xpress Cloud IDE. Assim você poderá navegar pelo código, alterar, compilar e carregar diretamente na sua MPLAB Xpress Board.

Acesse o manual da OLED W Click, aqui. Baixe diversos exemplos para essa Click Board na Libstock.

Ficou alguma dúvida? Deixe seu comentário.

Aplicações com a MPLAB Xpress Board

Primeiros passos com a MPLAB Xpress Evaluation Board Usando a Accel 3 Click com a MPLAB Xpress Board
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
2 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
eron
eron
06/09/2016 20:36

Belo post Fabio, parabens! Voce sabe quando estas plaquinhas vão chegar no Brasil? Encontrei apenas os sites estrangeiros com as plaquinhas por US$10!

Abraço

Fabio_Souza_Embarcados
Fabio_Souza_Embarcados
Reply to  eron
06/09/2016 23:07

Olá Eron, infelizmente no Brasil não é fácil achar essas placas. Talvez seja mais fácil comprar de fora. Esse site possui algumas placas da mikroe: https://www.microgenios.com/?1.36,modulos-acessorios.html

Home » Software » Display OLED na MPLAB Xpress Board

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: