Skocz do zawartości
Vroobee

[STM32] STM32F3x problem z uruchomieniem wyświetlacza graficznego - SPI

Pomocna odpowiedź

Mnie zastanawia ten człon "I2S" w nazwach funkcji. Jesteś pewny, że wykorzystujesz poprawne funkcje? Bo ogólnie I2S to trochę co innego i do czego innego służy niż SPI https://en.wikipedia.org/wiki/I²S

Udostępnij ten post


Link to post
Share on other sites
* @brief  Transmits a Data through the SPIx/I2Sx peripheral.
 * @param  SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 
 *         in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode.  
 * @param  Data: Data to be transmitted.
 * @retval None

Funkcja odpowiedzialna za wysyłanie danych przez SPI/I2S.

Przy okazji zapytam, bo mnie to nurtuje. Mój angielski nie jest jakiś super ale z tego co zrozumiałem w jakimś pdfie na stronie ST o SPI to ramka wysyłania danych przez SPI wygląda tak:

- 8 Command Bitów,
- 8 bitów danych.

Podejrzewam, że dlatego funkcja wysyłająca wykorzystuje zmienną uint16_t. Ktoś może to potwierdzić ?

Czy może być błąd w tym, że wykorzystuję do przesyłania funkcję, która na wejściu musi otrzymać zmienną 16 bitową, a wysyłam tablicę char'ów, której każdy element jest zapisany w HEXie ?

Udostępnij ten post


Link to post
Share on other sites

Faktycznie I2S to tylko zmyłka ze strony ST...

Co do formatu SPI to jest bardzo prosty - wysyłasz w paczkach n-bitów, najczęściej 8, ale może być inna liczba, np. 4 lub 11 - i dlatego uint16_t, żeby zmieściło się więcej niż 8. Ale nie musi być tam ani komendy, ani danych. To jest ustalane w "wyższej warstwie", czyli np. sterowniku wyświetlacza. Samo SPI po prostu przesyła paczkę n-bitów i koniec.

A co do działania, to popatrz na ten fragment:

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_5); 
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_5); 

Czy w drugiej linijce nie powinno być aby GPIO_AF_3 ?

Udostępnij ten post


Link to post
Share on other sites
#define GPIO_AF_5            ((uint8_t)0x05) /* IR_OUT, I2S2, I2S3, SPI1, SPI2, TIM8, USART4, USART5 */

Hmmm... nie sądzę, żeby tam musiało być GPIO_AF_3, które odpowiada za:

#define GPIO_AF_3            ((uint8_t)0x03) /* COMP7_OUT, TIM8, TIM15, Touch, HRTIM1 */

A mi chodzi o używanie SPI1. W funkcji wskazywana jest funkcja alternatywna - SPI1 jest funkcją 5 (GPIO_AF_5). PinSource to pin źródłowy czyli PB3 i PB5.

Udostępnij ten post


Link to post
Share on other sites

Jednak F3 sporo różni się od F1 - zostaje więc dokładne przeczytanie dokumentacji i przykładów. Jedyne co na szybko jeszcze można wypróbować to dodanie:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

Udostępnij ten post


Link to post
Share on other sites

Zwiększa nieco pobór prądu, ale nic złego poza tym. Niby potrzebne dopiero przy remapowaniu pinów, ale co szkodzi spróbować.

Udostępnij ten post


Link to post
Share on other sites

Próbowałeś tej zmiany współrzędnych x z y ( adresowania ) ? Jak wygląda obraz na LCD po takim zabiegu ?

Udostępnij ten post


Link to post
Share on other sites

Zmieniłem komendą wyświetlanie horyzontalne na wertykalne, wyświetlały się czarne poziome paski z pustymi polami w środku.

Udostępnij ten post


Link to post
Share on other sites

Po trudach i znojach oraz godzinach siedzenia w SW for STM32 doszedłem w końcu do pożądanego efektu, mianowicie wyświetlenia logo Forbota na LCD od Nokii wykorzystując STM32F303K8T6. Poniżej wklejam kod. Zastosowałem osobną funkcję wysyłania z wykorzystaniem flagi zajętości. Przesyłanie zmiennych 8 bitowych. Dla tego procka ma chyba znaczenie czy wysyłamy ramkę 8 czy 16 bit bo wcześniej wysyłając 16 bitów wyglądało to tak jakby zaczynał od MSB, wypełniał kolorem 8 bitów, a następne 8 bitów (0000 0000) wrzucał w sąsiedni piksel. Stąd otrzymywałem linie zamiast konkretnej bitmapy. 😋

#include "stm32f30x.h"
#include "delay.h"
#include <stdio.h>
#include <stdint.h>

#define LCD_DC			GPIO_Pin_0
#define LCD_CE			GPIO_Pin_7
#define LCD_RST			GPIO_Pin_6
#define LCD_BL			GPIO_Pin_12

int j =0;

const unsigned char logo_mini_mono [] = {
0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x7F, 0x7F, 0x7F, 0xFF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFE, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x7F, 0x3F, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x80, 0xE0, 0x01, 0x01, 0x02, 0x00, 0x04, 0x08, 0xF8,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
0xF8, 0xF9, 0xFB, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x7F, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0xE0, 0x0C, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03,
0x03, 0x81, 0x81, 0x81, 0xC1, 0xC0, 0xC0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE,
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC,
0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F,
};

void spi_sendrecv(uint8_t byte){
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_SendData8(SPI1, byte);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
}

void lcd_reset(){
GPIO_ResetBits(GPIOB, LCD_RST);
delay_ms(10);
GPIO_SetBits(GPIOB, LCD_RST);
}

void lcd_cmd(uint8_t cmd){
GPIO_ResetBits(GPIOB, LCD_CE|LCD_DC);
spi_sendrecv(cmd);
GPIO_SetBits(GPIOB, LCD_CE|LCD_DC);
}

void lcd_data(const uint8_t* data, int size){
int i=0;
GPIO_SetBits(GPIOB, LCD_DC);
GPIO_ResetBits(GPIOB, LCD_CE);
for (i = 0; i < size; i++)
	spi_sendrecv(data[i]);
GPIO_SetBits(GPIOB, LCD_CE);
}

void lcd_clr (void){
for(j=0;j<504;j++){
	spi_sendrecv(0x00);
}
}

int main(void){
GPIO_InitTypeDef gpio;
SPI_InitTypeDef spi;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

GPIO_StructInit(&gpio);
//BL
gpio.GPIO_Pin = GPIO_Pin_12;
gpio.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(GPIOA, &gpio);
GPIO_SetBits(GPIOA, GPIO_Pin_12);
//MOSI
gpio.GPIO_Pin = GPIO_Pin_5;
gpio.GPIO_Mode = GPIO_Mode_AF;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_OType = GPIO_OType_PP;
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_5);
GPIO_Init(GPIOB, &gpio);
//SCK
gpio.GPIO_Pin = GPIO_Pin_3;
gpio.GPIO_Mode = GPIO_Mode_AF;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_OType = GPIO_OType_PP;
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_5);
GPIO_Init(GPIOB, &gpio);

gpio.GPIO_Pin = LCD_DC|LCD_CE|LCD_RST;
gpio.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(GPIOB, &gpio);
GPIO_SetBits(GPIOB, LCD_CE|LCD_RST|LCD_DC);

SPI_StructInit(&spi);
spi.SPI_Mode = SPI_Mode_Master;
spi.SPI_NSS = SPI_NSS_Soft;
spi.SPI_FirstBit = SPI_FirstBit_MSB;
spi.SPI_DataSize = SPI_DataSize_8b;
spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_Init(SPI1, &spi);
SPI_Cmd(SPI1, ENABLE);

SysTick_Config(SystemCoreClock / 1000);

GPIO_SetBits(GPIOB, LCD_CE|LCD_RST);
lcd_reset();
lcd_cmd(0x21);
lcd_cmd(0x14);
lcd_cmd(0x40);
lcd_cmd(0x80 | 0x3f); //Ustawienie kontrastu
lcd_cmd(0x20);
lcd_cmd(0x0C);
lcd_clr();

lcd_data(logo_mini_mono, sizeof(logo_mini_mono));

while(1){

}
}

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...