이번에는 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가 정상 동작됨을 확인하였습니다.
'Hardware > STM32' 카테고리의 다른 글
[STM32F746G-DISCO] ADC 사용하기 (0) | 2024.07.07 |
---|---|
[STM32F746G-DISCO] RCC (Reset and Clock Control) (0) | 2024.07.07 |
[STM32F746G-DISCO] I2C 사용하기 (feat. OLED) (0) | 2024.07.06 |
[STM32F746G-DISCO] I2C 사용하기 (feat. 터치스크린) (0) | 2024.07.05 |
[STM32F746G-DISCO] USART 사용하기 (1) | 2024.07.05 |
댓글