embeded/FPGA - ALTERA2026. 10. 31. 18:23

dump.tcl

set fp [open "commands.txt" w]

foreach cmd [lsort [info commands]] {
    puts $fp $cmd
}

close $fp

 

~/altera_lite/25.1std/quartus/bin$ ./quartus_sh
Quartus Prime Shell
Version 25.1std.0 Build 1129 10/21/2025 SC Lite Edition
Copyright (C) 2025  Altera Corporation. All rights reserved.

Usage:
------

quartus_sh [-h | --help[=<option|topic>] | -v]
quartus_sh -g | --gui [<project_name>]
quartus_sh <other options>
quartus_sh -t <script file> [<script args>]
quartus_sh -s
quartus_sh --tcl_eval <tcl command>

 

$ ./quartus_sh -t dump.tcl
Info: *******************************************************************
Info: Running Quartus Prime Shell
    Info: Version 25.1std.0 Build 1129 10/21/2025 SC Lite Edition
    Info: Copyright (C) 2025  Altera Corporation. All rights reserved.
    Info: Your use of Altera Corporation's design tools, logic functions
    Info: and other software and tools, and any partner logic
    Info: functions, and any output files from any of the foregoing
    Info: (including device programming or simulation files), and any
    Info: associated documentation or information are expressly subject
    Info: to the terms and conditions of the Altera Program License
    Info: Subscription Agreement, the Altera Quartus Prime License Agreement,
    Info: the Altera IP License Agreement, or other applicable license
    Info: agreement, including, without limitation, that your use is for
    Info: the sole purpose of programming logic devices manufactured by
    Info: Altera and sold by Altera or its authorized distributors.  Please
    Info: refer to the Altera Software License Subscription Agreements
    Info: on the Quartus Prime software download page.
    Info: Processing started: Sat Oct 31 18:21:07 2026
Info: Command: quartus_sh -t dump.tcl
Info (23030): Evaluation of Tcl script dump.tcl was successful
Info: Quartus Prime Shell was successful. 0 errors, 0 warnings
    Info: Peak virtual memory: 449 megabytes
    Info: Processing ended: Sat Oct 31 18:21:07 2026
    Info: Elapsed time: 00:00:00
    Info: Total CPU time (on all processors): 00:00:00

 

막상 돌려서 나오는데 위에서 있다고 한 것들이 보이지 않는다. 머냐?

$ cat commands.txt
add_to_recent_projects
after
append
apply
array
assignment_group
atcl_test_generate_debug_messages
atcl_test_issue_internal_error
atcl_test_issue_tcl_error
atcl_test_issue_tcl_result_error
auto_execok
auto_import
auto_load
auto_load_index
auto_qualify
available_in_sw_edition
binary
break
case
catch
cd
cfg_is_on
chan
check_device_family_equivalence
checksum
clock
close
close_side_revision
concat
continue
copy_project
copy_project_for_hardcopy
coroutine
create_base_clock
create_relative_clock
create_revision
create_test_collection
delete_revision
deploy_platform
dict
disable_msg_box
disable_natural_bus_naming
disable_natural_bus_naming_internal
enable_msg_box
enable_natural_bus_naming
enable_natural_bus_naming_internal
encoding
enumerate_family_traits
enumerate_traits
eof
error
escape_brackets
escape_brackets_internal
eval
exec
execute_assignment_batch
exit
export_assignment_files
export_assignments
expr
fblocked
fconfigure
fcopy
file
fileevent
flush
for
foreach
foreach_in_collection
format
get_acf_info
get_acf_manager
get_all_assignment_names
get_all_assignments
get_all_global_assignments
get_all_instance_assignments
get_all_parameters
get_all_quartus_defaults
get_all_sw_editions
get_all_user_option_names
get_assignment_info
get_assignment_name_info
get_assignments_for_name_id
get_auto_default_part_of
get_base_device_of
get_clocks
get_collection_size
get_current_project
get_current_revision
get_database_version
get_device_install_path_of
get_device_list
get_dstr_string
get_environment_info
get_family_info
get_family_list
get_file_info
get_files
get_global_assignment
get_ini_file
get_ini_var
get_install_path_of
get_instance_assignment
get_libraries
get_license_xml
get_location
get_location_assignment
get_name_info
get_names
get_parameter
get_part_info
get_part_list
get_platform_list
get_project_directory
get_project_license_status
get_project_revisions
get_project_settings
get_quartus_legal_string
get_revision_database_files
get_revision_description
get_temperature_option
get_top_level_entity
get_user_option
get_voltage_info
gets
glob
global
help
if
import_assignments
incr
info
init_tk
interp
ipc_sh_mode_output_to_stdout
is_database_version_compatible
is_fitter_in_qhd_mode
is_project_open
join
lappend
lassign
lindex
linsert
list
llength
lmap
load
load_database
load_package
lrange
lrepeat
lreplace
lreverse
lsearch
lset
lsort
msg_tcl_disable_msg_box
msg_tcl_enable_eda_socket
msg_tcl_enable_msg_box
msg_tcl_flush_stdout
msg_tcl_internal_error
msg_tcl_internal_error_display
msg_tcl_post_display
msg_tcl_post_display_and_delete
msg_tcl_post_message
msg_tcl_post_message_handle
msg_tcl_prompt_display
msg_tcl_puts
msg_vdebug
namespace
native_puts
open
open_side_revision
package
pb_eval
pid
postMessage
post_message
proc
project_archive
project_clean
project_close
project_exists
project_new
project_open
project_restore
project_settings_exist
puts
pwd
qerror
qeval
qexec
qexit
qputs
qshm_connect_to_quartus
qshm_create_server
qshm_disconnect_from_quartus
qshm_dispose_client
qshm_dispose_server
qshm_get_hub_key_prefix
qshm_get_parent_hub_key
qshm_get_server_state
qshm_obtain_client
qshm_send_request
qshm_send_server_state_query
qshm_set_context
qshm_set_server_state
qshm_start_server
qshm_stop_server
read
read_large_file
regexp
regsub
remove_all_global_assignments
remove_all_instance_assignments
remove_all_parameters
rename
report_device_info
report_family_info
report_part_info
report_platform_info
resolve_file_path
return
revision_exists
revision_exists_internal
scan
seek
set
set_acf_manager
set_best_effort_fmax_optimization_assignments
set_clock_latency
set_clock_uncertainty
set_current_revision
set_dll_loading
set_file_lock
set_global_assignment
set_hc_assignments
set_high_effort_fmax_optimization_assignments
set_ini_var
set_input_delay
set_instance_assignment
set_io_assignment
set_location
set_location_assignment
set_multicycle_assignment
set_output_delay
set_parameter
set_power_file_assignment
set_process_log_suffix
set_project_mode
set_project_settings
set_qsf_mode
set_quartus_array
set_revision_description
set_timing_cut_assignment
set_user_option
socket
source
split
stopwatch
string
subst
sw_edition_is
switch
tailcall
tclLog
tell
test_assignment_trait
test_device_trait_of
test_family_trait_of
test_part_trait_of
throw
time
timegroup
trace
try
unknown
unknown_original
unload
unload_database
unset
update
uplevel
upvar
variable
vwait
webhelp_display_topic
while
yield
yieldto
zlib

'embeded > FPGA - ALTERA' 카테고리의 다른 글

tcl, tk, tcl/tk  (0) 2026.10.31
chisel (Constructing Hardware in a Scala Embedded Language)  (0) 2026.10.16
ghdl 사용해봄  (0) 2026.05.08
DE1-SOC LXDE 부팅 완료  (0) 2026.05.02
altera cyclone V HPS BOOTSEL, CLOCKSEL  (0) 2026.04.29
Posted by 구차니
embeded/FPGA - ALTERA2026. 10. 31. 18:09

vivado에만 있는 줄 알았는데,  altera에서도 있다고 해서 일단은 호기심에 조사중

2. FPGA 프로젝트 관리 — 서로 다름
기능 Vivado Quartus
프로젝트 생성 create_project project_new
프로젝트 열기 open_project project_open
프로젝트 닫기 close_project project_close
프로젝트 저장 save_project_as 등 export_assignments
디바이스 선택 set_part set_global_assignment -name DEVICE
최상위 모듈 설정 set_property top set_global_assignment -name TOP_LEVEL_ENTITY
Verilog 추가 add_files set_global_assignment -name VERILOG_FILE
VHDL 추가 add_files set_global_assignment -name VHDL_FILE
SystemVerilog 추가 add_files set_global_assignment -name SYSTEMVERILOG_FILE
제약 파일 등록 add_files -fileset constrs_1 set_global_assignment -name SDC_FILE
소스 목록 조회 get_files get_all_global_assignments 등
프로젝트 설정 조회 get_property get_global_assignment
프로젝트 설정 변경 set_property set_global_assignment
동일한 작업을 수행하는 대표 명령어이며, 반드시 1:1로 대응하는 것은 아닙니다. 

3. FPGA 핀 및 속성 설정 — 서로 다름
기능 Vivado Quartus
외부 핀 위치 set_property PACKAGE_PIN set_location_assignment
I/O 표준 set_property IOSTANDARD set_instance_assignment -name IO_STANDARD
풀업 설정 set_property PULLUP set_instance_assignment -name WEAK_PULL_UP_RESISTOR
구동 강도 set_property DRIVE set_instance_assignment -name CURRENT_STRENGTH_NEW 등
내부 셀 속성 set_property set_instance_assignment 등
최적화 보존 DONT_TOUCH, KEEP 속성 PRESERVE_REGISTER, KEEP 등
디바이스 정보 조회 get_parts, get_property get_part_info 등

4. 타이밍 제약 — 대부분 유사
SDC 기반 명령은 공통으로 사용할 수 있는 부분이 많습니다.
기능 Vivado Quartus 호환성
기본 클록 생성 create_clock create_clock 높음
파생 클록 create_generated_clock 동일 높음
입력 지연 set_input_delay 동일 높음
출력 지연 set_output_delay 동일 높음
False Path set_false_path 동일 높음
Multicycle Path set_multicycle_path 동일 높음
최대 지연 set_max_delay 동일 높음
최소 지연 set_min_delay 동일 높음
클록 그룹 set_clock_groups 동일 높음
클록 불확실성 set_clock_uncertainty 동일 높음
포트 검색 get_ports get_ports 높음
클록 검색 get_clocks get_clocks 높음
내부 핀 검색 get_pins get_pins 부분 호환
내부 셀 검색 get_cells get_cells 부분 호환

5. 합성 및 배치·배선 — 상당히 다름
기능 Vivado Quartus
합성 실행 launch_runs synth_1 또는 synth_design execute_module -tool map
배치·배선 place_design, route_design execute_module -tool fit
전체 컴파일 launch_runs impl_1 등 execute_flow -compile
비트스트림 생성 write_bitstream execute_module -tool asm
합성 결과 열기 open_run synth_1 도구별 데이터베이스/리포트 API
타이밍 분석 report_timing Timing Analyzer의 report_timing
자원 사용량 report_utilization Fitter/Analysis & Synthesis 리포트
소비 전력 report_power Power Analyzer
실행 완료 대기 wait_on_run execute_flow 등은 동기 실행

6. Tk GUI 명령어 — 기본 문법 동일, 실행 환경 차이
Tk는 Tcl GUI 툴킷이므로, Tk를 사용할 수 있는 인터프리터라면 위젯 명령 자체는 동일합니다.
GUI 기능 Vivado의 Tk 환경 Quartus의 Tk 환경
창 제목 wm title 동일
창 크기 wm geometry 동일
버튼 button 동일
텍스트 label 동일
입력창 entry 동일
여러 줄 편집 text 동일
체크박스 checkbutton 동일
라디오 버튼 radiobutton 동일
프레임 frame 동일
자동 배치 pack 동일
격자 배치 grid 동일
좌표 배치 place 동일
이벤트 처리 bind 동일
주기적 실행 after 동일
파일 선택창 tk_getOpenFile 동일
메시지 박스 tk_messageBox 동일

7. IP 및 시스템 통합 명령 — 거의 별개
기능 Vivado Quartus
IP 생성 create_ip qsys-script/IP 관련 Tcl API
IP 파라미터 설정 set_property CONFIG.* set_instance_parameter_value 등
블록 디자인 생성 create_bd_design create_system
IP 인스턴스 추가 create_bd_cell add_instance
IP 연결 connect_bd_net, connect_bd_intf_net add_connection
주소 할당 assign_bd_address set_connection_parameter_value 등
시스템 검증 validate_bd_design validate_system
시스템 생성 generate_target save_system, qsys-generate 등

[링크 : https://chatgpt.com/share/6ae5b255-64bc-83e8-8e86-148906633033]

 

존 오스터하우트 라는 사람이 혼자서 북치고 장구치고 해버렸네 -ㅁ-

설계자 존 오스터하우트
개발자 Tcl 코어 팀
발표일 1988년(38년 전)
최근 버전 9.1.0[1] 위키데이터에서 편집하기
최근 버전 출시일 2026년 9월 29일(32일 전)

[링크 : https://ko.wikipedia.org/wiki/Tcl]

 

원저자 John Ousterhout
개발자 Tcl Core Team[1]
발표일 1991년(35년 전)
안정화 버전
9.1.0[2] 위키데이터에서 편집하기 / 2026년 9월 29일

[링크 : https://en.wikipedia.org/wiki/Tk_(software)]

 

우분투에서 설치는 다음과 같고

$ sudo apt install tcl tk

 

실행 명령어는 아래와 같다.

$ whereis tclsh
tclsh: /usr/bin/tclsh /usr/share/man/man1/tclsh.1.gz

$ whereis wish
wish: /usr/bin/wish /usr/share/man/man1/wish.1.gz

 

아무튼.. tcl이 엄청 오래된건줄 알았는데 python이 예상외로 오래 되었다는것에 놀라는 중 

$ tclsh
% set a 20
20
% puts "$a"
20
% [expr $a+$a]
invalid command name "40"

 

리눅스에서는 아래처럼 실행하면 프롬프트가 뜨고 창이 뜨면서 바로 gui를 만들수 있다.

$ wish


% wm title . "Tk Example"



'embeded > FPGA - ALTERA' 카테고리의 다른 글

quartus_sh  (0) 2026.10.31
chisel (Constructing Hardware in a Scala Embedded Language)  (0) 2026.10.16
ghdl 사용해봄  (0) 2026.05.08
DE1-SOC LXDE 부팅 완료  (0) 2026.05.02
altera cyclone V HPS BOOTSEL, CLOCKSEL  (0) 2026.04.29
Posted by 구차니
embeded/esp322026. 10. 26. 23:21

예전에 그냥 업로드 되었나? 기억이 안나네.

아무튼 업로드 툴로 리셋 걸려서 되면 문제없이 사용이 가능한거라는데..

 

[링크 : https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/boot-mode-selection.html]

 

[링크 : https://fishpoint.tistory.com/11972]

 

이전글의 회로를 보니 IO0 / RST로 DTR / RST가 되어있긴 한 것 같다.

2026.01.17 - [embeded/esp32] - esp32-2432S028 데이터 시트

'embeded > esp32' 카테고리의 다른 글

esp32-s3 / n16r8  (0) 2026.08.27
esp32 s3 n16r8 / n9r2  (0) 2026.08.26
esp32cam 영상인식  (0) 2026.05.24
platform.io + vscode + esp32  (0) 2026.02.18
esp32 on arduino ide  (0) 2026.02.18
Posted by 구차니
embeded/i.mx 8m plus2026. 10. 21. 18:29

imx8mp 에는 여러가지 이상한(?) 것들이 달려있다.

cortex-m7 800Mhz 랑

HiFi DSP 라고 tensilica / xtensa 계열 dsp가 그건데

Advanced Multimedia and Display

  • Video Decode: 1080p60, h.265/4, VP9, VP8
  • Video Encode: 1080p60, h.265/4
  • GPU: 16 GFLOPS (high-precision) OpenGL® ES 3.1/3.0, Vulkan®, Open CL™ 1.2 FP, OpenVG™ 1.1
  • Audio: 18x I2S TDM, DSD512, S/PDIF Tx + Rx, 8-ch PDM Mic input, eARC, ASRC
  • Low power voice accelerator: Cadence® Tensilica® HiFi 4 DSP @ 800 MHz
  • Display: MIPI-DSI, HDMI® 2.0a Tx, LVDS (4/8-lane) Tx

[링크 : https://www.nxp.com/products/i.MX8MPLUS]

 

이전에 생각만 해오던거 오늘은 ai 도움으로 조사중

4 Building DSP Framework on Linux OS
Before you compile the DSP-related code, set up the DSP-related toolchains. The DSP framework, DSP codec wrapper, and DSP codec use Xtensa development toolchain.

[링크 : https://www.nxp.com/docs/en/user-guide/UG10167.pdf]

 

cortex-m7 처럼 rpmsg로 하고, 똑같은 방법으로 펌웨어를 올려서 작동시키면 된다.

기본 컨셉은 ahb를 통해 주변장치가 있으니까 도메인이 존재할거고

리눅스 dtb는 리눅스에서 사용하지 않을 녀석(mcu 들이 사용할 녀석을 제외)을 골라서 사용한다.

ddr 메모리는 mcu / dsp 통신용으로 영역을 선정하고(즉, 리눅스에서 사용하지 않도록 영역 지정)

rpmsg 를 통해서 거기 데이터 있으니 가져가서 처리하라고 찔러준다.

 

xtensa 이긴한데 정확한 아키텍쳐는 찾아봐도 안나오고

그래도 혹시나 하는 마음에 esp32 / esp32-s2 / esp826 바이너리를 빌드해서 dsp에서 돌아가나 테스트 해보려고 함

 

다운로드 경로(zephyr rtos sdk)

[링크 : https://github.com/zephyrproject-rtos/sdk-ng/releases/]

 

테스트 결과

 

일단 esp32 / esp32-s2 로도 돌릴수 있는데 이상하게 느리다는게 좀 단점

zephyr의 것을 쓰면 아무튼 cadence sdk 안쓰고도 가벼운건 돌릴수 있다 정도가 될 듯.

 

+

2026.10.22

zephyr 언급된 문서들

 

AN13970 Running Zephyr RTOS on Cadence Tensilica HiFi 4 DSP

[링크 : https://www.nxp.com/docs/en/application-note/AN13970.pdf]

    [링크 : https://community.nxp.com/t5/i-MX-Processors/Programming-the-Tensilica-HiFi4-DSP/m-p/2079878]

    [링크 : https://openamp-libopenamp-prs.readthedocs.io/en/latest/demos/system_reference-NXP.html]

For details on how to harness the power processing of the DSP by running Zephyr RTOS on the DSP, while running Linux OS on the main Cortex-A core, see the Running Zephyr RTOS on Cadence Tensilica HiFi 4 DSP (AN13970). This covers simple and more complex examples, such as hello_world or IPC samples. In the application note, all examples are explained using the existing drivers and/or frameworks from the Linux OS and Zephyr RTOS.

[링크 : https://www.nxp.jp/docs/en/user-guide/UG10167.pdf]

 

[링크 : https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/hello_world]

    [링크 : https://www.nxp.com/company/about-nxp/smarter-world-blog/BL-HIFI4-DSP-CORE-WITH-ZEPHYR]

 

'embeded > i.mx 8m plus' 카테고리의 다른 글

eiq-portal로 학습 시도(cpu)  (0) 2026.05.27
nxp CMSIS-NN  (0) 2026.05.13
g2d_surface g2d_blit()  (0) 2026.02.10
eiq 모델 정리  (0) 2025.09.16
eiq 데이터 구조  (0) 2025.09.05
Posted by 구차니
embeded/ARM2026. 10. 21. 12:30

리눅스 재단에서 관리하는 rtos 라고 한다.

한번 들여다는 봐야겠네. freeRTOS 보다는 인지도가 없으려나?

 

 [링크 : https://www.nxp.com/docs/en/application-note/AN13970.pdf]

 [링크 : https://www.zephyrproject.org/]

 [링크 : https://m.blog.naver.com/chcbaram/222755342935]

 

+

claude 말로는 아래와 같다고 한다.

그나저나 freertos가 aws에 인수 당했구나..

[링크 : https://www.clien.net/service/board/news/11501037]

 

'embeded > ARM' 카테고리의 다른 글

mbed studio with 32f469idiscovery  (0) 2026.02.21
mbed studio / cli  (0) 2026.02.20
Ethos-U85  (0) 2026.02.06
SVE(Scalable Vector Extension)  (0) 2025.08.28
emmc 파티션 정렬  (0) 2024.02.07
Posted by 구차니
embeded/FPGA - ALTERA2026. 10. 16. 23:30

fpga 다루는 언어인가?

 

scala 라는 언어에 포함 되어있는 하드웨어 

import 보이니 먼가 python 같으면서도 var 대신 val 이니 nodel.js 같기도 하고?

import chisel3._

class MyBundle extends Bundle {
  val foo = UInt(4.W)
  val bar = UInt(4.W)
}

class Foo extends Module {
  val bundle = Wire(new MyBundle)
  bundle.foo := 0xc.U
  bundle.bar := 0x3.U
  val uint = bundle.asUInt
  printf(cf"$uint") // 195

  // Test
  assert(uint === 0xc3.U)
}

[링크 : https://www.chisel-lang.org/docs]

[링크 : https://www.chisel-lang.org/]

 

import chisel3._
import chisel3.util.Counter
import circt.stage.ChiselStage

class Blinky(freq: Int, startOn: Boolean = false) extends Module {
  val io = IO(new Bundle {
    val led0 = Output(Bool())
  })
  // Blink LED every second using Chisel built-in util.Counter
  val led = RegInit(startOn.B)
  val (_, counterWrap) = Counter(true.B, freq / 2)
  when(counterWrap) {
    led := ~led
  }
  io.led0 := led
}

object Main extends App {
  // These lines generate the Verilog output
  println(
    ChiselStage.emitSystemVerilog(
      new Blinky(1000),
      firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info")
    )
  )
}

[링크 : https://github.com/chipsalliance/chisel]

[링크 : https://en.wikipedia.org/wiki/Chisel_(programming_language)]

'embeded > FPGA - ALTERA' 카테고리의 다른 글

quartus_sh  (0) 2026.10.31
tcl, tk, tcl/tk  (0) 2026.10.31
ghdl 사용해봄  (0) 2026.05.08
DE1-SOC LXDE 부팅 완료  (0) 2026.05.02
altera cyclone V HPS BOOTSEL, CLOCKSEL  (0) 2026.04.29
Posted by 구차니
embeded/Cortex-M3 STM2026. 9. 23. 14:17

아두이노 예제밖에 안보이냐..

[링크 : https://mobilitykids.tistory.com/entry/MAX7219-LED-매트릭스-디스플레이Arduino-튜토리얼-포함]

[링크 : https://m.blog.naver.com/eduino/222651170585]

 

spi 같긴한데.. 원래는 7seg 용으로 개발되었으나 dot matrix에서도 쓰는건가?

Features
● 10MHz Serial Interface
● Individual LED Segment Control
● Decode/No-Decode Digit Selection
● 150μA Low-Power Shutdown (Data Retained)
● Digital and Analog Brightness Control
● Display Blanked on Power-Up
● Drive Common-Cathode LED Display
● Slew-Rate Limited Segment Drivers for Lower EMI (MAX7221)
● SPI, QSPI, MICROWIRE Serial Interface (MAX7221)

[링크 : https://www.analog.com/media/en/technical-documentation/data-sheets/max7219-max7221.pdf]

 

+

선도 연결방법 알려달라고 하고

어떻게 어떻게 해서  claude가 다 해줘버리네. 인간은 멀 취미로 해야하지?

ai가 해준걸 취미라고 해도 될까? 고민되네..

 

/*
 * max7219.h
 *
 * MAX7219 8x8 도트매트릭스(데이지체인) 구동 + 텍스트 스크롤 드라이버.
 * SPI(하드웨어)로 DIN/CLK를 보내고, CS(LOAD)는 별도 GPIO로 직접 제어한다.
 */
#ifndef __MAX7219_H
#define __MAX7219_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stm32f1xx_hal.h"

/* 체인에 연결된 8x8 모듈 개수. 모듈 1개만 있으면 1로 바꿀 것. */
#define MAX7219_NUM_DEVICES   4

/* 하드웨어 배선에 따라 좌우/모듈 순서가 반대로 보이면 아래 두 값을 바꿔서 조정 */
#define MAX7219_REVERSE_CHAIN 1   /* 텍스트가 모듈 순서상 반대로 표시되면 1 (실측: 4 3 2 1로 나와서 1로 설정) */
#define MAX7219_MIRROR_COLS   0   /* 글자가 좌우 반전되어 보이면 1 */

void MAX7219_Init(SPI_HandleTypeDef *hspi);
void MAX7219_Clear(void);
void MAX7219_SetIntensity(uint8_t level /* 0x0~0xF */);

/* 표시할 문자열을 설정(내부 컬럼 버퍼에 렌더링해 둠). ASCII만 지원(공백,0-9,A-Z,.,!,-) */
void MAX7219_SetText(const char *text);

/* 한 프레임(1컬럼) 스크롤 진행 + 출력. 텍스트가 한 바퀴 돌면 1을 반환(그 외 0). */
uint8_t MAX7219_ScrollStep(void);

/* 진단용: 스크롤 없이 모듈(0번부터)마다 고정 숫자 1,2,3,4...를 동시에 정적으로 표시.
 * 다중 디바이스 주소 지정이 정상인지 확인할 때만 임시로 사용. */
void MAX7219_ShowDeviceIndexTest(void);

#ifdef __cplusplus
}
#endif

#endif /* __MAX7219_H */

 

/*
 * max7219.c
 *
 * MAX7219 8x8 도트매트릭스 체인 구동 + 좌->우 텍스트 스크롤.
 *
 * 배선(하드웨어 SPI1 사용):
 *   MAX7219 DIN  -> PA7 (SPI1_MOSI)
 *   MAX7219 CLK  -> PA5 (SPI1_SCK)
 *   MAX7219 CS   -> PA4 (일반 GPIO, 소프트웨어 제어)
 *   MAX7219 VCC  -> 5V,  GND -> GND
 *
 * 레지스터 모델: MAX7219는 디코드모드 OFF 상태에서 DIGIT0~7 레지스터 각각이
 * 매트릭스의 "행(row)"이며, 그 8bit가 그 행의 8개 열(column)을 나타낸다.
 * 따라서 프레임을 만들 때는 (행, 각 모듈별 8bit) 형태로 SPI에 실어야 한다.
 */
#include "main.h"
#include "max7219.h"
#include <string.h>
#include <ctype.h>

#define MAX7219_REG_NOOP        0x00
#define MAX7219_REG_DIGIT0      0x01
#define MAX7219_REG_DECODEMODE  0x09
#define MAX7219_REG_INTENSITY   0x0A
#define MAX7219_REG_SCANLIMIT   0x0B
#define MAX7219_REG_SHUTDOWN    0x0C
#define MAX7219_REG_DISPLAYTEST 0x0F

#define MAX7219_TOTAL_COLS      (MAX7219_NUM_DEVICES * 8)

/* 표시 가능한 최대 문자열 길이(글자당 6컬럼 = 5폭+1간격) + 앞뒤 여백 */
#define MAX7219_TEXT_MAX_CHARS  64
#define MAX7219_COLBUF_SIZE     (MAX7219_TOTAL_COLS * 2 + MAX7219_TEXT_MAX_CHARS * 6)

static SPI_HandleTypeDef *s_hspi;
static uint8_t  s_colbuf[MAX7219_COLBUF_SIZE];
static uint32_t s_colbuf_len;
static uint32_t s_scroll_offset;

/* ---- 5x7 폰트: 행(row) 단위 원본 표현. 각 바이트의 bit4..bit0 = 좌->우 5개 컬럼 ---- */
typedef struct { char ch; uint8_t rows[7]; } Glyph5x7;

static const Glyph5x7 s_font[] = {
  {' ', {0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000}},
  {'0', {0b01110,0b10001,0b10011,0b10101,0b11001,0b10001,0b01110}},
  {'1', {0b00100,0b01100,0b00100,0b00100,0b00100,0b00100,0b01110}},
  {'2', {0b01110,0b10001,0b00001,0b00010,0b00100,0b01000,0b11111}},
  {'3', {0b11111,0b00010,0b00100,0b00010,0b00001,0b10001,0b01110}},
  {'4', {0b00010,0b00110,0b01010,0b10010,0b11111,0b00010,0b00010}},
  {'5', {0b11111,0b10000,0b11110,0b00001,0b00001,0b10001,0b01110}},
  {'6', {0b00110,0b01000,0b10000,0b11110,0b10001,0b10001,0b01110}},
  {'7', {0b11111,0b00001,0b00010,0b00100,0b01000,0b01000,0b01000}},
  {'8', {0b01110,0b10001,0b10001,0b01110,0b10001,0b10001,0b01110}},
  {'9', {0b01110,0b10001,0b10001,0b01111,0b00001,0b00010,0b01100}},
  {'A', {0b01110,0b10001,0b10001,0b11111,0b10001,0b10001,0b10001}},
  {'B', {0b11110,0b10001,0b10001,0b11110,0b10001,0b10001,0b11110}},
  {'C', {0b01111,0b10000,0b10000,0b10000,0b10000,0b10000,0b01111}},
  {'D', {0b11110,0b10001,0b10001,0b10001,0b10001,0b10001,0b11110}},
  {'E', {0b11111,0b10000,0b10000,0b11110,0b10000,0b10000,0b11111}},
  {'F', {0b11111,0b10000,0b10000,0b11110,0b10000,0b10000,0b10000}},
  {'G', {0b01111,0b10000,0b10000,0b10011,0b10001,0b10001,0b01111}},
  {'H', {0b10001,0b10001,0b10001,0b11111,0b10001,0b10001,0b10001}},
  {'I', {0b01110,0b00100,0b00100,0b00100,0b00100,0b00100,0b01110}},
  {'J', {0b00111,0b00010,0b00010,0b00010,0b00010,0b10010,0b01100}},
  {'K', {0b10001,0b10010,0b10100,0b11000,0b10100,0b10010,0b10001}},
  {'L', {0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b11111}},
  {'M', {0b10001,0b11011,0b10101,0b10101,0b10001,0b10001,0b10001}},
  {'N', {0b10001,0b11001,0b10101,0b10101,0b10011,0b10001,0b10001}},
  {'O', {0b01110,0b10001,0b10001,0b10001,0b10001,0b10001,0b01110}},
  {'P', {0b11110,0b10001,0b10001,0b11110,0b10000,0b10000,0b10000}},
  {'Q', {0b01110,0b10001,0b10001,0b10001,0b10101,0b10010,0b01101}},
  {'R', {0b11110,0b10001,0b10001,0b11110,0b10100,0b10010,0b10001}},
  {'S', {0b01111,0b10000,0b10000,0b01110,0b00001,0b00001,0b11110}},
  {'T', {0b11111,0b00100,0b00100,0b00100,0b00100,0b00100,0b00100}},
  {'U', {0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b01110}},
  {'V', {0b10001,0b10001,0b10001,0b10001,0b10001,0b01010,0b00100}},
  {'W', {0b10001,0b10001,0b10001,0b10101,0b10101,0b10101,0b01010}},
  {'X', {0b10001,0b10001,0b01010,0b00100,0b01010,0b10001,0b10001}},
  {'Y', {0b10001,0b10001,0b01010,0b00100,0b00100,0b00100,0b00100}},
  {'Z', {0b11111,0b00001,0b00010,0b00100,0b01000,0b10000,0b11111}},
  {'.', {0b00000,0b00000,0b00000,0b00000,0b00000,0b01100,0b01100}},
  {'!', {0b00100,0b00100,0b00100,0b00100,0b00100,0b00000,0b00100}},
  {'-', {0b00000,0b00000,0b00000,0b11111,0b00000,0b00000,0b00000}},
};
#define FONT_COUNT (sizeof(s_font) / sizeof(s_font[0]))

static const Glyph5x7 *font_lookup(char c)
{
  if (c >= 'a' && c <= 'z') c = (char)(c - 'a' + 'A'); /* 소문자 -> 대문자 */
  for (uint32_t i = 0; i < FONT_COUNT; i++)
  {
    if (s_font[i].ch == c) return &s_font[i];
  }
  return &s_font[0]; /* 지원 안 하는 문자는 공백으로 */
}

/* row(0=top..6=bottom) 문자열 비트에서 col(0=left..4)에 해당하는 컬럼 바이트를 뽑아
 * bit r 위치에 채운다 (bit0=top row ... bit6=bottom row). */
static uint8_t glyph_col_byte(const Glyph5x7 *g, uint8_t col)
{
  uint8_t val = 0;
  for (uint8_t r = 0; r < 7; r++)
  {
    uint8_t bit = (g->rows[r] >> (4 - col)) & 0x01U;
    val |= (uint8_t)(bit << r);
  }
  return val;
}

/* ---- 저수준 SPI 전송 ---- */

static inline void cs_low(void)  { HAL_GPIO_WritePin(MAX7219_CS_PORT, MAX7219_CS_PIN, GPIO_PIN_RESET); }
static inline void cs_high(void) { HAL_GPIO_WritePin(MAX7219_CS_PORT, MAX7219_CS_PIN, GPIO_PIN_SET); }

/* 체인의 모든 모듈에 동일한 (reg,data)를 전송 (초기화/공통 설정용) */
static void max7219_write_all(uint8_t reg, uint8_t data)
{
  uint8_t buf[2] = { reg, data };
  cs_low();
  for (uint32_t i = 0; i < MAX7219_NUM_DEVICES; i++)
  {
    HAL_SPI_Transmit(s_hspi, buf, 2, HAL_MAX_DELAY);
  }
  cs_high();
}

/* 한 행(row 0~7)에 대해 모듈별 8bit 데이터를 체인에 맞는 순서로 전송.
 * dev_data[0] = MCU와 가장 가까운(첫번째) 모듈. SPI 시프트 특성상 체인에서는
 * 가장 먼 모듈 데이터부터 먼저 밀어넣어야 CS 상승 시 올바르게 래치된다. */
static void max7219_send_row(uint8_t row, const uint8_t *dev_data)
{
  uint8_t reg = (uint8_t)(MAX7219_REG_DIGIT0 + row);
  cs_low();
#if MAX7219_REVERSE_CHAIN
  for (int32_t dev = 0; dev < MAX7219_NUM_DEVICES; dev++)
#else
  for (int32_t dev = MAX7219_NUM_DEVICES - 1; dev >= 0; dev--)
#endif
  {
    uint8_t buf[2] = { reg, dev_data[dev] };
    HAL_SPI_Transmit(s_hspi, buf, 2, HAL_MAX_DELAY);
  }
  cs_high();
}

void MAX7219_Init(SPI_HandleTypeDef *hspi)
{
  s_hspi = hspi;

  max7219_write_all(MAX7219_REG_DISPLAYTEST, 0x00);
  max7219_write_all(MAX7219_REG_SCANLIMIT, 0x07);   /* 8자리(행) 전부 사용 */
  max7219_write_all(MAX7219_REG_DECODEMODE, 0x00);  /* BCD 디코드 없음: 매트릭스 모드 */
  max7219_write_all(MAX7219_REG_INTENSITY, 0x04);   /* 밝기 0x0~0xF */
  max7219_write_all(MAX7219_REG_SHUTDOWN, 0x01);    /* 0=shutdown, 1=normal operation */

  MAX7219_Clear();
}

void MAX7219_SetIntensity(uint8_t level)
{
  max7219_write_all(MAX7219_REG_INTENSITY, (uint8_t)(level & 0x0FU));
}

void MAX7219_Clear(void)
{
  uint8_t zeros[MAX7219_NUM_DEVICES];
  memset(zeros, 0, sizeof(zeros));
  for (uint8_t row = 0; row < 8; row++)
  {
    max7219_send_row(row, zeros);
  }
}

void MAX7219_SetText(const char *text)
{
  uint32_t len = 0;

  /* 화면 밖에서 스크롤 들어오도록 앞쪽 여백(패널 폭만큼 공백) */
  for (uint32_t i = 0; i < MAX7219_TOTAL_COLS && len < MAX7219_COLBUF_SIZE; i++)
  {
    s_colbuf[len++] = 0x00;
  }

  for (const char *p = text; *p != '\0' && len + 6 <= MAX7219_COLBUF_SIZE; p++)
  {
    const Glyph5x7 *g = font_lookup(*p);
    for (uint8_t c = 0; c < 5; c++)
    {
      s_colbuf[len++] = glyph_col_byte(g, c);
    }
    s_colbuf[len++] = 0x00; /* 글자 사이 1컬럼 간격 */
  }

  /* 화면 밖으로 완전히 빠져나가도록 뒤쪽 여백 */
  for (uint32_t i = 0; i < MAX7219_TOTAL_COLS && len < MAX7219_COLBUF_SIZE; i++)
  {
    s_colbuf[len++] = 0x00;
  }

  s_colbuf_len = len;
  s_scroll_offset = 0;
}

static void render_frame(void)
{
  uint8_t dev_row[MAX7219_NUM_DEVICES];

  if (s_colbuf_len == 0) return;

  for (uint8_t row = 0; row < 8; row++)
  {
    for (uint32_t dev = 0; dev < MAX7219_NUM_DEVICES; dev++)
    {
      uint8_t val = 0;
      for (uint8_t c = 0; c < 8; c++)
      {
        uint32_t col_index = (s_scroll_offset + dev * 8U + c) % s_colbuf_len;
        uint8_t bit = (s_colbuf[col_index] >> row) & 0x01U;
#if MAX7219_MIRROR_COLS
        val |= (uint8_t)(bit << c);
#else
        val |= (uint8_t)(bit << (7 - c));
#endif
      }
      dev_row[dev] = val;
    }
    max7219_send_row(row, dev_row);
  }
}

uint8_t MAX7219_ScrollStep(void)
{
  render_frame();

  if (s_colbuf_len == 0) return 1;

  s_scroll_offset++;
  if (s_scroll_offset >= s_colbuf_len)
  {
    s_scroll_offset = 0;
    return 1;
  }
  return 0;
}

/* 각 모듈에 스크롤 없이 고정 숫자를 동시에 정적으로 표시(디버그용).
 * dev=0 -> "1", dev=1 -> "2" ... 모듈이 서로 다른 내용을 "동시에" 보여주는지,
 * 그리고 계속 켜진 상태로 유지되는지(깜빡임/순차갱신 없는지) 확인하는 용도. */
void MAX7219_ShowDeviceIndexTest(void)
{
  uint8_t dev_row[MAX7219_NUM_DEVICES];
  const Glyph5x7 *glyphs[MAX7219_NUM_DEVICES];

  for (uint32_t dev = 0; dev < MAX7219_NUM_DEVICES; dev++)
  {
    char digit = (char)('1' + (dev % 9));
    glyphs[dev] = font_lookup(digit);
  }

  for (uint8_t row = 0; row < 8; row++)
  {
    for (uint32_t dev = 0; dev < MAX7219_NUM_DEVICES; dev++)
    {
      uint8_t val = 0;
      if (row < 7) /* 글꼴은 7행(0~6)까지만 있음, 8번째 행은 항상 빈 줄 */
      {
        for (uint8_t c = 0; c < 5; c++) /* 글꼴 폭 5, 나머지 3컬럼은 여백(0) */
        {
          uint8_t bit = (glyphs[dev]->rows[row] >> (4 - c)) & 0x01U;
#if MAX7219_MIRROR_COLS
          val |= (uint8_t)(bit << (2 + c));
#else
          val |= (uint8_t)(bit << (7 - c));
#endif
        }
      }
      dev_row[dev] = val;
    }
    max7219_send_row(row, dev_row);
  }
}

'embeded > Cortex-M3 STM' 카테고리의 다른 글

ws2812b vs hub75  (0) 2026.09.23
네오픽셀 ws2812b-64 작동  (0) 2026.09.23
stm32 gpio hi-z  (0) 2026.09.10
stm32f103c9t6(bluepill) + keypad  (0) 2026.09.08
stm32 usb composite / report id  (0) 2026.09.04
Posted by 구차니
embeded/Cortex-M3 STM2026. 9. 23. 12:46

짱구 굴려봐도.. ws2812b가 절대 쌀수가 없네..

라즈베리 파이에 ws2612b-64를 8x8로 구성해서

총 64x64 해상도 출력하는데 드는 돈이 장당 2500원 해도 16만원 (실 구매가는 2200원 이긴 한데)

전원이랑 라즈베리 파이 추가하면 총 가격이 어마어마 해진다.

 

[링크 : https://itempage3.auction.co.kr/DetailView.aspx?itemno=F479040772] HUB75 128x128 13만원

 

 네, 보통 HUB75가 단위면적당 더 쌉니다. 이유는 구조적입니다.

  근본 이유
  - WS2812B: LED 하나당 드라이버 IC가 하나씩 내장(개별 어드레싱) → LED 개수만큼 IC 비용이 그대로 곱해짐
  - HUB75: LED 여러 개(보통 16개)를 드라이버 IC 하나(MBI5124 등)가 묶어서 구동 → IC 개수가 LED 개수의 1/16
    수준이라 원가가 확 낮음
  - 게다가 HUB75는 옥외광고/전광판 산업에서 이미 수백만 장 양산되는 표준품이라 규모의 경제까지 붙음

  대략적인 단가 비교 (픽셀피치 1cm 기준으로 맞춰서)
  - WS2812B 8×8 모듈(8cm×8cm=64cm²): 약 2,500원 → 약 39원/cm²
  - HUB75 P10 판넬(32×16px, 32cm×16cm=512cm²): 알리 기준 대략 10,000~15,000원 → 약 20~29원/cm²

  → 같은 면적, 비슷한 해상도 밀도 기준으로 HUB75가 30~50% 정도 저렴한 편입니다.

  64×64(64cm×64cm) 전체로 환산하면
  - WS2812B: 아까 계산한 16만원
  - HUB75(같은 픽셀피치 P10 기준, 32×32px 판넬 4장 정도 조합): 대략 4~6만원대로 절반 이하까지 내려갈 수 있음

  덤으로 따라오는 이점
  - HUB75 판넬은 애초에 체이닝용 커넥터 + 판넬 내 전원 분배가 설계되어 있어서, 아까 얘기한 "전원 주입 지점 직접
    설계" 부담이 훨씬 줄어듭니다 (완전히 없어지진 않지만 DIY WS2812보다 훨씬 정형화됨)

  대신 치러야 할 비용은 복잡도
  - 드라이버가 HUB75 전용 스캔+BCM 방식이라 소프트웨어를 새로 짜야 함 (지금 있는 WS2812 코드 재사용 불가, 전에
    말씀드린 대로)
  - MCU도 RPi나 ESP32-S3처럼 DMA로 지속 스캔 감당할 수 있는 걸 써야 함

  정리하면 돈은 HUB75가 이기고, 개발 난이도는 WS2812가 더 쉬움 — 트레이드오프입니다. 64개 패널 사기 전에 HUB75
  견적도 한 번 비교해보시는 게 좋을 것 같아요.

'embeded > Cortex-M3 STM' 카테고리의 다른 글

max7219 8-Digit LED Display Drivers  (0) 2026.09.23
네오픽셀 ws2812b-64 작동  (0) 2026.09.23
stm32 gpio hi-z  (0) 2026.09.10
stm32f103c9t6(bluepill) + keypad  (0) 2026.09.08
stm32 usb composite / report id  (0) 2026.09.04
Posted by 구차니
embeded/Cortex-M3 STM2026. 9. 23. 12:08

stm32f103 / bluepill

네오픽셀 ws2812b-64

+ claude

 

PB0 를 신호선으로 GND는 연결해주어야 한다.

white로 하면 최대 밝기가 아니어도 미친듯이 눈이 부시고 4.5V / 1.6A 먹는데

레인보우 패턴으로 바꾸니 4V / 0.15A 정도로 착하게 먹는다.

 

저기가 1번 LED

 

하나 더 켜진게 led 2번

뒤집으면 입력핀 바로 뒤에있는게 1번이다.

 

직접 코딩해보려다가 작동만 확인하려고 ai 써서 일단 진행

낮은 클럭으로 하다가 안되서 72MHz로 올리니 정상적으로 작동한다. 역시 SPI로 가야하나?

/* -------------------- WS2812 (PB0, bit-bang, DWT cycle count) -------------------- */

/* Cortex-M3 DWT 사이클 카운터 활성화 (마이크로초 이하 정밀 타이밍용) */
static void DWT_Init(void)
{
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  DWT->CYCCNT = 0;
  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}

/* 비트 1개 전송: 기준 시각(start) 대비 상대시간으로 High->Low 구간을 제어해
 * 분기/함수호출 오버헤드로 인한 지터를 최소화한다.
 * always_inline: -O0 빌드에서도 GCC가 반드시 인라인하도록 강제 (그냥 inline은
 * -O0에서 무시되어 매 비트마다 진짜 함수호출(push/pop)이 발생, 비트 사이 LOW
 * 구간이 수십배 길어져 스트립이 매 비트를 리셋으로 오인하는 문제가 있었음). */
__attribute__((always_inline)) static inline void ws2812_send_bit(uint8_t bit)
{
  uint32_t start = DWT->CYCCNT;
  uint32_t high_cycles = bit ? WS_T1H_CYCLES : WS_T0H_CYCLES;

  WS2812_PORT->BSRR = WS2812_PIN;                  /* Data line High */
  while ((DWT->CYCCNT - start) < high_cycles) { }
  WS2812_PORT->BSRR = (uint32_t)WS2812_PIN << 16U;  /* Data line Low  */
  while ((DWT->CYCCNT - start) < WS_BIT_CYCLES) { }
}

__attribute__((always_inline)) static inline void ws2812_send_byte(uint8_t byte)
{
  for (int8_t i = 7; i >= 0; i--)
  {
    ws2812_send_bit((byte >> i) & 0x01U);
  }
}

/* led_grb[] 버퍼 내용을 스트립으로 전송. 전송 중 인터럽트(특히 USB)로 인한
 * 타이밍 흐트러짐을 막기 위해 전송 구간만 짧게(약 1.92ms/64LED) IRQ를 끈다.
 *
 * 전송 전에 예상 총 전류(mA)를 계산해서 WS_MAX_TOTAL_MA를 넘으면 전체 밝기를
 * 비율대로 깎아서 보낸다. led_grb[]는 원본 그대로 두고(다음 프레임 색상 계산에
 * 영향 없음), 실제 출력만 스케일한다. */
static void ws2812_show(void)
{
  uint32_t est_ma = (uint32_t)NUM_LEDS * WS_MA_IDLE_PER_LED;
  for (uint32_t i = 0; i < NUM_LEDS; i++)
  {
    uint32_t sum = (uint32_t)led_grb[i][0] + led_grb[i][1] + led_grb[i][2];
    est_ma += (sum * WS_MA_PER_CH_FULL) / 255U;
  }

  /* scale: 256 = 그대로, 그보다 작으면 그 비율만큼 줄임 (고정소수점 8bit) */
  uint32_t scale = 256U;
  if (est_ma > WS_MAX_TOTAL_MA)
  {
    scale = (WS_MAX_TOTAL_MA * 256U) / est_ma;
  }

  __disable_irq();
  for (uint32_t i = 0; i < NUM_LEDS; i++)
  {
    ws2812_send_byte((uint8_t)((led_grb[i][0] * scale) >> 8)); /* G */
    ws2812_send_byte((uint8_t)((led_grb[i][1] * scale) >> 8)); /* R */
    ws2812_send_byte((uint8_t)((led_grb[i][2] * scale) >> 8)); /* B */
  }
  __enable_irq();
  /* Reset/Latch(>=50us Low)은 다음 프레임까지의 HAL_Delay 구간이 충분히 커버함 */
}

/* 0~255 위치값을 무지개 색상(R,G,B)으로 변환 (Adafruit NeoPixel wheel과 동일) */
static void wheel(uint8_t pos, uint8_t *r, uint8_t *g, uint8_t *b)
{
  pos = 255 - pos;
  if (pos < 85)
  {
    *r = 255 - pos * 3;
    *g = 0;
    *b = pos * 3;
  }
  else if (pos < 170)
  {
    pos -= 85;
    *r = 0;
    *g = pos * 3;
    *b = 255 - pos * 3;
  }
  else
  {
    pos -= 170;
    *r = pos * 3;
    *g = 255 - pos * 3;
    *b = 0;
  }
}

int main(void)
{

  /* USER CODE BEGIN 1 */
uint32_t count = 0;       /* 프레임 카운터 (하트비트 타이밍용) */
uint32_t anim_offset = 0; /* 무지개 애니메이션 오프셋 (WS_ANIM_STEP만큼씩 증가) */
#if WS_TEST_ORIENTATION
    /* 방향 확인용: 1번(index 0) LED만 흰색, 나머지는 꺼둠 */
    for (uint32_t i = 0; i < NUM_LEDS; i++)
    {
      uint8_t v = (i == 0) ? WS_BRIGHTNESS : 0;
      led_grb[i][0] = v; /* G */
      led_grb[i][1] = v; /* R */
      led_grb[i][2] = v; /* B */
    }
    ws2812_show();
#else
    for (uint32_t i = 0; i < NUM_LEDS; i++)
    {
      uint8_t wheel_pos = (uint8_t)((i * 256 / NUM_LEDS + anim_offset) & 0xFF);
      uint8_t r, g, b;
      wheel(wheel_pos, &r, &g, &b);
      led_grb[i][0] = (uint8_t)((g * WS_BRIGHTNESS) / 255);
      led_grb[i][1] = (uint8_t)((r * WS_BRIGHTNESS) / 255);
      led_grb[i][2] = (uint8_t)((b * WS_BRIGHTNESS) / 255);
    }
    ws2812_show();
#endif
}

 

 

'embeded > Cortex-M3 STM' 카테고리의 다른 글

max7219 8-Digit LED Display Drivers  (0) 2026.09.23
ws2812b vs hub75  (0) 2026.09.23
stm32 gpio hi-z  (0) 2026.09.10
stm32f103c9t6(bluepill) + keypad  (0) 2026.09.08
stm32 usb composite / report id  (0) 2026.09.04
Posted by 구차니
embeded/rpi pico2026. 9. 17. 17:50

도대체 먼 끔찍한(?) 걸 만들어서 싸게 파는거야?!?

 

PIO- Programmable IO

[링크 : https://blog.naver.com/chcbaram/222807946312]

[링크 : https://github.com/raspberrypi/pico-examples/tree/master/pio]

 

cortex-m0+ 듀얼 코어라 AMP도 해봐야 하는디.. 언제 해보냐 ㅠㅠ

Posted by 구차니