我正在尝试使用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