Nokia lcd 5110 SPI communication with STM32 doesn't work - Page 1
Forum section: electronics / beginners

author: mohannad
author_rank: Contributor
timestamp: September 28, 2017, 10:13:07 pm
content: I'm trying to start a simple communication with nokia 5110 LCD using SPI protocol. I'm using SPI2 peripheral on stm32f103c8t6 board but it doesn't work as intended.The code should intialize SPI preipheral and send two commands to the LCD : first command to use the basic instruction mode and the second to set all segments on.Here's my code :Code:#include "stm32f10x.h" // Device header#define NRES GPIOA->ODR |= ((((uint16_t) 0x1) << 8))#define RES GPIOA->ODR &= (~(((uint16_t) 0x1) << 8))#define SET_DK GPIOA->ODR |= ((((uint16_t) 0x1) << 9))#define RESET_DK GPIOA->ODR &= (~(((uint16_t) 0x1) << 9))void CLK_init (void);void RCC_init (void);void GPIO_init(void);void SPI_init (void);void LCD_init (void);void delay(void);int main(void){char volatile a ;uint32_t tmp = GPIOB->CRH;CLK_init ();RCC_init ();GPIO_init();SPI_init ();LCD_init ();RESET_DK;SPI2->DR = (0x20); //LCD COMMAND : BASIC SET , HORIZ ADDRESSINGa = SPI2->SR & (((uint16_t)0x1)<<1); //TXE BITwhile(a != 0x2) //WAIT UNTIL TX BUFFER IS EMPTY{}SPI2->DR = (0x9); //E=1 , D= 0 - ALL SEGMENTS ONwhile(1){SPI2->DR = (0x9); //E=1 , D= 0 - ALL SEGMENTS ONwhile(a != 0x2) //WAIT UNTIL TX BUFFER IS EMPTY{}}}void CLK_init(void){// 01: HSE oscillator used as system clockRCC -> CFGR |= (uint32_t)0x1;RCC -> CFGR &= ~((uint32_t)0x1) << 1;RCC -> CFGR &= ~(((uint32_t)0x7) << 11);RCC -> CFGR |= ((uint32_t)0x1) << 13;}void RCC_init(void){RCC->APB2ENR |= ((uint32_t)0x1)<<0; //Enable AFIO pinRCC->APB2ENR |= ((uint32_t)0x3)<<2; //Enable ports A,BRCC->APB1ENR |= ((uint32_t)0x1)<<14; //ENABLE SPI2}void GPIO_init(void){GPIOB->CRH &= ~(((uint32_t) 0xf) << 16) ; //PB12 OUTPUT - AFIO - PUSH PULLGPIOB->CRH |= ((uint32_t) 0xb) << 16 ; //PB12 OUTPUT - AFIO - PUSH PULL //////NSS//////GPIOB->CRH &= ~(((uint32_t) 0xf) << 20) ; //PB13 OUTPUT - AFIO - PUSH PULLGPIOB->CRH |= ((uint32_t) 0xb) << 20 ; //PB13 OUTPUT - AFIO - PUSH PULL //////SCK//////GPIOB->CRH &= ~(((uint32_t) 0xf) << 24) ; //PB14 OUTPUT - AFIO - PUSH PULLGPIOB->CRH |= ((uint32_t) 0xb) << 24 ; //PB15 OUTPUT - AFIO - PUSH PULL //////MISO//////GPIOB->CRH &= ~(((uint32_t) 0xf) << 28) ; //PB15 OUTPUT - AFIO - PUSH PULLGPIOB->CRH |= ((uint32_t) 0xb) << 28 ; //PB15 OUTPUT - AFIO - PUSH PULL //////MOSI//////GPIOA->CRH &= ~(((uint32_t) 0xf) << 0) ; //PB8 OUTPUT - GENERAL PURPUSE - PUSH PULLGPIOA->CRH &= ~(((uint32_t) 0x1) << 0) ; //PB8 OUTPUT - GENERAL PURPUSE - PUSH PULLGPIOA->CRH &= ~(((uint32_t) 0xf) << 4) ; //PB8 OUTPUT - GENERAL PURPUSE - PUSH PULLGPIOA->CRH &= ~(((uint32_t) 0x1) << 4) ; //PB8 OUTPUT - GENERAL PURPUSE - PUSH PULL}void SPI_init(void){SPI2->CR1 = 0x0000;SPI2->CR1 |= ((uint16_t)0x1)<<4; // Fclk/4//SPI1->CR1 |= ((uint16_t)0x1)<<8; // Enable SSISPI2->CR2 |= ((uint16_t)0x1)<<2;SPI2->CR1 |= ((uint16_t)0x1)<<2; // Master modeSPI2->CR1 |= ((uint16_t)0x1)<<15; // BIDIRECTIONSPI2->CR1 |= ((uint16_t)0x1)<<14; // TRANSMIT ONLYSPI2->CR1 |= ((uint16_t)0x1)<<6; // SPI1 enable}void LCD_init(void){NRES; //PULLS RESET PIN HIGHRESET_DK; //PULLS DK PIN LOW - COMMAND MODERES; //PULLS RESET PIN LOWdelay();NRES; //PULLS RESET PIN HIGH}void delay(void){uint32_t volatile count = 0 ;while( count < 100 ){count++;}}What's really weird is that the LCD sometimes turns 1/3 of its pixels on when I push the reset button , and if I pushed more two times it turns the whole screen on (1/3 each time) and the same when I enter the debug mode.So what is the wrong with my code?