Skocz do zawartości

[STM32F4] LCD via SPI


abc12

Pomocna odpowiedź

Dzień dobry.

Jestem początkującycm właścicielem płytki STM32F429-DISCO. W ramach ćwiczenia staram się skonwertować bibliotekę LCD znalezioną w internecie w celu użytkowania wbudowanego wyświetlacza pod HAL SPI. Po sporej części spędzonego czasu niestety LCD nadal nie działa. Sprawdziłem, że SPI jest inicjowane. Command string do odpalenia LCD również jest poprawny, bo jest na bazie dokumentacji+poradników. Będę bardzo wdzięczny za pomoc przy znalezieniu przyczyny problemu. Kod poniżej (funkcje do SPI/GPIO init znajdują się na końcu LCD.h - przyznam, niezbyt zorganizowane rozwiązanie).

main.c:

#include "stm32f4xx.h"
#include "stm32f429i_discovery.h"
#include "LCD.h"
#include "SPI.h"
#include "fonts.h"


#define USE_MAIN_CLOCK_72MHZ 1

static void SystemClock_Config(void);


int main(void) {
   HAL_Init();

   // Configure the system clock
   SystemClock_Config();
   SystemCoreClockUpdate();
   SysTick_Config(SystemCoreClock / 1000);

   BSP_LED_Init(LED4);
   LCD_Init();

   for(;;)
   {
   	LCD_Putc(120,120, 'c', &Font8, LCD_COLOR_YELLOW);
   }

   return 0;
}


/**
* @brief  System Clock Configuration
*         The system Clock is configured as follow :
*            System Clock source            = PLL (HSE)
*            SYSCLK(Hz)                     = 180000000
*            HCLK(Hz)                       = 180000000
*            AHB Prescaler                  = 1
*            APB1 Prescaler                 = 4
*            APB2 Prescaler                 = 2
*            HSE Frequency(Hz)              = 8000000
*            PLL_M                          = 8
*            PLL_N                          = 360
*            PLL_P                          = 2
*            PLL_Q                          = 7
*            VDD(V)                         = 3.3
*            Main regulator output voltage  = Scale1 mode
*            Flash Latency(WS)              = 5
*         The LTDC Clock is configured as follow :
*            PLLSAIN                        = 192
*            PLLSAIR                        = 4
*            PLLSAIDivR                     = 8
* @param  None
* @retval None
*
* COPYRIGHT(c) 2014 STMicroelectronics
*/

#if 1 == USE_MAIN_CLOCK_180MHZ
static void SystemClock_Config(void) {
   RCC_ClkInitTypeDef RCC_ClkInitStruct;
   RCC_OscInitTypeDef RCC_OscInitStruct;
   RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;

   /* Enable Power Control clock */
   __PWR_CLK_ENABLE();

   /* The voltage scaling allows optimizing the power consumption when the device is
    clocked below the maximum system frequency, to update the voltage scaling value
    regarding system frequency refer to product datasheet.  */
   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

   /*##-1- System Clock Configuration #########################################*/
   /* Enable HSE Oscillator and activate PLL with HSE as source */
   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
   RCC_OscInitStruct.PLL.PLLM = 8;
   RCC_OscInitStruct.PLL.PLLN = 360;
   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
   RCC_OscInitStruct.PLL.PLLQ = 7;
   HAL_RCC_OscConfig(&RCC_OscInitStruct);

   HAL_PWREx_ActivateOverDrive();

   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
    clocks dividers */
   RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

   /*##-2- LTDC Clock Configuration ###########################################*/
   /* LCD clock configuration */
   /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
   /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */
   /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/4 = 48 Mhz */
   /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDIVR_8 = 48/8 = 6 Mhz */
   PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
   PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
   PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
   PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
   HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
}
#endif



/**
* SYSCLK = 72
* HCLK = 72
* Cortex Timer 72
* FCLK 72
* APB1 Peripheral (PCLK1) 36
* APB1 Timer 72
* APB2 Peripheral (PCLK2) 72
* APB2 Timer 72
*
*/
#if 1 == USE_MAIN_CLOCK_72MHZ
void SystemClock_Config(void)
{

 RCC_OscInitTypeDef RCC_OscInitStruct;
 RCC_ClkInitTypeDef RCC_ClkInitStruct;
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;

   /**Configure the main internal regulator output voltage
   */
 __HAL_RCC_PWR_CLK_ENABLE();

 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

   /**Initializes the CPU, AHB and APB busses clocks
   */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 4;
 RCC_OscInitStruct.PLL.PLLN = 72;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = 3;
 HAL_RCC_OscConfig(&RCC_OscInitStruct);


   /**Initializes the CPU, AHB and APB busses clocks
   */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                             |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
 PeriphClkInitStruct.PLLSAI.PLLSAIN = 50;
 PeriphClkInitStruct.PLLSAI.PLLSAIR = 2;
 PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
 HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);

//    /**Configure the Systick interrupt time
//    */
//  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
//
//    /**Configure the Systick
//    */
//  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
//
//  /* SysTick_IRQn interrupt configuration */
//  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
#endif


LCD.h:

#ifndef LCD_H_
#define LCD_H_

#include "fonts.h"


#define LCD_WIDTH  240
#define LCD_HEIGHT 320
#define LCD_PIXEL  76800

#define LCD_COLOR_WHITE			0xFFFF
#define LCD_COLOR_BLACK			0x0000
#define LCD_COLOR_RED           0xF800
#define LCD_COLOR_GREEN			0x07E0
#define LCD_COLOR_GREEN2		0xB723
#define LCD_COLOR_BLUE			0x001F
#define LCD_COLOR_BLUE2			0x051D
#define LCD_COLOR_YELLOW		0xFFE0
#define LCD_COLOR_ORANGE		0xFBE4
#define LCD_COLOR_CYAN			0x07FF
#define LCD_COLOR_MAGENTA		0xA254
#define LCD_COLOR_GRAY			0x7BEF
#define LCD_COLOR_BROWN			0xBBCA
#define LCD_TRANSPARENT			0x80000000

typedef enum {
LCD_Orientation_Portrait_1,
LCD_Orientation_Portrait_2,
LCD_Orientation_Landscape_1,
LCD_Orientation_Landscape_2
} LCD_Orientation_t;

void LCD_Init(void);
int LCD_InitLCD(void);
void LCD_SendData(uint8_t data);
void LCD_SendCommand(uint8_t data);
void LCD_SetCursor(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void LCD_Pixel(uint16_t x, uint16_t y, uint32_t color);
void LCD_Fill(uint32_t color);
void LCD_Rotate(LCD_Orientation_t orientation);
void LCD_Putc(uint16_t x, uint16_t y, char c, sFONT* font, uint32_t foreground);
void LCD_Puts(uint16_t x, uint16_t y, char* str, sFONT *font, uint32_t foreground);
void LCD_GetStringSize(char* str, sFONT* font, uint16_t* width, uint16_t* height);
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color);
void LCD_DrawRectangle(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, uint32_t color);
void LCD_DrawCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color);
void LCD_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color);
void LCD_DisplayOn(void);
void LCD_DisplayOff(void);
void Delay(volatile unsigned int delay);

#endif /* LCD_H_ */

SPI.h:

#ifndef SPI_H_
#define SPI_H_

#include "stm32f4xx_hal.h"

#define SPIx                             SPI5
#define SPIxCLK_ENABLE()                 __HAL_RCC_SPI5_CLK_ENABLE();
#define SPIxCLK_DISABLE()                __HAL_RCC_SPI5_CLK_DISABLE();
#define SPIx_SCK_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOF_CLK_ENABLE();
#define SPIx_MISO_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOF_CLK_ENABLE();
#define SPIxMOSI_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOF_CLK_ENABLE();
#define WRX_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOD_CLK_ENABLE();
#define CS_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOC_CLK_ENABLE();
#define RST_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOD_CLK_ENABLE();

#define SPIx_FORCE_RESET()               __SPI5_FORCE_RESET()
#define SPIx_RELEASE_RESET()             __SPI5_RELEASE_RESET

#define SPIx_SCK_PIN                     GPIO_PIN_7
#define SPIx_SCK_GPIO_PORT               GPIOF
#define SPIx_SCK_AF                      GPIO_AF5_SPI5
#define SPIx_MISO_PIN                    GPIO_PIN_8
#define SPIx_MISO_GPIO_PORT              GPIOF
#define SPIx_MISO_AF                     GPIO_AF5_SPI5
#define SPIx_MOSI_PIN                    GPIO_PIN_9
#define SPIx_MOSI_GPIO_PORT              GPIOF
#define SPIx_MOSI_AF                     GPIO_AF5_SPI5

#define WRX_PIN							 GPIO_PIN_13
#define WRX_GPIO_PORT                    GPIOD
#define CS_PIN                           GPIO_PIN_2
#define CS_GPIO_PORT                     GPIOC
#define RST_PIN                          GPIO_PIN_12
#define RST_GPIO_PORT                    GPIOD

#define DMAx                             DMA2
#define DMAx_CLOCK_ENABLE()              __HAL_RCC_DMA2_CLK_ENABLE();
#define DMAx_RX_STREAM                   DMA2_Stream3
#define DMAx_RX_CHANNEL                  DMA_CHANNEL_2
#define DMAx_TX_STREAM                   DMA2_Stream4
#define DMAx_TX_CHANNEL                  DMA_CHANNEL_2
#define DMAx_CLOCK_ENABLE()              __HAL_RCC_DMA2_CLK_ENABLE();


#define BUFFERSIZE                      (COUNTOF(aTxBuffer)-1)
#define COUNTOF(__BUFFER__)             (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))

void GPIO_SPI_DMA_Init(void);
void SPI_Init(void);
void DMA_Init(void);
void GPIO_Init(void);
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi);
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi);


LCD.c:

#include <stdlib.h>
#include "LCD.h"
#include "SPI.h"
#include "ili9341.h"
#include "stm32f4xx_hal.h"


#define WRX_SET()          HAL_GPIO_WritePin(WRX_GPIO_PORT, WRX_PIN, 1);
#define WRX_RESET()        HAL_GPIO_WritePin(WRX_GPIO_PORT, WRX_PIN, 0);
#define CS_SET()           HAL_GPIO_WritePin(CS_GPIO_PORT, CS_PIN, 1);
#define CS_RESET()         HAL_GPIO_WritePin(CS_GPIO_PORT, CS_PIN, 0);
#define RST_SET()          HAL_GPIO_WritePin(RST_GPIO_PORT, RST_PIN, 1);
#define RST_RESET()        HAL_GPIO_WritePin(RST_GPIO_PORT, RST_PIN, 0);

typedef enum {
LCD_Landscape,
LCD_Portrait
}LCD_Orientation;

typedef struct {
uint16_t width;
uint16_t height;
LCD_Orientation orientation;
}LCD_Options_t;

GPIO_InitTypeDef GPIO_InitStruct;
SPI_HandleTypeDef hspi;
DMA_HandleTypeDef hdma_spi_rx;
DMA_HandleTypeDef hdma_spi_tx;

uint16_t LCD_x;
uint16_t LCD_y;
LCD_Options_t LCD_Options;
uint8_t Data_From_Puts = 0;

void LCD_Init(void) {
GPIO_Init();
CS_SET();
DMA_Init();
SPI_Init();
LCD_InitLCD();
LCD_x = LCD_y = 0;
LCD_Options.width = LCD_WIDTH;
LCD_Options.height = LCD_HEIGHT;
LCD_Options.orientation = LCD_Portrait;
LCD_Fill(LCD_COLOR_RED);
}

int LCD_InitLCD(void) {
RST_RESET();
Delay(20000);
RST_SET();
Delay(20000);
LCD_SendCommand(LCD_SWRESET);
Delay(50000);
LCD_SendCommand(LCD_POWERA);
LCD_SendData(0x39);
LCD_SendData(0x2C);
LCD_SendData(0x00);
LCD_SendData(0x34);
LCD_SendData(0x02);
LCD_SendCommand(LCD_POWERB);
LCD_SendData(0x00);
LCD_SendData(0xC1);
LCD_SendData(0x30);
LCD_SendCommand(LCD_DTCA);
LCD_SendData(0x85);
LCD_SendData(0x00);
LCD_SendData(0x78);
LCD_SendCommand(LCD_DTCB);
LCD_SendData(0x00);
LCD_SendData(0x00);
LCD_SendCommand(LCD_POWER_SEQ);
LCD_SendData(0x64);
LCD_SendData(0x03);
LCD_SendData(0x12);
LCD_SendData(0x81);
LCD_SendCommand(LCD_PRC);
LCD_SendData(0x20);
LCD_SendCommand(LCD_POWER1);
LCD_SendData(0x23);
LCD_SendCommand(LCD_POWER2);
LCD_SendData(0x10);
LCD_SendCommand(LCD_VCOM1);
LCD_SendData(0x3E);
LCD_SendData(0x28);
LCD_SendCommand(LCD_VCOM2);
LCD_SendData(0x86);
LCD_SendCommand(LCD_MAC);
LCD_SendData(0x48);
LCD_SendCommand(LCD_PIXEL_FORMAT);
LCD_SendData(0x55);
LCD_SendCommand(LCD_FRMCTR1);
LCD_SendData(0x00);
LCD_SendData(0x18);
LCD_SendCommand(LCD_DFC);
LCD_SendData(0x08);
LCD_SendData(0x82);
LCD_SendData(0x27);
LCD_SendCommand(LCD_3GAMMA_EN);
LCD_SendData(0x00);
LCD_SendCommand(LCD_COLUMN_ADDR);
LCD_SendData(0x00);
LCD_SendData(0x00);
LCD_SendData(0x00);
LCD_SendData(0xEF);
LCD_SendCommand(LCD_PAGE_ADDR);
LCD_SendData(0x00);
LCD_SendData(0x00);
LCD_SendData(0x01);
LCD_SendData(0x3F);
LCD_SendCommand(LCD_GAMMA);
LCD_SendData(0x01);
LCD_SendCommand(LCD_PGAMMA);
LCD_SendData(0x0F);
LCD_SendData(0x31);
LCD_SendData(0x2B);
LCD_SendData(0x0C);
LCD_SendData(0x0E);
LCD_SendData(0x08);
LCD_SendData(0x4E);
LCD_SendData(0xF1);
LCD_SendData(0x37);
LCD_SendData(0x07);
LCD_SendData(0x10);
LCD_SendData(0x03);
LCD_SendData(0x0E);
LCD_SendData(0x09);
LCD_SendData(0x00);
LCD_SendCommand(LCD_NGAMMA);
LCD_SendData(0x00);
LCD_SendData(0x0E);
LCD_SendData(0x14);
LCD_SendData(0x03);
LCD_SendData(0x11);
LCD_SendData(0x07);
LCD_SendData(0x31);
LCD_SendData(0xC1);
LCD_SendData(0x48);
LCD_SendData(0x08);
LCD_SendData(0x0F);
LCD_SendData(0x0C);
LCD_SendData(0x31);
LCD_SendData(0x36);
LCD_SendData(0x0F);
LCD_SendCommand(LCD_SLEEP_OUT);
Delay(1000000);
LCD_SendCommand(LCD_DISPLAY_ON);
LCD_SendCommand(LCD_GRAM);
return 1;
}

void LCD_DisplayOn(void){
LCD_SendCommand(LCD_DISPLAY_ON);
}

void LCD_DisplayOff(void) {
LCD_SendCommand(LCD_DISPLAY_OFF);
}

void LCD_SendCommand(uint8_t data) {
WRX_RESET();
CS_RESET();
HAL_SPI_Transmit_IT(&hspi, &data, 1);
CS_SET();
}

void LCD_SendData(uint8_t data) {
WRX_SET();
CS_RESET();
HAL_SPI_Transmit_IT(&hspi, &data, 1);
CS_SET();
}

void LCD_DrawPixel(uint16_t x, uint16_t y, uint32_t color) {
LCD_SetCursor(x,y,x,y);
LCD_SendCommand(LCD_GRAM);
LCD_SendData(color >> 8);
LCD_SendData(color & 0xFF);
}

void LCD_SetCursor(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
LCD_SendCommand(LCD_COLUMN_ADDR);
LCD_SendData(x1 >> 8);
LCD_SendData(x1 & 0xFF);
LCD_SendData(x2 >> 8);
LCD_SendData(x2 & 0xFF);

LCD_SendCommand(LCD_PAGE_ADDR);
LCD_SendData(y1 >> 8);
LCD_SendData(y1 & 0xFF);
LCD_SendData(y2 >> 8);
LCD_SendData(y2 & 0xFF);
}

void LCD_Fill(uint32_t color) {
uint32_t n;
uint8_t hi,lo;
hi = color >> 8;
lo = color & 0xFF;
LCD_SetCursor(0,0,LCD_Options.width - 1,LCD_Options.height -1);
LCD_SendCommand(LCD_GRAM);
for(n=0;n<LCD_PIXEL;n++) {
	LCD_SendData(hi);
	LCD_SendData(lo);
}
}

void LCD_Rotate(LCD_Orientation_t orientation) {
LCD_SendCommand(LCD_MAC);
if (orientation == LCD_Orientation_Portrait_1) {
	LCD_SendData(0x58);
}
else if (orientation == LCD_Orientation_Portrait_2) {
	LCD_SendData(0x88);
}
else if (orientation == LCD_Orientation_Landscape_1) {
	LCD_SendData(0x28);
}
else LCD_SendData(0xE8);
if (orientation == LCD_Orientation_Portrait_1 || orientation == LCD_Orientation_Portrait_2) {
	LCD_Options.width = LCD_WIDTH;
	LCD_Options.height = LCD_HEIGHT;
	LCD_Options.orientation = LCD_Portrait;
}
else {
	LCD_Options.width = LCD_HEIGHT;
	LCD_Options.height = LCD_WIDTH;
	LCD_Options.orientation = LCD_Landscape;
}
}

void LCD_Puts(uint16_t x, uint16_t y, char *str, sFONT* font, uint32_t foreground) {
uint16_t startX = x;
LCD_x = x;
LCD_y = y;
while (*str) {
	if (*str == '\n') {
		LCD_y += font->Height + 1;
		if (*(str+1) == '\r') {
			LCD_x = 0;
			str++;
		}
		else {
			LCD_x = startX;
		}
		str++;
		continue;
	}
	else if (*str == '\r') {
		str++;
		continue;
	}
	LCD_Putc(LCD_x, LCD_y, *str++, font, foreground);
}
}

void LCD_GetStringSize(char *str, sFONT* font, uint16_t *width, uint16_t *height) {
uint16_t w = 0;
*height = font->Height;
while (*str++) {
	w += font->Width;
}
*width = w;
}

void LCD_Putc(uint16_t x, uint16_t y, char c, sFONT* font, uint32_t foreground) {
uint32_t i, b, j;
LCD_x = x;
LCD_y = y;
if ((LCD_x + font->Width) > LCD_Options.width) {
	LCD_y += font->Width;
	LCD_x = 0;
}
for (i=0; i<font->Height; i++) {
	b = font->table[(c-32)*font->Height + i];
	for (j=0; j<font->Width;j++) {
		if ((b<<j) & 0x8000) {
			LCD_DrawPixel(LCD_x + j, LCD_y + i, foreground);
		}
	}
}
LCD_x += font->Width;

}

void LCD_DrawLine(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2, uint32_t color) {

int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
  yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
  curpixel = 0;
  deltax = abs(X2 - X1);
  deltay = abs(Y2 - Y1);
  x = X1;
  y = Y1;
  if (X2 >= X1)
  {
    xinc1 = 1;
    xinc2 = 1;
  }
  else
  {
    xinc1 = -1;
    xinc2 = -1;
  }
  if (Y2 >= Y1)
  {
    yinc1 = 1;
    yinc2 = 1;
  }
  else
  {
    yinc1 = -1;
    yinc2 = -1;
  }
  if (deltax >= deltay)
  {
    xinc1 = 0;
    yinc2 = 0;
    den = deltax;
    num = deltax / 2;
    numadd = deltay;
    numpixels = deltax;
  }
  else
  {
    xinc2 = 0;
    yinc1 = 0;
    den = deltay;
    num = deltay / 2;
    numadd = deltax;
    numpixels = deltay;
  }
  for (curpixel = 0; curpixel <= numpixels; curpixel++)
  {
	LCD_DrawPixel(x, y, color);
    num += numadd;
    if (num >= den)
    {
      num -= den;
      x += xinc1;
      y += yinc1;
    }
    x += xinc2;
    y += yinc2;
  }
}

void LCD_DrawRectangle(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, uint32_t color) {
LCD_DrawLine(x0,y0,x1,y0,color);
LCD_DrawLine(x0,y0,x0,y1,color);
LCD_DrawLine(x1,y0,x1,y1,color);
LCD_DrawLine(x0,y1,x1,y1,color);
}

void LCD_DrawCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color) {
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;

   LCD_DrawPixel(x0, y0 + r, color);
   LCD_DrawPixel(x0, y0 - r, color);
   LCD_DrawPixel(x0 + r, y0, color);
   LCD_DrawPixel(x0 - r, y0, color);

   while (x < y) {
       if (f >= 0) {
           y--;
           ddF_y += 2;
           f += ddF_y;
       }
       x++;
       ddF_x += 2;
       f += ddF_x;

       LCD_DrawPixel(x0 + x, y0 + y, color);
       LCD_DrawPixel(x0 - x, y0 + y, color);
       LCD_DrawPixel(x0 + x, y0 - y, color);
       LCD_DrawPixel(x0 - x, y0 - y, color);

       LCD_DrawPixel(x0 + y, y0 + x, color);
       LCD_DrawPixel(x0 - y, y0 + x, color);
       LCD_DrawPixel(x0 + y, y0 - x, color);
       LCD_DrawPixel(x0 - y, y0 - x, color);
   }
}

void LCD_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color) {
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;

   LCD_DrawPixel(x0, y0 + r, color);
   LCD_DrawPixel(x0, y0 - r, color);
   LCD_DrawPixel(x0 + r, y0, color);
   LCD_DrawPixel(x0 - r, y0, color);
   LCD_DrawLine(x0 - r, y0, x0 + r, y0, color);

   while (x < y) {
       if (f >= 0) {
           y--;
           ddF_y += 2;
           f += ddF_y;
       }
       x++;
       ddF_x += 2;
       f += ddF_x;

       LCD_DrawLine(x0 - x, y0 + y, x0 + x, y0 + y, color);
       LCD_DrawLine(x0 + x, y0 - y, x0 - x, y0 - y, color);

       LCD_DrawLine(x0 + y, y0 + x, x0 - y, y0 + x, color);
       LCD_DrawLine(x0 + y, y0 - x, x0 - y, y0 - x, color);
   }
}




void SPI_Init(void) {

 hspi.Instance = SPIx;
 hspi.Init.Mode = SPI_MODE_MASTER;
 hspi.Init.Direction = SPI_DIRECTION_2LINES;
 hspi.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
 hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi.Init.NSS = SPI_NSS_SOFT;
 hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
 hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi.Init.CRCPolynomial = 10;
 HAL_SPI_Init(&hspi);

}


void DMA_Init(void) {

/* DMA controller clock enable */
 DMAx_CLOCK_ENABLE();

 /* DMA interrupt init */
 /* DMA2_Stream3_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
 /* DMA2_Stream4_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);

}

void GPIO_Init(void) {
WRX_GPIO_CLK_ENABLE();
CS_GPIO_CLK_ENABLE();
RST_GPIO_CLK_ENABLE();

GPIO_InitStruct.Pin = WRX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(WRX_GPIO_PORT, &GPIO_InitStruct);

GPIO_InitStruct.Pin = CS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(CS_GPIO_PORT, &GPIO_InitStruct);

GPIO_InitStruct.Pin = RST_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW ;
HAL_GPIO_Init(RST_GPIO_PORT, &GPIO_InitStruct);
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) {

SPIxCLK_ENABLE();
SPIx_SCK_GPIO_CLK_ENABLE();
SPIx_MISO_GPIO_CLK_ENABLE();
SPIxMOSI_GPIO_CLK_ENABLE();


GPIO_InitStruct.Pin = SPIx_SCK_PIN|SPIx_MISO_PIN|SPIx_MOSI_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = SPIx_SCK_AF;
HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);

hdma_spi_rx.Instance = DMAx_RX_STREAM;
hdma_spi_rx.Init.Channel = DMAx_RX_CHANNEL;
hdma_spi_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi_rx.Init.Mode = DMA_NORMAL;
hdma_spi_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_spi_rx);

__HAL_LINKDMA(hspi,hdmarx,hdma_spi_rx);

hdma_spi_tx.Instance = DMAx_TX_STREAM;
hdma_spi_tx.Init.Channel = DMAx_TX_CHANNEL;
hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi_tx.Init.Mode = DMA_NORMAL;
hdma_spi_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_spi_tx);

__HAL_LINKDMA(hspi,hdmatx,hdma_spi_tx);
}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) {

SPIxCLK_DISABLE();
HAL_GPIO_DeInit(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN);
HAL_GPIO_DeInit(SPIx_MISO_GPIO_PORT, SPIx_MISO_PIN);
HAL_GPIO_DeInit(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN);


HAL_DMA_DeInit(hspi->hdmarx);
HAL_DMA_DeInit(hspi->hdmatx);
}

void Delay(volatile unsigned int delay) {
for(;delay != 0; delay--);
}
Link do komentarza
Share on other sites

Z tego co pamiętam, to ten wyświetlacz zajmował strasznie dużo pinów na tej Discoverce, więc raczej nie obsłużysz go przez SPI.

W dokumentacji (UM1670) do tej płytki jest coś takiego:

The TFT LCD is a 2.41" display of 262 K colors. Its definition is QVGA (240 x 320 dots) and is directly driven by the STM32F429ZIT6 using the RGB protocol. It includes the ILI9341 LCD controller and can operate with a 2.8 ±0.3 V voltage.

Na początek spróbuj z przykładami napisanymi przez ST bezpośrednio dla tej płytki: http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries-expansions/stsw-stm32138.html

Link do komentarza
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!

Anonim
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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.