DeadGeneratio Napisano Wrzesień 27, 2023 Udostępnij Napisano Wrzesień 27, 2023 Jak w temacie, zaufałem marce WeAct pod względem mikrokontrolerów, ale niestety ciężko z znalezieniem biblioteki do 2,9 calowego modułu wyświetlacza w technologii e-paper, w wersji black, white and red. Chciałem wzorować się na module od waveshare, mają biblioteki do stm32 f103, ale tylko dla wersji black-white. Z kolei na githubie od WeAct, link obok: https://github.com/WeActStudio/WeActStudio.EpaperModule/tree/master nie ma wersji dla STM. Starałem się przejrzeć datasheet jak zrobiłem to dla czujnika ciśnienia i temperatury STH czy tam SHT31 i zrobiłem komplet funkcji które działały na jego podstawie, ale ten datashhet mnie niestety przerasta. Sądziłem, że będzie to najzwyklejszy ekran a to ma więcej funkcji niż stare telefony, a tak przynajmniej datasheet wygląda. Ma ktoś może taką bibliotekę, wie gdzie szukać bądź zetknął się już z tym modułem? 1 Link do komentarza Share on other sites More sharing options...
H1M4W4R1 Wrzesień 27, 2023 Udostępnij Wrzesień 27, 2023 (edytowany) Weź exampla od APM32F103 i przerób ją pod STM32... powinny być zbliżone 😉 https://github.com/WeActStudio/WeActStudio.EpaperModule/tree/master/Example/EpaperModuleTest_APM32F103/Epaper Edytowano Wrzesień 27, 2023 przez H1M4W4R1 1 Link do komentarza Share on other sites More sharing options...
DeadGeneratio Październik 1, 2023 Autor tematu Udostępnij Październik 1, 2023 Są podobne, trochę się namęczyłem z modyfikowaniem. Mam problem teraz z programowym ustawieniem SPI, zamiast w cube ide robię to w programie. Ktoś rzuciłby okiem co robię źle? Poniżej cały kod, oraz schemat podłączenia pod płytkę. Model mikrokontrolera to STM32H723VGT6 Namieszane_w_SPI.zip Link do komentarza Share on other sites More sharing options...
_LM_ Październik 1, 2023 Udostępnij Październik 1, 2023 Masz dołączony nagłówek screen.h w pliku źródłowym? Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
DeadGeneratio Październik 1, 2023 Autor tematu Udostępnij Październik 1, 2023 (edytowany) W screen.c mam: #include "screen.h" #include "fonts.h" #include "stm32h7xx_hal.h" a wcześniej gdy ustawiłem rozdrobnienie programu osobne pliki .c oraz .h #include "screen.h" #include "fonts.h" #include "stm32h7xx_hal.h" #include "spi.h" #include "gpio.h" Wiem, że to głupie z tym spi.h skoro ja tworzę tutaj instancję SPI, ale postanowiłem stworzyć początkowo w CUBE IDE instancję SPI, a potem w kodzie nie dodawać części odpowiedzialnej za inicjowanie SPI. To co teraz widać jest próbą stworzenia tej instancji bez pomocy CUBE IDE. Plik screen.h wygląda następująco: #ifndef INC_SCREEN_H_ #define INC_SCREEN_H_ #include "stm32h7xx_hal.h" I oczywiście, w pliku main.c mam dołączenie screen.h Edytowano Październik 1, 2023 przez DeadGeneratio Link do komentarza Share on other sites More sharing options...
DeadGeneratio Październik 1, 2023 Autor tematu Udostępnij Październik 1, 2023 Udało mi się zmodyfikować kod - SPI2 jest inicjalizowane przez CUBE IDE z zawartością analogiczną do tej co w kodzie: void MX_SPI2_Init(void) { /* USER CODE BEGIN SPI2_Init 0 */ /* USER CODE END SPI2_Init 0 */ /* USER CODE BEGIN SPI2_Init 1 */ /* USER CODE END SPI2_Init 1 */ hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_1LINE; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi2.Init.CLKPhase = SPI_PHASE_2EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial = 0x0; hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; hspi2.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; hspi2.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; hspi2.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; hspi2.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; hspi2.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; hspi2.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; hspi2.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; hspi2.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE; hspi2.Init.IOSwap = SPI_IO_SWAP_DISABLE; if (HAL_SPI_Init(&hspi2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SPI2_Init 2 */ /* USER CODE END SPI2_Init 2 */ } oraz wejścia/wyjścia GPIO także: void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, SPI2_RES_Pin|SPI2_DC_Pin|SPI2_CS_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : PBPin PBPin PBPin */ GPIO_InitStruct.Pin = SPI2_RES_Pin|SPI2_DC_Pin|SPI2_CS_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : PtPin */ GPIO_InitStruct.Pin = SPI2_BUSY_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(SPI2_BUSY_GPIO_Port, &GPIO_InitStruct); } Przyszedł czas na testowanie wyświetlacza i mam mały zonk, bo niestety robię to na chłopski rozum z racji braku poradników bądź toturiali, a i z ekranem typu e-papier mam doczynienia pierwszy raz. Przeglądając plik screen.h: #ifndef INC_SCREEN_H_ #define INC_SCREEN_H_ #include "stm32h7xx_hal.h" #define EPD_W 128 #define EPD_H 296 #define EPD_OK 0 #define EPD_ERROR 1 #define EPD_ROTATE_0 0 #define EPD_ROTATE_90 90 #define EPD_ROTATE_180 180 #define EPD_ROTATE_270 270 #define EPD_COLOR_WHITE 0xFF #define EPD_COLOR_BLACK 0x00 #define EPD_COLOR_RED EPD_COLOR_BLACK #define EPD_FONT_SIZE8x6 (8) #define EPD_FONT_SIZE12x6 (12) #define EPD_FONT_SIZE16x8 (16) #define EPD_FONT_SIZE24x12 (24) #define EPD_DEEPSLEEP_MODE1 (0x01) #define EPD_DEEPSLEEP_MODE2 (0x03) #define EPD_W_BUFF_SIZE ((EPD_W % 8 == 0) ? (EPD_W / 8) : (EPD_W / 8 + 1)) typedef struct { uint8_t *Image; uint16_t Width; uint16_t Height; uint16_t WidthMemory; uint16_t HeightMemory; uint16_t Color; uint16_t Rotate; uint16_t WidthByte; uint16_t HeightByte; } EPD_PAINT; extern EPD_PAINT EPD_Paint; uint8_t epd_init(void); uint8_t epd_init_partial(void); void epd_enter_deepsleepmode(uint8_t mode); void epd_init_internalTempSensor(void); void epd_update(void); void epd_update_partial(void); void epd_display(uint8_t *Image1, uint8_t *Image2); void epd_displayBW(uint8_t *Image); void epd_displayBW_partial(uint8_t *Image); void epd_displayRED(uint8_t *Image); void epd_paint_newimage(uint8_t *image, uint16_t Width, uint16_t Height, uint16_t Rotate, uint16_t Color); void epd_paint_setpixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color); void epd_paint_selectimage(uint8_t *image); void epd_paint_clear(uint16_t color); void epd_paint_drawPoint(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color); void epd_paint_drawLine(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color); void epd_paint_drawRectangle(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color, uint8_t mode); void epd_paint_drawCircle(uint16_t X_Center, uint16_t Y_Center, uint16_t Radius, uint16_t Color, uint8_t mode); void epd_paint_showChar(uint16_t x, uint16_t y, uint16_t chr, uint16_t size1, uint16_t color); void epd_paint_showString(uint16_t x, uint16_t y, uint8_t *chr, uint16_t size1, uint16_t color); void epd_paint_showNum(uint16_t x, uint16_t y, uint32_t num, uint16_t len, uint16_t size1, uint16_t color); void epd_paint_showChinese(uint16_t x, uint16_t y, uint16_t num, uint16_t size1, uint16_t color); void epd_paint_showPicture(uint16_t x, uint16_t y, uint16_t sizex, uint16_t sizey, const uint8_t BMP[], uint16_t Color); #ifdef __cplusplus } #endif #endif widzę, że wypadałoby zainicjalizować ekran - epd_init(). Potem dla testu wykonuję epd_paint_clear(0xFF), czyli cały ekran czyszczę na dany kolor, a przynajmniej tak myślałem. Nic się nie działo więc dorzuciłem epd_update() oraz na koniec epd_enter_deepsleepmode(), ale ekran dostaje padaczki. Stwierdziłem, że okej, być może funkcja czyści ekran z tego tylko koloru co zadeklaruję, więc trzykrotnie wywołałem czyszczenie poszczególnego koloru, ale ekran dalej działa tak samo upośledzenie. Ktoś domyśla się co może być przyczyną? W załączniku nowy kod. Nagranie działania ekranu: https://drive.google.com/file/d/1GSGuvmLHbmtp-CNvZ1q1f0HsIFLJ5cqm/view?usp=sharing Namieszane_w_SPIv2.zip Link do komentarza Share on other sites More sharing options...
_LM_ Październik 1, 2023 Udostępnij Październik 1, 2023 3 godziny temu, DeadGeneratio napisał: robię to na chłopski rozum z racji braku poradników bądź toturiali a nota katalogowa wyświetlacza? Link do komentarza Share on other sites More sharing options...
DeadGeneratio Październik 2, 2023 Autor tematu Udostępnij Październik 2, 2023 (edytowany) Niestety z takim rozbudowanym albo tak napisanym dokumentem nie jestem w stanie sobie poradzić samodzielnie. Staram się analizować kod analogiczny dla APM i sprawdzać sobie funkcje poszczególne a nawet odtworzyć kod, ale idzie bardzo kiepsko. Na pewno muszę zainicjować wyświetlacz. Z inżynierii wstecznej wychodzi, że należy wykorzystać rejestr 0x01, a następnie wysłać wartość 0x27, 0x01 oraz 0x01. W sumie czy należy nie wiem, ktoś tak zrobił i w ten sposób wyświetlacz zadziałał. Z kodu potem wynika, że na mikrokontrolerze przygotowana jest mapa bitowa, która potem jest wysyłana komendą epd_display, czyli rejestr 0x24 dla koloru czarno-białego i rejestr 0x26 dla czerwonego. Wysyłane są wtedy dane do RAMu. Ale najgorsze jest to, że skoro rozdzielczość wynosi z grubsza 100x300 to powinienem mieć około 30000 znaków w tablicy. A przykładowe obrazy w pliku bmp mają maksymalnie 4000 znaków. Na samym końcu wywołać wysłanie zawartości RAMu z wyświetlacza na sam wyświetlacz do czego służy rejestr 0x21, a następnie wysłanie komendy przy DC = 1, 0b00000000 - screen poniżej z dokumentacji. Po aktualizacji na pewno wejście w deepsleep mode, czyli 0x10, a potem DC = 1 oraz 0b00000001. Edytowano Październik 2, 2023 przez DeadGeneratio Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »