MCU
STM32F103(ST)
IDE
Atollic(TrueSTUDIO), STM32CubeMX
목표
위 MCU와 IDE 환경에서 개발을 위한 MCU 기본 설정

 

1. STM32CubeMX 실행

 

- New Project

 

- Part Number Search : STM32F103C8-LQFP48

 

- Start Project

 

- Pinout 설정

- Peripheral Tree에서 설정

- Pin을 직접 설정

 

2. SYS(ST-LINK 사용을 위해서는 설정해야 함, ISP mode 사용시 필요 없으며 ISP mode 사용 방법은 다른 곳에서 설명)

- 'Pinout & Configuration' Tab으로 이동

1) System Core 선택

2) SYS 선택

- Debug : Serial Wire(SWD) 선택

- PA13(SWDIO), PA14(SWCKL)에 자동 할당(녹색으로 표시)

 

3. Clock Configuration(HSE) 설정

- 'Pinout & Configuration' Tab으로 이동

1) System Core 선택

2) RCC(Reset and Clock Control) 항목 선택

- High Speed Clock(HSE) : Crystal/Ceramic Resonator 선택

- PD0-OSC_IN(RCC_OSC_IN), PD1-OSC_OUT(RCC_OSC_OUT) 자동 할당(녹색 표시 )

- 'Clock Configuration' Tab으로 이동

1) PLL Source Mux : HSE 선택

2) HCLK : 64(MHz) 입력

 

4. Clock Configuration(LSE) 설정

- 'Pinout & Configuration' Tab으로 이동

1) System Core 선택

2) RCC(Reset and Clock Control) 항목 선택

- Low Speed Clock(LSE) : Crystal/Ceramic Resonator 선택

- PC14-OSC32_IN(RCC_OSC32_IN), PC15-OSC32_OUT(RCC_OSC32_IN) 자동 할당(녹색 표시)

- 'Clock Configuration' Tab으로 이동

1) RTC Clock Mux : LSE 활성화 안됨

 

5. RTC 설정

- 'Pinout & Configuration' Tab으로 이동

1) Timers 선택

2) RTC(Real Time Clock) 항목 선택

- Activate Clock Source 체크

- RTC OUT : No RTC Output 선택

 (RTC OUT = Disable 설정은 내부적으로 PC13 핀 기능을 RTC용으로 막아버림

  RTC OUT = No RTC Output 설정은 RTC는 켜두되, PC13 핀은 일반 GPIO로 열어줌)

- Tamper 설정시 PC13(LED Port) 기능 제한

- 'Clock Configuration' Tab으로 이동

1) RTC Clock Mux : LSE 선택

- RTC 기능 설정 후 LSE 선택 가능

 

6. 'Project Manager' Tab

1) Project Name 입력

2) Toolchain / IDE 선택 : 여기서는 TrueSTUDIO 선택

※ Toolchain / IDE를 TrueSTUDIO가 아닌 다른것으로 선택하고 GENERATE CODE를 한번이라도 하면

Toolchain을 TrueSTUDIO로 다시 선택해도 ATOLLIC에서 Build가 안되는 경우가 있으니,

위 같은 실수를 했을 경우 생성된 source를 지우고 다시 GENERATE CODE 할것을 권장함

3) GENARATE CODE 클릭

 

 

 

'ST > STM32F103C8' 카테고리의 다른 글

STM32F103C8 - UART(DMA)  (3) 2025.08.08
STM32F103C8 - UART(Interrupt)  (1) 2025.08.08
STM32F103C8 - UART(Polling)  (1) 2025.08.08
STM32F103C8 - GPIO(EXTI)  (2) 2025.08.08
STM32F103C8 - GPIO  (0) 2025.08.08

 

리눅스 기반 임베디드 플랫폼 선택을 위한 SoC/MPU 비교표
성능, 실시간 처리, 보급성 기준으로 보는 리눅스 기반 SoC/MPU 비교 가이드
항목
Raspberry Pi CM5
STM32MP1
(ST)
i.MX 8M Mini(NXP)
AM64x
(TI)
PIC64GX
(Microchip)
CPU
ARM Cortex-A76 (4x) @ 2.0GHz
Cortex-A7 (2x) + M4
Cortex-A53 (4x) @ 1.8GHz
Cortex-A53 (2x) + R5F (2x)
RISC-V 64bit (4x AMP)
GPU

VideoCore VII
Vivante GPU
GC NanoUltra
X
없음
AI/ML

O (NEON, GPU 연산)
X
O (NEON)
O (DSP, 옵션)
△ (기본 수준)
리눅스

O (Pi OS, Ubuntu 등)
O
O
O
O (Yocto, Buildroot 등)
RTOS 동시 지원 (AMP)
X
O
X
O
O (Linux + RTOS 병행 실행)
RAM 용량

4~8GB LPDDR4
512MB~1GB DDR3
1~4GB LPDDR4
1~2GB
DDR4
최대 8GB DDR4 (예정)
스토리지

eMMC
(최대 32GB)
eMMC
eMMC
eMMC
eMMC, NAND/NOR
보안 부팅

X
O
O (보안 부팅, 키 관리, PMP 등)
디스플레이 지원

HDMI, DSI, CSI
병렬 RGB LCD
MIPI DSI
X
HDMI, MIPI CSI
TSN 지원

X
X
X
O
O (HX 시리즈)
FPGA 포함 여부

X
X
X
X
O (단, PolarFire SoC와 핀 호환)

 

주요 고성능 임베디드 SoC/MPU 기술 분석
리눅스 기반 SoC 및 멀티코어 MPU의 비교 분석

1. Raspberry Pi CM5

  • 용도: 프로토타이핑, 소형 서버, 엣지 컴퓨팅, HMI, 교육용 리눅스 디바이스
  • 개발환경: Debian 기반 Raspberry Pi OS. Python/C/C++, VS Code 원활.
  • 툴체인: GCC (arm64), 대부분 오픈소스 지원 풍부
  • 커널/드라이버: VideoCore GPU, V4L2, CSI/DSI, SPI/I2C 풍부. 메인라인 진행 중.
  • 보드 설계: Compute Module 형태로, PCIe/HDMI/USB 분리 설계 필요. 고속 신호 설계 요구됨.
  • 보안 기능: 기본 Secure Boot 없음. Trusted Platform 지원은 부족.
  • RTOS/AMP: 리눅스 단독 운영에 최적. RTOS 병행 구조 미지원.
  • 온도/수명: 표준 소비자 제품 온도 등급. 공급 일정 불안정 이슈 있음.
  • 생태계: 포럼/서드파티 풍부. 모듈(SOM) 수 많음.
  • 실사용 사례: 미디어 처리 장비, 스마트 카메라, 3D 프린터 컨트롤러 등

 

→ 유연한 개발 환경과 뛰어난 커뮤니티 지원 및 가격이 가장 저렴. 산업용 환경에선 보안이나 실시간 요구가 아쉬움.

 

 

2. STM32MP1 (ST)

  • 용도: 디스플레이 제어, HMI, 터치 UI, 복합 제어기기
  • 개발환경: STM32CubeMX, OpenSTLinux, Yocto 기반 SDK, Qt 등 UI 지원
  • 툴체인: GCC, STM32CubeIDE, Buildroot
  • 커널/드라이버: DSI, LVDS, I2C, ADC 등 전통 STM32 주변장치 대부분 지원
  • 보드 설계: 중간 난이도. DDR3L, PMIC 통합. 2/4층 설계 가능
  • 보안 기능: TrustZone, Secure Boot, HW RNG 등 존재
  • RTOS/AMP: Cortex-M4 내장. FreeRTOS 병행 운영 매우 쉬움
  • 온도/수명: 산업용 온도, 10년 공급 보장
  • 생태계: STM32 시리즈의 방대한 커뮤니티와 유틸리티 활용 가능
  • 실사용 사례: 산업용 UI 패널, 터치 제어기, 휴대용 검사 장비

 

→ 소형 제어기기와 디스플레이 기반 UI에 적합한 특성을 가지고 있으며, 산업용에 최적화된 솔루션을 제공

 

 

3. NXP i.MX 8M Mini (NXP)

  • 용도: 스마트 홈, 오디오 기기, 카메라 허브, 미디어 디바이스
  • 개발환경: Yocto 기반 Linux SDK (NXP 제공). Qt 등 UI 프레임워크 지원.
  • 툴체인: GCC, Yocto Toolchain. 개발 레벨 높지만 확장성 뛰어남.
  • 커널/드라이버: Vivante GPU, CSI, I2S, MIPI DSI 드라이버 등 안정적.
  • 보드 설계: PMIC 권장, LPDDR 인터페이스 설계 난이도 있음.
  • 보안 기능: TrustZone, CAAM, Secure Boot, OTP 키 영역 제공.
  • RTOS/AMP: Cortex-M4 내장. FreeRTOS와 AMP 구성에 적합.
  • 온도/수명: 산업용 등급 및 10~15년 장기공급.
  • 생태계: Toradex/Variscite 등 SOM 업체 다수.
  • 실사용 사례: 구글 스마트 스피커, 오디오앰프, 산업 UI 디바이스

 

→ 스마트 홈이나 미디어 디바이스에 강점을 보이며, 보안 측면에서도 안정적인 성능을 발휘. 보통 SOM 형태로 사용하며 가격이 다른 제품 대비 비쌈

 

 

4. AM64x (TI)

  • 용도: 산업용 게이트웨이, 리얼타임 제어기, 공장 자동화 장비
  • 개발환경: TI SDK (Yocto 기반), CCS IDE, PDK, SysConfig 등 잘 갖춰짐
  • 툴체인: GCC, TI Clang. RTOS, Linux 병행 빌드 지원
  • 커널/드라이버: TSN, PRU, EtherCAT, CAN, USB 안정성 높음
  • 보드 설계: DDR4/PCIe, 산업 인터페이스 설계 필요. 하드웨어 요구 높은 편
  • 보안 기능: TrustZone, HSM, Secure Boot, Firewall 등 강력
  • RTOS/AMP: R5F 코어 + Cortex-A53 구조. Linux + RTOS AMP 구조 이상적
  • 온도/수명: -40~105°C, 10년 이상 공급 보장
  • 생태계: TI E2E, 산업 고객사 다수, 모듈 업체도 있음
  • 실사용 사례: 이더넷 스위치, 로봇 제어기, 산업 HMI

 

→ 산업용 리얼타임 제어와 보안에서 뛰어난 성능을 발휘하며, 장기적인 공급 안정성까지 확보된 제품

 

 

5. PIC64GX (Microchip)

  • 용도: 보안 네트워크 장비, 병렬 신호 처리, 엣지 분석 장비 등 (예정)
  • 개발환경: MPLAB X IDE, Harmony SDK 예정. 툴 지원은 ARM보다 제한적.
  • 툴체인: GCC for RISC-V, LLVM. 일부 전용 툴 필요 가능성 있음.
  • 커널/드라이버: 리눅스 커널 포팅 중. 초기 단계, 주변장치 드라이버 불안정 가능.
  • 보드 설계: 아직 공식 설계 자료 많지 않음. 하드웨어 사양 미확정.
  • 보안 기능: RISC-V PMP, Crypto 엔진 탑재 예정. Secure Boot 포함.
  • RTOS/AMP: RTOS 호환 구조 예상. 병렬 처리용 RT Core 내장.
  • 온도/수명: Microchip 특성상 산업용 등급 및 10년 이상 공급 예상.
  • 생태계: 시작 단계. 커뮤니티 제한적.
  • 실사용 사례: 아직 없음. 산업용 보안 게이트웨이 기대됨.

 

→ 아직 초기 단계에 있어 실제 활용 사례나 툴체인과 라이브러리 지원 부. RISC-V 기반 신기술을 고려할 때 중간 이상의 가격을 예상.

 

 

요약

- 임베디드 SoC/MPU 비교는 각 칩셋의 특성과 장단점을 정리해 보았는데, 실제 제품 개발에 있어서 선택에 도움이 되고자 함

- 각 제품은 고유의 장점과 특화된 용도가 있기 때문에, 무엇보다 사용할 애플리케이션과 요구사항에 맞는 최적의 SoC/MPU를 선택하는 것이 가장 중요

 

 

'ST > MCU' 카테고리의 다른 글

ST Stellar(스텔라) 32-bit automotive MCU  (1) 2025.04.24
MCU(4) - NXP  (0) 2025.03.17
MCU(3) - Infineon  (0) 2025.03.17
MCU(2) - TI  (0) 2025.03.17
MCU(1) - ST  (0) 2025.03.17

https://www.st.com/en/automotive-microcontrollers/stellar-32-bit-automotive-mcus.html

 

Stellar 32-bit automotive MCUs - STMicroelectronics

Discover STMicroelectronics' Stellar 32-bit automotive MCUs, providing high performance and reliability for automotive systems.

www.st.com


Stellar MCU + xMemory의 주요 장점

1. 동적으로 재구성 가능한 메모리 구조

  • 기존 MCU에서는 메모리 맵이 고정되어 있어, 펌웨어가 굽히면 메모리 영역이 변하지 않음. 즉, 코드와 데이터 영역을 고정하고, 추가적인 메모리가 필요하면 새로운 MCU로 교체하거나 기존 메모리를 덮어써야 함
  • Stellar xMemory는 소프트웨어로 메모리 맵을 동적으로 재구성 가능
  • 예를 들어, 기존 코드 영역을 데이터 저장 공간으로 바꿀 수 있고, 필요한 메모리 용량을 소프트웨어적으로 늘리거나 줄일 수 있음
  • 프로그램을 굽고 나서도 메모리 구조를 자유롭게 변경 가능하며, 기능 추가나 업데이트 시 메모리 구성을 유연하게 바꿀 수 있어 향후 변화에 더 잘 대응할 수 있음

 

2. 소프트웨어 정의 차량(SDV)에 최적화

  • Stellar MCU는 **소프트웨어 정의 차량(SDV)**의 요구사항을 충족하도록 설계. 하드웨어 변경 없이 소프트웨어로 기능을 변경하거나 업데이트 가능.
  • 예를 들어, 차량이 출시된 후에도 새로운 기능을 소프트웨어로 추가하거나, 버그를 수정하거나 성능을 최적화하는 것이 소프트웨어적으로 가능
  • 하드웨어를 교체하지 않고도 다양한 기능을 소프트웨어로만 확장 가능하고, 이는 OTA(Over-the-Air) 업데이트로 쉽게 수행

 

3. 자동차 안전 및 보안에 최적화

  • Stellar xMemory는 ISO 26262 ASIL D 수준의 기능 안전성과 ISO 21434 사이버 보안 표준을 준수. 이를 통해 차량의 안전성과 보안을 강화
  • ASIL D는 자동차의 안전성이 매우 중요한 분야에서 요구되는 최고 수준의 안전 표준. Stellar MCU는 이 기준을 충족하여, 안전한 운행을 보장
  • 또한 사이버 보안이 중요한 자동차 시스템에서 ISO 21434 표준을 지원하여, 외부 공격으로부터 차량 시스템을 보호할 수 있음

 

4. 고성능 메모리 및 내구성

  • Stellar xMemory는 Phase Change Memory (PCM) 기술을 기반으로 하여, 기존 플래시 메모리보다 빠르고 내구성이 뛰어나며 전력 소모가 적음
  • PCM은 쓰기 속도가 빠르고, 내구성(쓰기 횟수)이 훨씬 좋으며, 전력 소모가 적기 때문에 차량의 실시간성, 내구성, 저전력 소모 요구 사항을 충족.
  • 기존 MCU는 수만 번의 쓰기 제한이 있지만, xMemory는 수백만 번까지 쓸 수 있어 긴 시간 동안 안정적으로 동작 가능

 

5. 차세대 전기차 및 자율주행 시스템에 최적화

  • Stellar MCU는 **전기차(EV)**와 같은 차세대 차량 아키텍처에 최적화. 전기차의 **배터리 관리 시스템(BMS)**이나 자율주행 시스템과 같이 고속 데이터 처리와 실시간 성능을 요구하는 시스템에 적합
  • 전기차에서 배터리 수명과 에너지 효율이 중요한 요소인데, xMemory의 저전력 특성이 이를 지원하고, 고속 데이터 전송과 처리가 중요한 자율주행 시스템에서도 최적의 성능을 발휘

 

Stellar MCU + xMemory 장점

항목
기존 MCU
Stellar MCU + xMemory
메모리 구조
고정
동적으로 재구성 가능
기능 확장성
하드웨어 변경 필요
소프트웨어로 유연하게 확장 가능
안전성
기본 수준
ASIL D 기능 안전성, ISO 21434 사이버 보안
메모리 내구성
Flash 제한
PCM 기반, 내구성 높고 속도 빠름
전기차 대응
제한적
전기차 및 자율주행 시스템 최적화
업데이트 방식
펌웨어 교체
OTA(Over-the-Air) 업데이트 가능

 


결론

Stellar MCU와 xMemory 기술은 자동차 산업에서 소프트웨어 정의 차량(SDV)의 요구를 충족하고, 기능을 유연하게 확장하며, 안전성과 보안성을 강화하는 강력한 기술

기존 MCU가 한계가 있었던 메모리 구조의 고정성과 기능 확장성의 부족을 해결하며, 차량의 실시간 요구사항을 충족할 수 있는 미래지향적인 MCU로, 차량의 성능과 수명을 연장하는 데 큰 역할

 

'ST > MCU' 카테고리의 다른 글

리눅스 기반 임베디드 플랫폼 선택을 위한 SoC/MPU 비교표  (0) 2025.05.14
MCU(4) - NXP  (0) 2025.03.17
MCU(3) - Infineon  (0) 2025.03.17
MCU(2) - TI  (0) 2025.03.17
MCU(1) - ST  (0) 2025.03.17

 

MCU
STM32F746G DISCOVERY(ST)
IDE
STM32CubeIDE
목표
CAMERA 입력을 받아 LCD로 출력

 

1. DCMI(digital camera Interface)

- MCU에 내장되어 있는 디지털 카메라 인터페이스(DCMI)

- DCMI를 이용하여 DM-CAM130 카메라 테스트

 

1-1. DM-CAM130

DM-CAM130

- Dimensions: 47.8 mm * 37.6 mm * 6mm

- Signal System: CMOS 1.3 Mega Pixel

- Resolution: Up to 1280 * 1024

- Interface:30-pin FPC connector

- Power Supply:From STM32F4DIS-BB

- Operating Temp.:-10°C ~ 70°C

- Supports still photos

- Frame Rate:15 fps for SXGA, 30 fps for VGA and CI

 

1-2. Signal

Interfacing a camera module with an MCU

제어신호

- PIXCLK는 camer의 clock를 공급한다.

- VSYNC는 frame 동기화에 사용된다.

- HSYNC는 line 동기화에 사용된다.

 

Image Data 신호

- camer의 data가 전송되는데 사용되며 병렬 연결의 경우 8bit에서 12bit까지 사용된다.

 

Serial

- camera의 Cofiguration을 위해 사용되며 주로 I2C 버스이다.

 

1-3. DCMI peripheral

DCMI slave AHB2 peripheral in STM32F2x7 line smart architecture

위와 같이 Camera data는 AHB2 주변 장치로 입력되어 GP DMA2와 연결된다.

 

1-4. RGB565

RGB565 foramt은 아래와 같이 5bit의 red value가 msb로 배치되고, 중간에 6bit의 green value가 배치되고 마지작에 5bit의 blue value가 lsb로 배치된다.

LTDC의 Pixel Format도 RGB565로 설정하고 Camera의 DMA target 주소와 LCD의 buffer주소를 동일하게 설정하면 Camera data가 LCD로 출력된다.

 

1-5. YCbYCr

YCbYCr format은 위와 같이 8bit씩 배치된다. 즉 640X480 pixel이라면 절반은 Y data이고 ¼은 Cb ¼은 Cr data이다.

 

2. STM32F746 DISCOVERTY CAMERA 관련 회로도

MCU
JH55-A OV9655 Camera Module

 

3. DCMI 설정

3-1. DCMI : Slave 8 bits External Synchro

3-2. Parameter Settings :

 

3-3. I2C GPIO Settings

 

3-4. GPIO Settings :

 

3-5. DMA : DMA2 stream1

 

3-6. NVIC : EXTI enable

- GENERATE CODE


4. main.c 수정

- 해상도에 맞추어 Sensor에 I2C data를 전송

- HAL_DCMI_Start_DMA 함수를 호출

파라미터로 hdcmi 개체와 capture mode buffer 및 사이즈

- DMA Mode로 동작하므로 손실없이 Camera Image를 그대로 보여줌

#define CAM_DMA_SIZE     (240*320)

OV9655_ReadID(&ov9655_id);
OV9655_QVGAConfig();
HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)pBuf, CAM_DMA_SIZE/2);
 

 

TM32F746 CAMERA 테스트

'ST > STM32F746DIS' 카테고리의 다른 글

STM32F746G DISCOVERY - LCD + TOUCH  (0) 2025.04.19
STM32F746G DISCOVERY - LCD I/F  (0) 2025.04.19
STM32F746G DISCOVERY - SDRAM  (0) 2025.04.19
STM32F746G DISCOVERY - TIM(IC, OC, PWM)  (0) 2025.04.19
STM32F746G DISCOVERY - TIMER  (0) 2025.04.19
 
MCU
STM32F746G DISCOVERY(ST)
IDE
STM32CubeIDE
목표
TOUCH SCREEN 입력을 받아 LCD 화면 전환

 

1. STM32F746 DISCOVERTY LCD + TOUCH 관련 회로도

Backlight driver & PFC of LCD panel

2. I2C 설정

2-1. I2C3 : I2C

 

2-2. I2C Parameter Settings : slave address 0x70

 

2-3. I2C GPIO Settings : PH7(I2C3_SCL), PH8(I2C3_SDA)로 변경

 

2-4. GPIO Settings : PI13(LCD_INT)로 추가

 

2-5. NVIC : EXTI enable

- GENERATE CODE


3. main.c 수정

- HAL_GPIO_EXTI_Callback() 작성

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	ts_trigger = 1;
}
 

 

- SDRAM 초기화 함수와 LTDC 프레임 버퍼 주소 지정, Touch Screen 초기화

	BSP_SDRAM_Initialization(REFRESH_COUNT);
	HAL_LTDC_SetAddress(&hltdc, pBuf, 0);
	status = BSP_TS_Init(480,272);
	if(status == 0) printf("Touch Init OK\r\n");
	else printf("Touch Init Error : %d\r\n", status);
 

 

- Touch 입력을 받아 화면 색을 바꾸는 함수 작성

	while (1)
	{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(ts_trigger == 1)
		{
			ts_trigger = 0;
			if(BSP_TS_GetState(&TS_State)==0){
				x=TS_State.touchX[0];
				y=TS_State.touchY[0];
				printf("TS_x = %d , TS_y=%d \r\n",x,y);
				uint32_t rng_val = HAL_RNG_GetRandomNumber(&hrng);
				if(x < 240)
				{
					if(y < 136) buf_rect(pBuf, 0,240,0,136,rng_val & 0xffff);
					else buf_rect(pBuf, 0,240,136,272,rng_val & 0xffff);
				}
				else
				{
					if(y < 136) buf_rect(pBuf, 240,480,0,136,rng_val & 0xffff);
					else buf_rect(pBuf, 240,480,136,272,rng_val & 0xffff);
				}
			}
			HAL_Delay(10);
		}
	}
	/* USER CODE END 3 */
 
STM32F746 LCD + TOUCH 테스트

 

'ST > STM32F746DIS' 카테고리의 다른 글

STM32F746G DISCOVERY - CAMERA I/F  (0) 2025.04.19
STM32F746G DISCOVERY - LCD I/F  (0) 2025.04.19
STM32F746G DISCOVERY - SDRAM  (0) 2025.04.19
STM32F746G DISCOVERY - TIM(IC, OC, PWM)  (0) 2025.04.19
STM32F746G DISCOVERY - TIMER  (0) 2025.04.19

 

MCU
STM32F746G DISCOVERY(ST)
IDE
STM32CubeIDE
목표
LCD I/F를 이용하여 TFT LCD 출력

 

- 이전 글과 달리 IDE를 ATOLLIC → CubeIDE로 변경

- ATOLLIC은 CubeMX와 ATOLLIC을 따로 설치해야 하나, CubeIDE = CubeMX + IDE 통합 환경

- 사용상의 큰 다른점은 없으나, ATOLLIC에서 생성한 프로젝트를 CubeIDE에서 바로 사용할 수 없고 Import 해서 사용해야 함


1. LTDC(LCD-TFT Display Controller)

STM32F746G DISCOVERY Board에는 480 x 272 해상도의 4.3인치 터치패널이 있는 TFT-LCD가 달려있다.

Red : Green : Blue = 5 : 6 : 5 = 16bit Color에 480x272 해상도의 한 화면을 그릴때 메모리를 계산해 보면,

- 480 x 272 x 2byte = 261,120byte = 261Kbytes

- STM32F746의 SRAM이 320Kbytes인데, 한 화면을 그리고 나면 메모리가 없다.

그래서 외부 SDRAM을 프레임 버퍼 메모리로 사용해야 하므로, LCD 설정에 앞서 SDRAM을 설정 해야 한다.


2. STM32F746 DISCOVERTY LCD + TOUCH 관련 회로도

 

MCU

 

 

Backlight driver & PFC of LCD panel

 

3. LTDC 설정

3-1. RGB565(16 bits)

 

3-2. Clock Configuration : LCD Clock 9.6MHz로 설정

 

3-3. LTDC Parameter Settings

3-4. LTDC Layer Settings : Layer 설정

3-5. LTDC GPIO Settings : Data Bus 결선 확인

아래 회로도를 확인하여, LTDC에서 기본으로 지정하는 포트가 아니고 DISCOVERY Board에서 지정하는 포트로 변경해야 한다.

MCU

 

 

3-6. LCD DSP와 Backlight Pin 설정

 

4. RNG 설정

- 화면에 색을 랜덤으로 바꾸기 위해 Random Number Generator 를 enable

- GENERATE CODE


5. main.c 수정

- 네모 표시함수를 작성

/* USER CODE BEGIN 0 */

void buf_rect(uint16_t  *pBuf, uint32_t start_x, uint32_t stop_x,
              uint32_t start_y,uint32_t stop_y,uint16_t color)
{
    for(uint32_t j=start_y; j<stop_y; j++)
    {
        for(uint32_t i=start_x; i<stop_x; i++)
        {
            *(pBuf + j*480 + i) = (uint16_t)color;
        }
    }
}
 

 

- pBuf 주소를 지정

/* USER CODE BEGIN 1 */
    uint16_t  *pBuf = (uint16_t *)0xC0000000;
/* USER CODE END 1 */
 

 

- SDRAM 초기화 함수와 LTDC 프레임 버퍼 주소 지정

/* USER CODE BEGIN 2 */
    BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);
    HAL_LTDC_SetAddress(&hltdc, pBuf, 0);  // Reconfigure the frame buffer Address
/* USER CODE END 2 */
 

 

- random 함수를 발생시키는 함수를 추가하고 여기서 발생한 32bit 정수를 반씩 나누어 색으로 이용하는 함수를 작성

	while (1)
	{
	/* USER CODE END WHILE */
	
	/* USER CODE BEGIN 3 */
		uint32_t rng_val = HAL_RNG_GetRandomNumber(&hrng);
		printf("RNG_val = 0x%08lx \r\n",rng_val);
		buf_rect(pBuf, 0,240,0,136,rng_val & 0xffff);  	rng_val >>= 16;
		buf_rect(pBuf, 240,480,0,136,rng_val & 0xffff);
	
		rng_val = HAL_RNG_GetRandomNumber(&hrng);
		printf("RNG_val = 0x%08lx \r\n",rng_val);
		buf_rect(pBuf, 0,240,136,272,rng_val & 0xffff);  	rng_val >>= 16;
		buf_rect(pBuf, 240,480,136,272,rng_val & 0xffff);
		HAL_Delay(500);
	}
	/* USER CODE END 3 */
 
STM32F746 LCD 테스트

 

'ST > STM32F746DIS' 카테고리의 다른 글

STM32F746G DISCOVERY - CAMERA I/F  (0) 2025.04.19
STM32F746G DISCOVERY - LCD + TOUCH  (0) 2025.04.19
STM32F746G DISCOVERY - SDRAM  (0) 2025.04.19
STM32F746G DISCOVERY - TIM(IC, OC, PWM)  (0) 2025.04.19
STM32F746G DISCOVERY - TIMER  (0) 2025.04.19

 

MCU
STM32F746G DISCOVERY(ST)
IDE
Atollic(TrueSTUDIO), STM32CubeMX
목표
외부 SDRAM 추가

 

1. SDRAM External memory interface

1) STM32F746 DISCOVERY SDRAM Pin map(자세히는 MB1191 참고)

 

2) SDRAM signals

SDRAM signal
Port
I/O
type
Description
Alternate function
SDCLK
PG8
O
SDRAM clock
-
SDCKE[1:0]
PC3
O
SDCKE0 : SDRAM Bank 1 Clock Enable
SDCKE1 : SDRAM Bank 2 Clock Enable
-
SDNE[1:0]
PH3
O
SDNE0: SDRAM Bank 1 Chip Enable
SDNE1: SDRAM Bank 2 Chip Enable
-
A[12:0]
A0~A11
O
Address
FMC_A[12:0]
D[31:0]
D0~D15
I/O
Bidirectional data bus
FMC_D[31:0]
BA[1:0]
PG5,PG4
O
Bank Address
FMC_A[15:14]
NRAS
PF11
O
Row Address Strobe
-
NCAS
PG15
O
Column Address Strobe
-
SDNWE
PH5
O
Write Enable
-
NBL[3:0]
PE1,PE0
O
Output Byte Mask for write accesses
(memory signal name: DQM[3:0])
FMC_NBL[3:0]

 

2. STM32CubeMX : SDRAM 추가

- 'Clock Configuration' Tab으로 이동

1) HCKL = 216MHz

 

- 'Pinout & Configuration' Tab으로 이동

1) Connectivity - FMC 선택

 

2) SDRAM1 선택

3) Clock and chip enable : SDCKE0 + SDNE0(PC3, PH3)

SDCKE0 기본 할당 PH2 → PC3으로 변경

4) Internal bank number : 4 banks(BA0, BA1)

5) Address : 12 bits(A0 ~ A11 ; 최대 13 bits)

6) Data : 16 bits

7) Byte enable : 16-bit byte enable

 

2. SDNRAS,SDNCAS,SDCLK는 회로도와 동일하게 자동 할당

1) column addr : 8bit(A0 ~A7)

2) row addr : 12bit(A0 ~A11)

3) CAS latency : 3 memory cycles(100MHz 이상 동작시)

4) write protection : disabled

5) SDRAM CLK = HCLK/2=108MHz(max 143MHz)

6) burst read : Disabled

7) read pipe delay : 1 HCLK clock cycle

 

8) Load mode register to active daly : 2

9) Exit self-refresh delay : 7

10) Self-refresh time : 4

11) SDRAM common row cycle delay : 7

12) write recovery time : 3

13) SDRAM common row precharge delay : 2

14) Row to column delay : 2

- GENERATE CODE 클릭


- FMC만 설정한다고 SDRAM을 바로 쓸수 있는게 아니고 SDRAM을 초기화 해줘야 하는데 여기서는 bsp sdram library를 사용함

- BSP library를 프로젝트 폴더에 넣고 시작할것

 

 

3. ATOLLIC 실행

1) C/C++ General > Paths and Symbols > Includes > GNU C에 BSP 폴더 추가

 

2) C/C++ General > Paths and Symbols > Source Location에 BSP 폴더 추가

 

3) BSP_SDRAM_Initialization() 수정

: Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1으로 되어있는지 확인

void BSP_SDRAM_Initialization(uint32_t RefreshCount)
{
  __IO uint32_t tmpmrd =0;

  /* Step 1:  Configure a clock configuration enable command */
  Command.CommandMode             = FMC_SDRAM_CMD_CLK_ENABLE;
  Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber       = 1;
  Command.ModeRegisterDefinition  = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);

  /* Step 2: Insert 100 us minimum delay */ 
  /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
  HAL_Delay(1);

  /* Step 3: Configure a PALL (precharge all) command */ 
  Command.CommandMode             = FMC_SDRAM_CMD_PALL;
  Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber       = 1;
  Command.ModeRegisterDefinition  = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);  
  
  /* Step 4: Configure an Auto Refresh command */ 
  Command.CommandMode             = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber       = 4;
  Command.ModeRegisterDefinition  = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
  
  /* Step 5: Program the external memory mode register */
  tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |
                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
                     SDRAM_MODEREG_CAS_LATENCY_3           |
                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |
                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  
  Command.CommandMode             = FMC_SDRAM_CMD_LOAD_MODE;
  Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber       = 1;
  Command.ModeRegisterDefinition  = tmpmrd;

  /* Send the command */
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
  
  /* Step 6: Set the refresh rate counter */
  /* Set the device refresh rate */
  HAL_SDRAM_ProgramRefreshRate(&hsdram1, RefreshCount); 
}
 

 

4) main.c 수정

: BSP_SDRAM_Initialization(REFRESH_COUNT); 호출

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
#define SDRAM_ADDRESS 0xC0000000

/* USER CODE BEGIN 2 */
BSP_SDRAM_Initialization(REFRESH_COUNT);
 

 

5) Linker Script 수정

: SDRAM 추가

- SDRAM 사용 예제를 찾아보면 SDRAM 주소에 직접 데이터를 쓰는 경우를 봤는데, 변수 한두개도 아니고 64Mbit 용량을 주소에다가 직접 사용하는건 비효율적이라고 본다.

MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 1024K
SDRAM (xrw)      : ORIGIN = 0xC0000000, LENGTH = 8M
}
 

 

Compile시에 아래와 같이 SDRAM이 할당된 것을 확인 할 수 있다.

 

6) 실제로 SDRAM에 변수를 사용하기 위해서 .bss를 SDRAM에 할당하자.

  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >SDRAM
 

이게 잘 될까? 결론부터 얘기하면 동작하지 않는다.

SDRAM 초기화에 사용하는 변수중에 .bss로 할당 되는 변수가 있는데, SDRAM에 변수를 할당해야 하는데 SDRAM은 초기화가 되지 않았다? 아직 집을 짓지도 않았는데, 그 집주소에 택배를 보내는 꼴이다.

 

그러면 어떻게 해야 하나?

1. Bootloader로 SDRAM을 살리고 본 프로그램에서 변수를 SDRAM에 할당

2. 내가 쓰고자 하는 소스가 있는 폴더만 SDRAM에 할당 하도록 함

 

여기서는 2번 방법에 대해 설명한다. 아래와 같이 링커 스트립트를 수정하면, USER 폴더 안에 있는 소스의 모든 변수는 SDRAM에 할당 된다.

  .bss_sdram :
  {
  . = ALIGN(8);
  
  	_sbss_sdram = .; 
  	*USER* (.bss .bss* COMMON)
  	
  	. = ALIGN(8);
  } >SDRAM
  
  /* Uninitialized data section into "RAM" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM
 

 

Debug 폴더 안의 map 파일을 열어보면 USER 폴더안의 소스의 변수 'flag_filter'가 SDRAM에 할당 된것을 확인 할 수 있다.

 

.bss_sdram      0x0c010000        0x4
                0x0c010000                _sbss_sdram = .
 *USER*(.bss .bss* COMMON)
 .bss.flag_filter
                0x0c010000        0x4 USER\temp.o
                0x0c010000                flag_filter
                0x0c010004                _ebss_sdram = .
                0x0c010004                . = ALIGN (0x4)

.bss            0x20000074      0x1fc
                0x20000074                _sbss = .
                0x20000074                __bss_start__ = _sbss
 *(.bss)
 

'ST > STM32F746DIS' 카테고리의 다른 글

STM32F746G DISCOVERY - LCD + TOUCH  (0) 2025.04.19
STM32F746G DISCOVERY - LCD I/F  (0) 2025.04.19
STM32F746G DISCOVERY - TIM(IC, OC, PWM)  (0) 2025.04.19
STM32F746G DISCOVERY - TIMER  (0) 2025.04.19
STM32F746G DISCOVERY - UART(DMA)  (0) 2025.04.19
 
MCU
STM32F746G DISCOVERY(ST)
IDE
Atollic(TrueSTUDIO), STM32CubeMX
목표
HAL driver를 사용하여 TIMER 다양한 mode를 사용하여 LED를 1Hz(1초에 한번 켜졌다 꺼졌다)로 ON-OFF 한다.

 

TIM2를 사용하는데 TIM2는 APB1 Timer clock = 100MHz

 

1. STM32CubeMX : TIMER Output Compare 설정

- 'Pinout & Configuration' Tab으로 이동

1) Timers - TIM2 선택

2) Channel1 : Output Compare No Output 선택

3) Prescaler : 50000-1

- 100MHz / 50,000 = 2,000 = 2KHz

4) Counter Period : 1000-1

- 2,000 / 1,000 = 2Hz, 0.5s 간격으로 TIM2 Interrupt 발생

5) Output Compare : 100

- OC count가 500이 될때 마다 TIM2 Output Compare Interrupt 발생

6) NVIC : TIM2 global interrupt Enabled

- GENERATE CODE 클릭


- ATOLLIC : main.c 수정

- HAL_TIM_Base_Start_IT, HAL_TIM_OC_Start_IT ; 인터럽트 시작을 위해 추가

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_GFXSIMULATOR_Init();
  MX_USART1_UART_Init();
  MX_RTC_Init();
  MX_TIM6_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim2);
  HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_1);
  /* USER CODE END 2 */
 

- HAL_TIM_PeriodElapsedCallback(), HAL_TIM_OC_DelayElapsedCallback() 작성

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == htim2.Instance)
	{
		HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
	}
}

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == htim2.Instance)
	{
		HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
	}
}
 

- 0.5s 마다 duty 10%로 LED 점멸

STM32F746 TIMER OC 테스트(LED 점멸)

2. STM32CubeMX : TIMER PWM 설정

- 'Pinout & Configuration' Tab으로 이동

1) TIM2 선택

2) Channel1 : PWM Generation No Output 선택

3) Prescaler : 50000-1

- 100MHz / 50,000 = 2,000 = 2KHz

4) Counter Period : 1000-1

- 2,000 / 1,000 = 2Hz, 0.5s 간격으로 TIM2 Interrupt 발생

5) Output Compare : 900

- Duty 90%

6) NVIC : TIM2 global interrupt Enabled

- GENERATE CODE 클릭

 

- ATOLLIC : main.c 수정

- HAL_TIM_PWM_Start ; 인터럽트 시작을 위해 추가

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_GFXSIMULATOR_Init();
  MX_USART1_UART_Init();
  MX_RTC_Init();
  MX_TIM6_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
  HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
  /* USER CODE END 2 */
 

- HAL_TIM_PWM_PulseFinishedCallback() 작성

- 0.5s 마다 인터럽트가 걸리는데, 인터럽트 걸릴때 마다 토글하게 되있으므로 1s 마다 LED 점멸

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	  if(htim->Instance == htim2.Instance)
	  {
		  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
	  }
}
 

 

- 소스를 약간 수정해 본다.

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_GFXSIMULATOR_Init();
  MX_USART1_UART_Init();
  MX_RTC_Init();
  MX_TIM6_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim2);
  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
  HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
  /* USER CODE END 2 */
 
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == htim2.Instance)
	{
		HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
	}
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	  if(htim->Instance == htim2.Instance)
	  {
		  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
	  }
}
 

- 0.5s 마다 duty 90%로 LED 점멸

STM32F746 TIMER PWM 테스트(LED 점멸)

 

'ST > STM32F746DIS' 카테고리의 다른 글

STM32F746G DISCOVERY - LCD I/F  (0) 2025.04.19
STM32F746G DISCOVERY - SDRAM  (0) 2025.04.19
STM32F746G DISCOVERY - TIMER  (0) 2025.04.19
STM32F746G DISCOVERY - UART(DMA)  (0) 2025.04.19
STM32F746G DISCOVERY - UART(Polling, Interrupt)  (0) 2025.04.19

 

MCU
STM32F746G DISCOVERY(ST)
IDE
Atollic(TrueSTUDIO), STM32CubeMX
목표
HAL driver를 사용하여 TIMER로 LED를 1Hz(1초에 한번 켜졌다 꺼졌다)로 ON-OFF 한다.

 

TIMER6은 외부 출력이 없는 내부 타이머. 사용에 앞서 TIM6의 기본 clock이 얼마인지 확인해야 한다. TIMER6은 APB1에 연결 되어 있음을 확인 할 수 있다.

Bus
Boundary address
Peripheral

APB1
0x4000 8000 - 0x4000 FFFF
Reserved
0x4000 7C00 - 0x4000 7FFF
UART8
0x4000 7800 - 0x4000 7BFF
UART7
0x4000 7400 - 0x4000 77FF
DAC
0x4000 7000 - 0x4000 73FF
PWR
0x4000 6C00 - 0x4000 6FFF
HDMI-CEC
0x4000 6800 - 0x4000 6BFF
CAN2
0x4000 6400 - 0x4000 67FF
CAN1
0x4000 6000 - 0x4000 63FF
I2C4
0x4000 5C00 - 0x4000 5FFF
I2C3
0x4000 5800 - 0x4000 5BFF
I2C2
0x4000 5400 - 0x4000 57FF
I2C1
0x4000 5000 - 0x4000 53FF
UART5
0x4000 4C00 - 0x4000 4FFF
UART4
0x4000 4800 - 0x4000 4BFF
USART3
0x4000 4400 - 0x4000 47FF
USART2
0x4000 4000 - 0x4000 43FF
SPDIFRX
0x4000 3C00 - 0x4000 3FFF
SPI3 / I2S3
0x4000 3800 - 0x4000 3BFF
SPI2 / I2S2
0x4000 3400 - 0x4000 37FF
Reserved
0x4000 3000 - 0x4000 33FF
IWDG
0x4000 2C00 - 0x4000 2FFF
WWDG
0x4000 2800 - 0x4000 2BFF
RTC & BKP Registers
0x4000 2400 - 0x4000 27FF
LPTIM1
0x4000 2000 - 0x4000 23FF
TIM14
0x4000 1C00 - 0x4000 1FFF
TIM13
0x4000 1800 - 0x4000 1BFF
TIM12
0x4000 1400 - 0x4000 17FF
TIM7
0x4000 1000 - 0x4000 13FF
TIM6
0x4000 0C00 - 0x4000 0FFF
TIM5
0x4000 0800 - 0x4000 0BFF
TIM4
0x4000 0400 - 0x4000 07FF
TIM3
0x4000 0000 - 0x4000 03FF
TIM2

 

​APB1 Timer clock = 100MHz

1. STM32CubeMX : TIMER 설정

- 'Pinout & Configuration' Tab으로 이동

1) TIM6 선택

2) Activated에 체크

3) Prescaler : 10000-1

- 100MHz / 5,000 = 20,000 = 20KHz

4) Counter Period : 10000-1

- 1/20,000 * 10,000 = 0.5s 마다 인터럽트 발생

5) TIM6 global interrupt : Enbled

- GENERATE CODE 클릭


- ATOLLIC : main.c

- HAL_TIM_Base_Start_IT (&htim6); 인터럽트 시작을 위해 추가

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_RTC_Init();
  MX_GFXSIMULATOR_Init();
  MX_USART1_UART_Init();
  MX_TIM6_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT (&htim6);
  /* USER CODE END 2 */
 

- ATOLLIC : stm32f1xx_it.c 수정

- void TIM6_IRQHandler(void) 수정

- CubeMX 설정에서 0.5초마다 인터럽트가 걸리게 설정하였고 인터럽트 핸들러에서 매 인터럽트 마다 포트를 토글 하므로 1초마다(1Hz) LED가 깜박임.

void TIM6_DAC_IRQHandler(void)
{
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */

  /* USER CODE END TIM6_DAC_IRQn 0 */
  HAL_TIM_IRQHandler(&htim6);
  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */
  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  /* USER CODE END TIM6_DAC_IRQn 1 */
}
 

직접 인터럽트 핸들러를 수정하는 방법도 있고 callback 함수를 추가하는 방법도 있으나, 여기서는 TIM6가 내부 인터럽트만 존재하므로(한가지) 인터럽트 핸들러를 수정하였음.

STM32F746 TIMER 테스트(LED 점멸)

 

 

MCU
STM32F746G DISCOVERY(ST)
IDE
Atollic(TrueSTUDIO), STM32CubeMX
목표
HAL driver를 사용하여 UART DMA mode 입출력 Test(Receive Overrun 방지)

 

- UART Firmware 작성시 아래와 같이 크게 세가지 모드로 구분 할 수 있음

- 각 mode별로 입출력 Test

1. Polling

2. Interrupt

3. DMA

이번 페이지에서는 DMA mode 사용


3. STM32CubeMX : UART-DMA 설정

- Configuration은 STM32F746 DISCOVERY - printf()를 이용하여 UART로 문자열 출력 참고

 

- DMA Settings 확인

1) DMA 선택

2) Add 클릭

3) USART1_RX : Mode : Circular, Increment : Memory

- GENERATE CODE 클릭


- ATOLLIC : main.c

- 터미널에서 Keyboard 입력을 받아 다시 Terminal로 출력 코드 작성

- 필요한 변수 선언

#define RX_MAX    1

uint8_t rcv_data[RX_MAX];
 

- while() 작성

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  HAL_UART_Receive_DMA(&huart1, rcv_data, RX_MAX);

  while (1)
  {
	  HAL_Delay(50);

	  if(rcv_data[0])
	  {
  		  printf("Rx OK = %c\r\n", rcv_data[0]);
  		  rcv_data[0] = 0x00;
  	  }

  	  if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_ORE))
  	  {
  		  printf("UART1 Overrun Error occurred.\r\n");
  		  __HAL_UART_CLEAR_IT(&huart1,UART_CLEAR_OREF);
  	  }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
 

+ Recent posts