cancel
Showing results for 
Search instead for 
Did you mean: 

SPI With Nokia LCD

onofe
Associate II
Posted on February 11, 2014 at 07:42

Hi, I am trying to use stm32f3 spi to interface nokia lcd, 5110 but it does not work. I am not sure what is wrong with my code. Can anyone help me please? Thanks

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

https://www.dropbox.com/sh/uztgjhkhu3n0hgw/ZHE6kabwv1

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

code:

&sharpinclude ''Main.h''

&sharpinclude ''stm32f30x.h''

&sharpinclude ''stm32f30x_rcc.h''

&sharpinclude ''stm32f30x_gpio.h''

int main (void)

{

clock_source();

spi_initialise();

lcd_init();

while(1)

{

lcd_string (''de1!'');

}

}

void spi_initialise(void)

{

/*setting up all the general puarpose I/O's for the spi transaction*/

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//enable spi2 clock

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);//enable gpiob clock

GPIO_PinAFConfig(lcd_spi_port, GPIO_PinSource13, GPIO_AF_6);//spi2 is alternate function 2

GPIO_PinAFConfig(lcd_spi_port, GPIO_PinSource15, GPIO_AF_6);

//lcd_SPI_port,GPIO_PinSource10,GPIO_AF_5

/*configure spi gpio pin settings*/

gpio_struct.GPIO_Mode =  GPIO_Mode_AF;

gpio_struct.GPIO_OType = GPIO_OType_PP;

gpio_struct.GPIO_PuPd = GPIO_PuPd_NOPULL;

gpio_struct.GPIO_Speed = GPIO_Speed_50MHz;

/*configure mosi pin as alternate function*/

gpio_struct.GPIO_Pin = spi_mosi;

GPIO_Init(lcd_spi_port, &gpio_struct);

/*configure miso pin*/

gpio_struct.GPIO_Pin = spi_miso;

GPIO_Init(lcd_spi_port, &gpio_struct);

/*configure spi clock pin*/

gpio_struct.GPIO_Pin = spi_clock;

GPIO_Init(lcd_spi_port, &gpio_struct);

/*none spi pins*/

gpio_struct.GPIO_Pin = lcd_dc|lcd_reset_pin|lcd_cs|lcd_led;

gpio_struct.GPIO_Mode =  GPIO_Mode_OUT;

gpio_struct.GPIO_OType = GPIO_OType_PP;

gpio_struct.GPIO_PuPd = GPIO_PuPd_NOPULL;

gpio_struct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(lcd_spi_port, &gpio_struct);

/*Chip Select high */

  GPIO_SetBits(lcd_spi_port, lcd_cs);

/*configure lcd reset* /

gpio_struct.GPIO_Pin = lcd_reset_pin;

GPIO_Init(lcd_spi_port, &gpio_struct);

/ *configure lcd dc* /

gpio_struct.GPIO_Pin = lcd_dc;

GPIO_Init(lcd_spi_port, &gpio_struct);

/ *congigure lcd cs* /

gpio_struct.GPIO_Pin = lcd_cs;

GPIO_Init(lcd_spi_port, &gpio_struct);

/ *configure lcd led * /

gpio_struct.GPIO_Pin = lcd_led;

GPIO_Init(lcd_spi_port, &gpio_struct);*/

/*setting up all the various settings for the spi transfer*/

  SPI_I2S_DeInit(SPI2);//deinitalise or switch off the spi

spi_struct.SPI_Direction = SPI_Direction_1Line_Tx;

spi_struct.SPI_FirstBit = SPI_FirstBit_MSB;

spi_struct.SPI_DataSize = SPI_DataSize_8b;

spi_struct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;

spi_struct.SPI_NSS = SPI_NSS_Soft;

spi_struct.SPI_CPHA = SPI_CPHA_1Edge;

spi_struct.SPI_CPOL = SPI_CPOL_Low;

spi_struct.SPI_Mode =  SPI_Mode_Master;

spi_struct.SPI_CRCPolynomial = 7;

SPI_Init (SPI2, &spi_struct);

SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_QF);

SPI_Cmd (SPI2, ENABLE);//enable spi2

/*I use this part of the code to test the data transfer*/

while (SPI_I2S_GetFlagStatus (SPI2, SPI_I2S_FLAG_TXE) == RESET)

SPI_SendData8(SPI2, 0x80);

}

}

void lcd_character (char charr)

{

uint8_t j;

GPIO_SetBits (lcd_spi_port, lcd_reset_pin);//reset pin is active low

GPIO_SetBits (lcd_spi_port, lcd_dc);//data or command pin - 1 = data, 0 = command

GPIO_ResetBits (lcd_spi_port, lcd_cs);//cs = chip select - active low

for (j = 0; j < 5; j++)//font is 7 x 8

{

nokia_spi_send_data (Arimo7x8[charr - 0x20][j]);

}

}

void lcd_cmd (char cmd)

{

GPIO_SetBits (lcd_spi_port, lcd_reset_pin);//reset pin is active low

GPIO_ResetBits (lcd_spi_port, lcd_dc);//data or command pin - 1 = data, 0 = command

GPIO_ResetBits (lcd_spi_port, lcd_cs);//cs = chip select - active low

nokia_spi_send_data (cmd);//send data to lcd

}

void lcd_string (const char *string)

{

while (*string)

lcd_character (*string++);//send a char from string and increment the string address

}

void lcd_init()

{

uint8_t j;

uint8_t init_byte [] = { 0x21, 0xb1, 0x04, 0x14, 0x20, 0x0C };

GPIO_ResetBits(lcd_spi_port, lcd_cs);

lcd_reset();

delay_ms(100);

lcd_reset();

delay_ms(100);

GPIO_SetBits (lcd_spi_port, lcd_reset_pin);

delay_ms(1000);

for (j = 0; j < 6; j++)

{

lcd_cmd (init_byte[j]);

delay_ms(100);

//__ASM {0};

}

display_normal();

}

static uint8_t nokia_spi_send_data (char byte)

{

while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);//wait till there is no more data to send

SPI_SendData8(SPI2, byte);

while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);//wait till there is no more data to send

return 0;

}

#lcd #nokia-lcd #stm32f3 #spi
5 REPLIES 5
chen
Associate II
Posted on February 11, 2014 at 10:42

Hi

'' I am trying to use stm32f3 spi to interface nokia lcd, 5110 but it does not work.''

We need to see your circuit to understand what is going on.

''I am not sure what is wrong with my code. Can anyone help me please? ''

It looks like the code immediately tries to communicate with the LCD interface. I am guessing that both are power up together, you are expecting the LCD controller to be ready. In my experience, the STM32 powers up and is up and running way ahead of any peripheral attached to it.

Simple solution - put in a delay (around 10ms) before trying to communicate with LCD.

Proper solution - put the LCD under control of the STM32, ie use STM32 IO pin to control reset of LCD controller. Control the LCD reset in software. It will still need a short delay after releasing reset.

onofe
Associate II
Posted on March 28, 2014 at 01:50

The problem is not even the lcd. My problem is when I am debugging, I don't see the data on the DR (Data Register). So, I cannot explain why the spi module seems no to work at all with my code. I tried debugging the demo program and i can see clearly that the data (byte) is written to ''DR''.

Posted on March 28, 2014 at 03:20

The debugger is NOT going to show you data written to the SPI->DR, it has no visibility of this. The value read from SPI->DR comes from the receive path.

The tools to use here would be a scope or logic analyzer, to confirm the signalling and timing, and how that matches the specifications for the display.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Andrew Neil
Evangelist III
Posted on March 28, 2014 at 08:07

''the specifications for the display''

There could be a problem right there!

The trouble with using surplus parts like this is often that no  specification is available - so you really have no idea what is the correct way to drive it...

syanke
Associate
Posted on March 29, 2014 at 01:17

I spent days trying to get SPI to work on my Nucleo L152RE.  It finally came down to changing spi_struct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; to use SPI_BaudRatePrescaler_8 (or 16, 32, 64).  Until then I got nowhere.