본문 바로가기

GUI

STM32F030R8로 Sharp memory LCD 사용하기

블루투스 공부때문에 오랬동안 미루어 두었던 GUI에 대해 공부해 보려고 합니다. 하드웨어는 STM32와 Sharp memory LCD를 사용할 예정이지만 그래픽 라이브러리는 이번에 사용된 MSP Graphic Library가 아니라 윈도우 기능이 있는 uGUI 또는 micro-GUI를 공부할 예정입니다. 따라서 이번 실습은 메모리 LCD 사용 방법과 그래픽 라이브러리에 대해 약간의 느낌만 가져가는 것에 초점을 맞췄습니다.


MCU는 STM32 제품을 선택했습니다. STM32에선 STM32CubeMX라는 아주 훌륭한 코드 생성기를 제공하기 때문입니다. 핀과 페리페럴 설정을 그래픽으로 확인할 수 있습니다. 시리얼 통신을 공부할 때 STM32를 사용했었는데, 오랜만에 다시 써보네요.


IDE는 TrueStudio를 사용했습니다. 얼마전 TrueStudio를 STM32에서 인수하면서 Pro 기능도 무료로 쓸 수 있게 되었습니다.


구성요소

  1. 430BOOST-SHARP96 (Sharp memory LCD 96x96)
  2. NUCLEO-F030R8 (STM32F030R8)
  3. MSP Graphic Library

430BOOST-SHARP96 모듈은 TI사에서 MSP-EXP430F5529LP (MSP430F5529) 개발 보드의 전용 LCD 모듈로 만든 것입니다. 물론 그래픽 라이브러리가 포팅된 예제도 함께 제공됩니다. 하지만 MSP430F5529 MCU는 MSP430 코어가 사용되었고 제가 공부한 것은 Cortex-M 아키텍쳐입니다. MSP-EXP430F5529LP 보드 가격은 비싸진 않지만 배송되기까지 기다리기 싫었고, 별로 쓰지도 않을 것같은 MSP430 아키텍쳐까지 새로 공부하기도 싫었습니다. 그래서 옛날에 사용했던 NUCLEO-F030R8 (STM32F030R8) 보드를 대신 사용하기로 했습니다.


STM32의 SPI는 MSP430의 SPI보다 훨씬 다양한 기능을 제공합니다. 하지만 위에서 언급했다시피 이번 실습은 느낌만 알고 빠르게 넘어갈 것입니다. 그래서 STM32의 SPI의 추가기능을 사용하여 없앨 수 있는 MSP-EXP430F5529LP 예제 코드를 거의 그대로 사용했습니다. 예를들면, Sharp memory LCD는 SPI로 시리얼 데이터를 수신할 때 LSB부터 인식합니다. 하지만 Cortex-M과 MSP430 아키텍쳐를 포함한 대부분의 임베디드 아키텍쳐는 데이터 프레임을 시리얼로 전송할 때 기본적으로 MSB부터 전송합니다. STM32의 SPI는 LSB부터 전송할 수 있는 옵션을 제공합니다. 반면 MSP430은 그렇지 않습니다. 따라서 EXP430F5529LP 예제 코드는 LCD 버퍼의 비트를 변경할 때마다 비트 반전을 고려하고 있습니다. 또한 STM32의 SPI는 TX 버퍼가 있고, 이것을 쉽게 사용할 수 있는 HAL 드라이버도 제공합니다. 예를들면 HAL_SPI_Transmit 함수의 세번째 파라미터에서 전송할 데이터의 수를 미리 설정하여 불필요한 코드를 최소화할 수도 있습니다. 하지만 위에서 언급한 이유로 그냥 1로 설정했습니다.


예전에 uGUI 코드를 잠깐 본적이 있습니다. uGUI는 LCD 버퍼를 변경할 때 모든 그래픽 처리함수가 LCD 버퍼를 변경할 때, 단 하나의 함수만 공통적으로 사용했던 것으로 기억합니다. 하지만 MSP Graphic Library는 LCD 버퍼를 변경할 때 선을 그리는 함수, 사각형을 그리는 함수 등 6개의 함수를 만들어 주어야 합니다. 잠깐 맛보기로만 보고갈 건데 STM32에 모두 최적화하기에는 시간과 노력이 아까웠습니다.


1. 430BOOST-SHARP96 (Sharp memory LCD 96x96)

주의할 것은 대부분의 SPI 모듈은 CS(Chip Select)핀이 High일 때 유휴 상태로 인식하고, Low일 때 Select 상태로 인식하지만, Sharp memory LCD의 SPI는 CS가 High일 때 Select된 것으로 인식합니다. STM32의 SPI는 전송을 시작할 때 하드웨어가 자동으로 CS 핀을 High에서 Low로 만들어주는 기능을 제공합니다. EXP430F5529LP 포팅 코드는 임의의 GPIO 핀을 선택해서 SPI로 데이터를 전송하기 전에 직접 GPIO 핀을 직접 변경해 줍니다. 처음엔 이것을 지우고 STM32CubeMX를 사용하여 STM32 SPI가 제공하는 자동 CS 기능을 사용(STM32 SPI1_CR1::SSM=0, SPI_CR2::SSOE=1)했습니다. 작동하지 않았습니다. 하지만 재부팅할 때마다 다른 출력을 보여주었기 때문에 LCD 버퍼를 그대로 사용한 것 때문에 발생한 오류로는 생각되지 않았습니다. 다시 프로그래밍 노트(PDF)를 자세히 살펴보니 Sharp memory LCD는 특이하게도 CS가 High일 때 Select된 것으로 인식했습니다. 그래서 CS를 위한 GPIO를 따로 만들고 수동으로 설정해 주니 제대로 작동했습니다.


그리고 메모리 LCD는 전력 소모가 매우 적기때문에 GPIO 출력을 사용하여 전력을 공급할 수 있습니다. STM32F030R8의 데이터시트를 보면 I/O 출력 전류가 25mA까지는 안정적으로 공급할 수 있다고 나와 있습니다. Sharp memory LCD의 프로그래밍 노트를 보면 SPI 전송속도가 2MBits/s일 때 피크 전류가 0.36mA이고 평균 22~25uA 정도의 전류만 사용(정말 엄청나게 적은 전류 소모입니다. 그래서 200mAh 배터리로도 LCD를 켜놓고 사용할 수 있습니다.)됩니다. 그리고 어차피 430BOOST-SHARP96 모듈에서 조차 모듈의 VCC와 LCD의 VDD의 연결이 끊어져 있습니다. 대신 모듈의 VCC 아래 있는 LCD Power Control에 GPIO 핀을 연결하여 전력을 공급할 수 있습니다. 


또한 보통 LCD와는 달리 Sharp memory LCD는 VCOM을 최소 초당 1초에 한번씩 토글시켜 주어야 합니다. 메모리 LCD 패널에 DC 바이어스가 쌓이는데 외부에서 VCOM을 토글하여 풀어준다고 합니다만 자세히는 모르겠습니다. 아무튼 VCOM을 토글하는 방법은 두가지가 있습니다. 첫번째는 외부에서 LCD의 EXTCOMIN 핀에 펄스를 공급하는 방식이고, 두번째는 명령어의 V비트를 통해 VCOM을 특정 값으로 변경하도록 Sharp memory LCD에 요청하는 방법입니다. 즉, 두번째 방법은 VCOM을 바꾸기 위해 SPI 신호선이 사용됩니다. 이것은 LCD의 EXTMODE 핀을 설정하여 바꿀 수 있습니다. High인 경우 첫번째 방법이, Low인 경우 두번째 방법이 사용되는 것으로 인식합니다. 430BOOST-SHARP96 모듈은 기본적으로 GND에 연결되어 있고, 따로 칩 레지스터를 납땝하여 설정을 변경할 수 있습니다. 저는 그대로 사용했습니다.

예전에 SPI에 대해 공부했을 때는 노키아5110 LCD 모듈로 공부했었습니다. 그때는 SPI 자체가 목표였기 때문에 LCD에 사각형을 그리고 오실로스코프로 파형을 관찰했을 뿐, GUI는 사용하지 않았습니다. 미리 데이터를 정의하고 SPI를 사용하여 전송만 했습니다. 그래서 기억은 잘 안나지만 노키아5110은 각 픽셀마다 주소가 할당되고, 원하는 픽셀만을 수정할 수 있었던 것으로 기억합니다. 하지만 메모리 LCD는 주소가 픽셀이 아닌 라인에 할당되기 때문에 픽셀 하나만 수정하려고 해도 라인 전체가 다시 전송되어야 합니다. 하지만 MSP Graphic Library는 화면을 갱신할 때 항상 전체 프레임을 전송했고, 저도 그대로 사용했습니다. 수정된 부분만 전송하기 위한 방법은 micro-GUI나 uGUI를 공부할 때 생각해 봐야 겠습니다.


2. NUCLEO-F030R8 (STM32F030R8)

핀 설정은 다음과 같습니다.

3. MSP Graphic Library

STM32의 HAL 드라이버가 다른 모듈 또는 페리페럴과 독립적으로 사용될 수 있도록 레지스터를 관리해주기 때문에 EXP430F5529LP 포팅 코드에서 사용된 인터럽트 또는 대기(Delay)관련 코드와 함수를 모드 제거했습니다.


코드 GitHub


결과