STM32 from signal to software

เรียนรู้ STM32 ด้วยการมองเห็น แล้วลงมือเปลี่ยนมัน

6 บทเรียน · 14 interactive labs · 20 โปรแกรมตัวอย่าง สำหรับ Nucleo F411RE และ STEO Training Shield 1 ตั้งแต่คล็อกหนึ่งเส้นจนถึงระบบหลาย peripheral

00

Core, memory, buses, clocks

เริ่มจากภาพใหญ่ของไมโครคอนโทรลเลอร์

ทำความเข้าใจว่า CPU, หน่วยความจำ และ peripheral สื่อสารกันผ่านบัสอย่างไร ก่อนแตะรีจิสเตอร์ตัวแรก

  • แยกบทบาท CPU กับ peripheral
  • ตามเส้นทางคล็อกจาก RCC ไปยังอุปกรณ์

LAB 01 · RCC / AHB / APB

คล็อกคือไฟเลี้ยงของ peripheral

HSE
11 MHz
→ PLL →
SYSCLK
76 MHz
AHB/APB

รีจิสเตอร์ของ GPIO, ADC, USART และ Timer จะไม่ตอบสนองจนกว่า RCC จะจ่ายคล็อกให้บัสที่อุปกรณ์นั้นเชื่อมอยู่ ลองเพิ่มความถี่เพื่อดูจังหวะระบบ

ลองกับโปรแกรมจริง →

01

GPIO, pull-up, debounce, EXTI

Digital I/O และเหตุการณ์จากปุ่ม

เรียนรู้การตั้งโหมดขา อ่านปุ่ม active-low กรองสัญญาณเด้ง และเลือก polling หรือ interrupt ให้เหมาะกับงาน

  • ตั้ง GPIO input/output/alternate function
  • ออกแบบ event จากปุ่มที่เกิดครั้งเดียว

LAB 02 · MODER / PUPDR / AFR

หนึ่งขา หลายบทบาท

INPUT
OUTPUT
AF TIM2

ขา PA5 ใช้เป็น GPIO output หรือ alternate function ของ TIM2 ได้ แต่เป็นสองโหมดพร้อมกันไม่ได้ การตั้ง mode จึงต้องมาก่อนการใช้งานเสมอ

ลองกับโปรแกรมจริง →

LAB 03 · INPUT / PULL-UP

ปุ่ม Active-low กลับตรรกะ

ขา PB4 = 1 (HIGH)

โปรแกรมอ่านว่า ไม่กด

เมื่อไม่กด pull-up ทำให้ขาอ่านเป็น 1 และเมื่อกดสวิตช์จะต่อกราวด์จนอ่านเป็น 0 โปรแกรมจึงต้องแปลระดับต่ำว่า “กำลังกด”

ลองกับโปรแกรมจริง →

LAB 04 · 10–30 ms

หน้าสัมผัสเด้ง ไม่ได้เปลี่ยนครั้งเดียว

event จะออกหลังสัญญาณนิ่งต่อเนื่อง

ปุ่มจริงสร้างขอบสัญญาณหลายครั้งในช่วงไม่กี่มิลลิวินาที ตัวกรอง debounce รอให้สัญญาณนิ่งก่อนออก press event เพียงหนึ่งครั้ง

ลองกับโปรแกรมจริง →

LAB 05 · MAIN LOOP / NVIC

Polling กับ Interrupt

POLLING

CPU ตรวจซ้ำทุก loop

INTERRUPT

ตื่นเมื่อมี event

Polling ตรวจอินพุตทุก loop ส่วน EXTI แจ้ง CPU เมื่อเกิดขอบสัญญาณ งานใน ISR ควรสั้นและส่งต่อด้วย flag ให้ main loop จัดการ

ลองกับโปรแกรมจริง →

02

Sampling, quantization, scaling

วัดโลกจริงด้วย ADC

เปลี่ยนแรงดันจากโพเทนชิโอมิเตอร์ NTC และ LDR ให้เป็นค่าดิจิทัลที่ใช้ตัดสินใจหรือควบคุมเอาต์พุตได้

  • อธิบายความหมายของค่าดิบ 12-bit
  • แปลงช่วงด้วย integer arithmetic อย่างปลอดภัย

LAB 06 · SAMPLE & HOLD

Sampling จับภาพสัญญาณตามเวลา

ADC เห็นสัญญาณต่อเนื่องเป็นชุดตัวอย่าง ยิ่งเว้นช่วงนานยิ่งพลาดการเปลี่ยนเร็ว แต่การอ่านถี่เกินความจำเป็นก็ใช้เวลา CPU มากขึ้น

ลองกับโปรแกรมจริง →

LAB 07 · 0…4095

12-bit แบ่งแรงดันเป็น 4096 ช่อง

STM32F411 แปลงแรงดันอ้างอิง 0–3.3 V เป็นรหัสดิจิทัล 0–4095 จึงเกิดขั้น quantization เล็ก ๆ ที่มองเห็นได้เมื่อขยายกราฟ

ลองกับโปรแกรมจริง →

LAB 08 · INTEGER MATH

แปลงช่วงโดยคูณก่อนหาร

3071
ADC raw
×100
÷4095
75%
output

การแปลง 0–4095 ไปเป็น 0–100 ควรใช้ชนิดกว้างพอ คูณก่อนหาร และ cast อย่างชัดเจน เพื่อรักษาความละเอียดและหลีกเลี่ยง overflow

ลองกับโปรแกรมจริง →

03

Frame, baud rate, buffering

สื่อสารกับคอมพิวเตอร์ผ่าน UART

มองข้อมูลตั้งแต่บิตบนสาย TX/RX ไปจนถึงวงแหวนรับข้อมูลแบบ interrupt และ protocol คำสั่งที่ main loop เข้าใจ

  • อ่านองค์ประกอบของเฟรม 8N1
  • อธิบายว่าทำไม RX interrupt ต้องมี buffer

LAB 09 · 115200 8N1

UART ส่งหนึ่งเฟรมทีละบิต

0
1
0
1
0
0
0
1
0
1
START8 DATA BITS (LSB FIRST)STOP

สาย TX ว่างเป็นระดับสูง จากนั้นส่ง start bit, ข้อมูล 8 บิตแบบ LSB ก่อน และ stop bit โดยผู้ส่งกับผู้รับต้องตั้ง baud rate ตรงกัน

ลองกับโปรแกรมจริง →

LAB 10 · RX INTERRUPT

วงแหวนช่วยไม่ให้ byte หาย

A
B
C
D
·
·
·
·

READ → วนกลับเมื่อถึงช่องสุดท้าย → WRITE

ISR เก็บอักขระที่ตำแหน่ง write แล้วขยับ index แบบวนกลับ ส่วน main loop อ่านจาก read index ทั้งสองส่วนจึงทำงานคนละหน้าที่

ลองกับโปรแกรมจริง →

04

Duty, frequency, software vs timer

ควบคุมกำลังด้วย PWM

สร้างความสว่าง LED แบบต่อเนื่องด้วยสัดส่วน high/low และเปรียบเทียบ PWM ที่ main loop สร้างกับฮาร์ดแวร์ TIM2

  • แยกผลของ duty กับ frequency
  • คำนวณความสัมพันธ์ PSC, ARR และ CCR

LAB 11 · 0–100%

Duty cycle กำหนดพลังงานเฉลี่ย

HIGH 65% / LOW 35%

เมื่อความถี่เร็วพอ ตาเห็น LED สว่างตามสัดส่วนเวลาที่สัญญาณเป็น high ไม่ได้เห็นการกระพริบแต่ละครั้ง

ลองกับโปรแกรมจริง →

LAB 12 · TIM2

Prescaler และ ARR กำหนดความถี่

จำนวนคาบต่อเวลาเพิ่มตาม frequency

Timer นับคล็อกหลังหารด้วย prescaler จนถึง auto-reload แล้วเริ่มรอบใหม่ ค่า CCR กำหนดจุดเปลี่ยนระดับภายในรอบ

ลองกับโปรแกรมจริง →

05

State, control flow, MISRA

ประกอบระบบให้ชัดและตรวจสอบได้

รวมตัวแปร เงื่อนไข ลูป และกฎโครงสร้าง C ให้โปรแกรมหลาย peripheral ยังอ่านง่าย ทดสอบได้ และคาดเดาพฤติกรรมได้

  • ออกแบบ state ที่พอดีกับโจทย์
  • ใช้โครงสร้าง MISRA-oriented ในโค้ดที่สร้าง

LAB 13 · STATE / IF / WHILE

ตัวแปร เงื่อนไข และ Loop สร้างพฤติกรรม

INPUT
IF
FALSE
STATE
45
↻ LOOP

ตัวแปรจำอดีต เงื่อนไขเลือกทาง และ loop ทำให้ระบบตอบสนองต่ออินพุตซ้ำ ๆ การแบ่งแต่ละบทบาทชัดเจนทำให้แก้โจทย์ซับซ้อนได้

ลองกับโปรแกรมจริง →

LAB 14 · EXPLICIT / BOUNDED

โครงสร้าง MISRA ทำให้เจตนาชัด

กำหนดค่าเริ่มต้น
while (true)
else ครบ
explicit cast
จำกัด loop
English comments

กำหนดค่าเริ่มต้น ใช้ true ในลูป ใส่ else ให้ครบ cast เมื่อชนิดเปลี่ยน และจำกัดขอบเขต ช่วยให้ทั้งคนอ่านและ static analyzer ตรวจพฤติกรรมได้

ลองกับโปรแกรมจริง →