如何使用spi在此oled显示器上显示任何内容?

时间:2019-12-21 18:38:26

标签: c arduino embedded spi

我正在尝试使用SPI在1.3英寸SH1106-OLED显示器上显示任何内容。作为主机,我使用Nxp FRDM-KL46Z。这是我正在使用的代码:

a)spi.c文件:

#include "spi.h"
#include "MKL46Z4.h"

void spiInit(void){

    SIM->SCGC4 |= SIM_SCGC4_SPI0_MASK;      // enable clock to spi0 module

    SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;     // enable clock to portA

    PORTA->PCR[6] |= PORT_PCR_MUX(1);       // pin6 in portA is gpio - used as Data/Command signal

    PORTA->PCR[7] |= PORT_PCR_MUX(1);       // pin7 in portA is gpio - used as Reset signal


    PORTA->PCR[16] |= PORT_PCR_MUX(2);      // pin16 in portA is SPI0 MOSI

    PORTA->PCR[15] |= PORT_PCR_MUX(2);      // pin15 in portA is SPI0 SCLK

    PORTA->PCR[14] |= PORT_PCR_MUX(2);      // pin14 in portA is SPI0 Slave Select (Chip Select)

    PTA->PDDR |= 1UL << 6;                  // direction - output

    PTA->PDDR |= 1UL << 7;                  // direction - output

    PTA->PCOR |= 1UL << 6;                  // Command - 0

    PTA->PCOR |= 1UL << 7;                  // Reset - 0

    SPI0->C1 |= SPI_C1_SPE_MASK;        // SPI System Enable

    SPI0->C1 |= SPI_C1_MSTR_MASK;       // Master mode selected

    SPI0->C1 &= ~SPI_C1_CPOL_MASK;      // Clock polarity - active high

    SPI0->C1 &= ~SPI_C1_CPHA_MASK;      // middle of the transmission

    SPI0->C2 &= ~SPI_C2_SPIMODE_MASK;   // 8 bit mode

    SPI0->C2 &= ~SPI_C2_SPC0_MASK;      // not bidirectional

    SPI0->C1 &= ~SPI_C1_LSBFE_MASK;     // transmission starts with msb

    SPI0->BR |= SPI_BR_SPPR(0b111);     // baud rates..

    SPI0->BR |= SPI_BR_SPR(0b1110);     // ...

    SPI0->C2 |= SPI_C2_MODFEN_MASK;     // slave
    SPI0->C1 |= SPI_C1_SSOE_MASK;       // select

}

b)和main.c文件:

#include "MKL46Z4.h"
#include "spi.h"

int main(void){

    spiInit();

    int i =0;

    for(i=0; i<2000000; i++){}; // delay

    PTA->PSOR |= 1UL << 7;  // Reset = 1

    for(i=0; i<2000000; i++){}; // delay

    /* Command register */

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xAE; //Set display Off

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xD5; //Set display clock divide ratio/oscillator frequency

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xA8;   //Set multiplex ratio

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xD3;   //Set display offset

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0x40;   //Set display start line

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0x8D;   //Set charge pump

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0x14;   //VCC generated by internal DC/DC circuit

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xA1;   //Set segment re-map

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xC0;   //Set COM output scan direction

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xDA;   //Set COM pins hardware configuration

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0x81;   //Set contrast control

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xD9;   //Set pre-changed period

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xDB;   //Set VCOMH Deselected level

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xA4;   //Set entire display on/off

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xA6;   //Set normal display

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0x20;   //Set memory address mode

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0x00;   //Horizontal

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0xAF;   //Set display on

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0x10;   //Set higher column start address for page addressing mode

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = 0x40;   //Set display start line

    for(i=0; i<2000000; i++){}; // delay

    PTA->PSOR |= 1UL << 6;      // Data = 1

    for(i=0; i<2000000; i++){}; // delay

    /* Sending data */

    int8_t data = 0b11111111;

    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;   
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;   
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;   
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;   
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;
    if((SPI0->S & SPI_S_SPTEF_MASK) == SPI_S_SPTEF_MASK) SPI0->DL = data;

    while(1){}
}

我以为我应该打开一些像素(此模式无关紧要我现在什么都不亮),但什么也没得到。有人知道我在做什么错吗?也许我的逻辑有些错误?有用的网址:https://os.mbed.com/platforms/FRDM-KL46Z/https://www.waveshare.com/wiki/OLED_Datasheets

0 个答案:

没有答案
相关问题