Olimex STM32-103STK LCD 8544 über SPI

OP #5992578
Lesenswert?

Hallo.

Ich versuche seit geraumer Zeit das oben genannte Olimex-Board bzw. das 
daran-hängende LCD-Display PCD 8544 am SPI über STM32CubeIDE zum laufen 
zu bekommen. Dazu benutze ich die HAL-Funktionen von STM32.
Ich hab schon alles versucht aber das LCD-Display läßt sich einfach 
nicht ansprechen.
Irgendwie hab ich so langsam den Eindruck, dass es Timing-Probleme vom 
SPI sind. Als Programmer nütze ich den JLink-EDU. Selbst das im 
LCD-Datasheet aufgeführte Beispiel hab ich programmiert, aber es 
reagiert nicht.
Ich häng mal den Source hier mit rein vielleicht kann mir jemand 
weiterhelfen.

Gruß ub
1
/* USER CODE BEGIN Header */
2
/**
3
  ******************************************************************************
4
  * @file           : main.c
5
  * @brief          : Main program body
6
  ******************************************************************************
7
  * @attention
8
  *
9
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
10
  * All rights reserved.</center></h2>
11
  *
12
  * This software component is licensed by ST under BSD 3-Clause license,
13
  * the "License"; You may not use this file except in compliance with the
14
  * License. You may obtain a copy of the License at:
15
  *                        opensource.org/licenses/BSD-3-Clause
16
  *
17
  ******************************************************************************
18
  */
19
/* USER CODE END Header */
20

21
/* Includes ------------------------------------------------------------------*/
22
#include "main.h"
23

24
/* Private includes ----------------------------------------------------------*/
25
/* USER CODE BEGIN Includes */
26

27
/* USER CODE END Includes */
28

29
/* Private typedef -----------------------------------------------------------*/
30
/* USER CODE BEGIN PTD */
31

32
/* USER CODE END PTD */
33

34
/* Private define ------------------------------------------------------------*/
35
/* USER CODE BEGIN PD */
36
#define LED_PortC       GPIO_PIN_12
37
#define LCD_CS_PortC    GPIO_PIN_10
38
#define LCD_DC_PortB    GPIO_PIN_2
39
#define LCD_Reset_PortC GPIO_PIN_7
40
/* USER CODE END PD */
41

42
/* Private macro -------------------------------------------------------------*/
43
/* USER CODE BEGIN PM */
44
#define LED_On()       GPIOC->BRR  |= LED_PortC
45
#define LED_Off()      GPIOC->BSRR |= LED_PortC
46

47
#define LCD_CS_Hi()    GPIOC->BSRR |= LCD_CS_PortC
48
#define LCD_CS_Lo()    GPIOC->BRR  |= LCD_CS_PortC
49

50
#define LCD_Data()     GPIOB->BSRR |= LCD_DC_PortB
51
#define LCD_Command()  GPIOB->BRR  |= LCD_DC_PortB
52

53
#define LCD_Reset_Lo() GPIOC->BRR  |= LCD_Reset_PortC
54
#define LCD_Reset_Hi() GPIOC->BSRR |= LCD_Reset_PortC
55

56
// Display Function Set = 0 0 1 0 0 PD V H
57
// PD=PowerDown 0=Chip active - 1=CHip in PowerDown
58
// V=Vertical-Mode 0=Horizontal-Adressing - 1=Vertical Adressing
59
// H=0 Basic Instruction H=1 Extended Instruction
60
// => PD=0 V=0 H=0    => 0010 0000 = 0x20
61
#define Disp_FunctionSet 0x20
62
#define Disp_FunctionSet_H 0x21
63

64
//      BankX = 0 1 0 0 0 Y2 Y1 Y0
65
#define Bank0 0x40
66
#define Bank1 0x41
67
#define Bank2 0x42
68
#define Bank3 0x43
69
#define Bank4 0x44
70
#define Bank5 0x45
71

72
// Display-Control bei DC=0=Command    0000 1D0E
73
// und H=0
74
// Blank               D=0 E=0       = 0000 1000 = 0x08
75
// Normal-Mode         D=1 E=0       = 0000 1100 = 0x0C
76
// All-Displaysegments D=0 E=1       = 0000 1001 = 0x09
77
// Invers              D=1 E=1       = 0000 1101 = 0x0D
78
#define Disp_Ctrl_Blank 0x08
79
#define Disp_Ctrl_Norm  0x0C
80
#define Disp_Ctrl_All   0x09
81
#define Disp_Ctrl_Inv   0x0D
82

83
/* USER CODE END PM */
84

85
/* Private variables ---------------------------------------------------------*/
86
SPI_HandleTypeDef hspi1;
87

88
/* USER CODE BEGIN PV */
89
HAL_StatusTypeDef spi1_status;
90
/* USER CODE END PV */
91

92
/* Private function prototypes -----------------------------------------------*/
93
void SystemClock_Config(void);
94
static void MX_GPIO_Init(void);
95
static void MX_SPI1_Init(void);
96

97
/* USER CODE BEGIN PFP */
98
void myDelay(unsigned long delay);
99
void LCD_Reset(void);
100
void Test_LCD(void);
101
void Write_Data(uint8_t v);
102
/* USER CODE END PFP */
103

104
/* Private user code ---------------------------------------------------------*/
105
/* USER CODE BEGIN 0 */
106

107
/* USER CODE END 0 */
108

109
/**
110
  * @brief  The application entry point.
111
  * @retval int
112
  */
113
int main(void)
114
{
115
  /* USER CODE BEGIN 1 */
116

117
  /* USER CODE END 1 */
118

119
  /* MCU Configuration--------------------------------------------------------*/
120

121
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
122
  // Schön wärs, aber dann läuft der Debugger nich...
123
  // auskommentiert und damit gehts weiter.
124
  //HAL_Init();
125

126
  /* USER CODE BEGIN Init */
127

128
  /* USER CODE END Init */
129

130
  /* Configure the system clock */
131
  SystemClock_Config();
132

133
  /* USER CODE BEGIN SysInit */
134

135
  /* USER CODE END SysInit */
136

137
  /* Initialize all configured peripherals */
138
  MX_GPIO_Init();
139
  MX_SPI1_Init();
140

141
  /* USER CODE BEGIN 2 */
142
  uint8_t k=0,k1=0;
143
  LCD_Reset();
144
  LCD_CS_Hi();              // CS auf High damit LCD deaktiviert
145
  Test_LCD();
146
  LED_Off();
147
  /* USER CODE END 2 */
148

149
  /* Infinite loop */
150
  /* USER CODE BEGIN WHILE */
151
  LCD_Data();      //D/C = High => Data
152

153
  while (1)
154
  {
155
    /* USER CODE BEGIN 3 */
156
    LED_Off();
157
    myDelay(500000);
158
    LED_On();
159
    myDelay(500000);
160
    k+=1;
161
    if (k >= 0x1F) { k = 0; }
162
    k1 = k & 0x1F;     // vordere 3 Bits ausblenden sonst inverse Darstellung
163
    //k1=0x1F;
164
    Write_Data(k1);
165

166
    /* USER CODE END 3 */
167
  }
168
  /* USER CODE END WHILE */
169
}
170

171
/**
172
  * @brief System Clock Configuration
173
  * @retval None
174
  */
175
void SystemClock_Config(void)
176
{
177
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
178
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
179

180
  /** Initializes the CPU, AHB and APB busses clocks 
181
  */
182
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
183
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
184
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
185
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
186
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
187
  {
188
    Error_Handler();
189
  }
190
  /** Initializes the CPU, AHB and APB busses clocks 
191
  */
192
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
193
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
194
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
195
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
196
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
197
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
198

199
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
200
  {
201
    Error_Handler();
202
  }
203
}
204

205
/**
206
  * @brief SPI1 Initialization Function
207
  * @param None
208
  * @retval None
209
  */
210
static void MX_SPI1_Init(void)
211
{
212

213
  /* USER CODE BEGIN SPI1_Init 0 */
214

215
  /* USER CODE END SPI1_Init 0 */
216

217
  /* USER CODE BEGIN SPI1_Init 1 */
218

219
  /* USER CODE END SPI1_Init 1 */
220
  /* SPI1 parameter configuration*/
221
  hspi1.Instance = SPI1;
222
  hspi1.Init.Mode = SPI_MODE_MASTER;
223
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
224
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
225
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
226
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
227
  hspi1.Init.NSS = SPI_NSS_SOFT;
228
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
229
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
230
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
231
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
232
  hspi1.Init.CRCPolynomial = 7;
233
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
234
  {
235
    Error_Handler();
236
  }
237
  /* USER CODE BEGIN SPI1_Init 2 */
238

239
  /* USER CODE END SPI1_Init 2 */
240

241
}
242

243
/**
244
  * @brief GPIO Initialization Function
245
  * @param None
246
  * @retval None
247
  */
248
static void MX_GPIO_Init(void)
249
{
250
  GPIO_InitTypeDef GPIO_InitStruct = {0};
251

252
  /* GPIO Ports Clock Enable */
253
  __HAL_RCC_GPIOA_CLK_ENABLE();
254
  __HAL_RCC_GPIOB_CLK_ENABLE();
255
  __HAL_RCC_GPIOC_CLK_ENABLE();
256

257
  /*Configure GPIO pin Output Level */
258
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
259

260
  /*Configure GPIO pin Output Level */
261
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_12, GPIO_PIN_RESET);
262

263
  /*Configure GPIO pin : PB2 */
264
  GPIO_InitStruct.Pin = GPIO_PIN_2;
265
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
266
  GPIO_InitStruct.Pull = GPIO_NOPULL;
267
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
268
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
269

270
  /*Configure GPIO pins : PC7 PC10 PC12 */
271
  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_12;
272
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
273
  GPIO_InitStruct.Pull = GPIO_NOPULL;
274
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
275
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
276

277
  /*Configure GPIO pin : PA5 PA7  war nicht notwendig LCD geht trotzdem nicht*/
278
  GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_7;
279
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
280
  //GPIO_InitStruct.Pull = GPIO_NOPULL;
281
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
282
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
283
  //GPIO_PinRemapConfig(GPIO_Remap_SPI1, DISABLE);
284
}
285

286
/* USER CODE BEGIN 4 */
287
/**-------------------------------------------------------------------------
288
  * @brief  This function is to delay some seconds.
289
  * @retval None
290
  * ------------------------------------------------------------------------
291
  */
292
void myDelay(unsigned long delay)
293
{
294
   while(delay)
295
   {
296
      delay=delay-1;
297
      if (delay == 0) break;
298
      asm volatile ("nop");
299
   }
300
}
301

302
void LCD_Reset(void)
303
{
304
    LCD_CS_Lo();             // Enable auf High damit LCD aktiviert
305
    LCD_Reset_Lo();
306
    myDelay(10000);          // RST f. 10us auf Low dann wieder High
307
    LCD_Reset_Hi();
308
    LCD_CS_Hi();
309
}
310

311
void Test_LCD(void)
312
{
313
    uint8_t k1=0;
314

315
    LCD_Command();    // D/C = Low => Command
316
    Write_Data(Disp_FunctionSet_H);
317
    k1=0x90;
318
    Write_Data(k1);
319
    Write_Data(Disp_FunctionSet);
320
    Write_Data(Disp_Ctrl_Inv);
321
}
322

323
void Write_Data(uint8_t v)
324
{
325
    uint8_t k1=0;
326
    uint32_t timeout=2,error;
327

328
    //PCD8544_CS_L();
329
    //PCD8544_DATA();
330
    //SPI_I2S_SendData(SPI1, Data);
331
    //while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
332
    //PCD8544_CS_H();
333
    LCD_CS_Lo();    // LCD aktivieren
334
    k1 = v;
335
    spi1_status = HAL_SPI_Transmit(&hspi1,&k1,1,timeout);
336
    while(spi1_status == HAL_BUSY);
337
    LCD_CS_Hi();    // LCD deaktivieren
338
    error = HAL_SPI_GetError(&hspi1);
339
    if (error != 0)
340
    {
341
        Error_Handler();
342
    }
343
    myDelay(100);
344
}
345

346
/* USER CODE END 4 */
347

348
/**
349
  * @brief  This function is executed in case of error occurrence.
350
  * @retval None
351
  */
352
void Error_Handler(void)
353
{
354
  /* USER CODE BEGIN Error_Handler_Debug */
355
  /* User can add his own implementation to report the HAL error return state */
356
    int i=1;
357
    for (i=1;i<=5;i++)
358
    {
359
        /* USER CODE BEGIN 3 */
360
        LED_Off();
361
        myDelay(50000);
362
        LED_On();
363
        myDelay(50000);
364
        /* USER CODE END 3 */
365
    }
366
    myDelay(500000);
367

368
  /* USER CODE END Error_Handler_Debug */
369
}
370

371
#ifdef  USE_FULL_ASSERT
372
/**
373
  * @brief  Reports the name of the source file and the source line number
374
  *         where the assert_param error has occurred.
375
  * @param  file: pointer to the source file name
376
  * @param  line: assert_param error line source number
377
  * @retval None
378
  */
379
void assert_failed(uint8_t *file, uint32_t line)
380
{ 
381
  /* USER CODE BEGIN 6 */
382
  /* User can add his own implementation to report the file name and line number,
383
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
384
  /* USER CODE END 6 */
385
}
386
#endif /* USE_FULL_ASSERT */
387

388
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Gast #5992733
Lesenswert?

> Ich hab schon alles versucht aber das LCD-Display läßt sich
> einfach nicht ansprechen.

Das ist eine Menge Quelltext mit einer noch viel größeren Menge 
Framework dahinter, welches nach meiner Erfahrung oft fehlerhaft ist 
(insbesondere was die STM32F1 Serie angeht).

Aber ich will Dir die HAL nicht madig machen, besser konstruktive 
Ratschläge geben. Das heisst in diesem Fall, Strukturiert vorgehen.

Zuerstmal solltest du mit einem Messgerät (z.B. Logic Analyzer) klären, 
was auf der SPI Schnittstelle passiert. Tut sich überhaupt irgend etwas? 
Und du solltest Unterbrechungspunkte in die Errorhandler setzen um 
nachzuschauen, welche Fehlercodes die HAL meldet. Dann suchst du die 
Erklärungen zu diesen Codes heraus.

Was ist mit deiner LED, blinkt die wenigstens regelmäßig alle 500ms?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren