본문 바로가기

[STM32F746G-DISCO] SPI 사용하기 (feat. OLED)

by rudals.kim 2024. 7. 6. 댓글 개
반응형
아래 테스트는 STM32CubeIDE 1.6.1/STM32Cube_FW_F7_V1.16.1를 사용하여 테스트 되었습니다.


이번에는 STM32F746G-DISCO 보드의 SPI 인터페이스를 사용하여 SSD1306 드라이버를 사용하는 OLED를 테스트해 보았습니다.

사용될 OLED는 아래와 같은 형태인데 GND, VCC, D0(SCK), D1(MOSI), RES, DC, CS 총 7개의 핀으로 구성되어져 있습니다.

우선 회로도에서 SPI 관련 포트를 살펴보았습니다.

 

STM32F746G-DISCO 보드 뒷면에는 아두이노 우노의 컨넥터가 있는데 이 컨넥터로 SPI2 인터페이스가 미리 할당되어져 있어서 이 포트를 사용하면 SPI 테스트를 할 수 있습니다.

 

디스플레이용 라이브러리는 이전 테스트와 동일한 u8glib을 사용할 예정이며 SPI에서 사용되어질 CS/DC/RST를 위해 D9/D8/D7 3개 포트를 GPIO로 할당하였습니다.

STM32CubeIDE에서 새 프로젝트를 생성 후 핀 초기화 후 SYS/USART1/SPI2 부분만 설정하였습니다.

GPIO와 SPI2 설정은 아래와 같이 설정하였습니다.

이전에 사용되어진 u8glib 라이브러리는 I2C만 고려되어 있어서 SPI를 사용하려면 하드웨어 관련 코드를 추가해 줘야 합니다. u8g_arm.c 파일 마지막에 아래 코드를 추가하였습니다. (DC/CS/RST관련 코드가 추가되어졌습니다.)

uint8_t u8g_com_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
	switch(msg)
	{
	case U8G_COM_MSG_STOP:
		break;
	case U8G_COM_MSG_INIT:
		u8g_MicroDelay();
		break;
	case U8G_COM_MSG_ADDRESS:
		u8g_10MicroDelay();
		HAL_GPIO_WritePin(DC_PORT, DC, arg_val);
		u8g_10MicroDelay();
		break;
	case U8G_COM_MSG_CHIP_SELECT:
		if ( arg_val == 0 )
			HAL_GPIO_WritePin(CS_PORT, CS, GPIO_PIN_SET);
		else
			HAL_GPIO_WritePin(CS_PORT, CS, GPIO_PIN_RESET);
		break;
	case U8G_COM_MSG_RESET:
        HAL_GPIO_WritePin(RST_PORT, RST, arg_val);
		break;
	case U8G_COM_MSG_WRITE_BYTE:
		HAL_SPI_Transmit(&SPI_HANDLER, &arg_val, 1, 10000);
		while(HAL_SPI_GetState(&SPI_HANDLER) != HAL_SPI_STATE_READY);
		u8g_MicroDelay();
		break;
	case U8G_COM_MSG_WRITE_SEQ:
	case U8G_COM_MSG_WRITE_SEQ_P:
	{
		HAL_SPI_Transmit(&SPI_HANDLER, (uint8_t *)arg_ptr, arg_val, 10000);
		while(HAL_SPI_GetState(&SPI_HANDLER) != HAL_SPI_STATE_READY);
		u8g_MicroDelay();
		arg_val = 0;
	}
	break;
	}
	return 1;
}


main 함수에 u8glib의 SPI용 초기화 코드를 추가합니다.

/* USER CODE BEGIN 2 */
u8g_InitComFn(&u8g, &u8g_dev_ssd1306_128x64_sw_spi, u8g_com_hw_spi_fn);
/* USER CODE END 2 */


OLED에 디스플레이될 draw함수를 추가합니다.

void draw(void)
{
  u8g_DrawFrame(&u8g, 0, 0, 128, 64);
  u8g_SetFont(&u8g, u8g_font_fixed_v0);
  u8g_DrawStr(&u8g, 2, 12, "STM32F746G-DISCO");
  u8g_DrawHLine(&u8g, 0, 14, 128);
  u8g_DrawStr(&u8g, 2, 32, "SPI2 Test by rudalskim");
  u8g_DrawStr(&u8g, 2, 52, "rudalskim.tistory.com");
}


main 함수의 while문에 아래 코드를 추가하여 OLED에 디스플레이되도록 합니다.

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    u8g_FirstPage(&u8g);
    do {
      draw();
    } while ( u8g_NextPage(&u8g) );
    u8g_Delay(10);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

 

회로 구성은 아래와 같이 연결하였습니다. 소스를 빌드 후 실행해 보면 잘 동작됩니다.

SPI2 인터페이스를 사용하여 OLED가 정상 동작됨을 확인하였습니다.

반응형

댓글