- เตรียมฮาร์ดแวร์ให้พร้อม
- ทำความเข้าใจ GPIO Pinouts บน STM8S103F
- คำอธิบาย Pinout และคำแนะนำสำหรับการเลือก GPIO STM8S103F
- การเขียนโปรแกรม STM8S สำหรับอินพุตและเอาต์พุต GPIO โดยใช้ SPL
- การอัปโหลดและทดสอบโปรแกรม
สำหรับไมโครคอนโทรลเลอร์โปรแกรมไฟ LED กะพริบจะเทียบเท่ากับโปรแกรม“ hello world” ในบทช่วยสอนก่อนหน้านี้เราได้เรียนรู้วิธีเริ่มต้นใช้งาน STM8S103F3 Development Board และวิธีตั้งค่า IDE และคอมไพเลอร์เพื่อตั้งโปรแกรมคอนโทรลเลอร์ STM8S ของเรา นอกจากนี้เรายังได้เรียนรู้วิธีใช้ไลบรารีอุปกรณ์ต่อพ่วงมาตรฐานและวิธีรวบรวมและอัปโหลดโค้ดลงในไมโครคอนโทรลเลอร์ของเรา ด้วยพื้นฐานทั้งหมดที่ครอบคลุมมาเริ่มเขียนโค้ดกันเลย ในบทช่วยสอนนี้เราจะเรียนรู้วิธีการใช้งานฟังก์ชัน GPIO ทั่วไปบนคอนโทรลเลอร์ STM8S บอร์ดมี LED ออนบอร์ดที่เชื่อมต่อกับพิน 5 ของพอร์ต B อยู่แล้วเราจะเรียนรู้วิธีการกะพริบ LED นี้และเพิ่ม LED ภายนอกและควบคุมด้วยปุ่มกด หากคุณเป็นมือใหม่ขอแนะนำอย่างยิ่งให้อ่านบทช่วยสอนก่อนหน้านี้ก่อนดำเนินการต่อ
เตรียมฮาร์ดแวร์ให้พร้อม
ก่อนที่เราจะดำน้ำในโปรแกรมให้เตรียมการเชื่อมต่อฮาร์ดแวร์ให้พร้อม ดังที่ได้กล่าวไว้ในตอนต้นเราจะใช้ LED สองดวงที่นี่หนึ่งคือ LED ออนบอร์ดซึ่งจะกะพริบอย่างต่อเนื่องและอีกดวงเป็น LED ภายนอกซึ่งจะสลับด้วยปุ่มกด แนวคิดคือการเรียนรู้ฟังก์ชัน GPIO ทั้งหมดในการตั้งค่าง่ายๆ LED ออนบอร์ดเชื่อมต่อกับ PB5 แล้ว (พิน 5 ของ PORTB) ดังนั้นฉันจึงเพิ่งเชื่อมต่อ LED กับ PA3 และปุ่มกดกับ PA2 ดังที่คุณเห็นในแผนภาพด้านล่าง
แต่จากพินเอาต์พุตทั้งหมดที่มีอยู่ในการควบคุมของเราเหตุใดฉันจึงเลือก PA3 สำหรับเอาต์พุตและ PA2 สำหรับอินพุต คำถามนั้นถูกต้องและฉันจะอธิบายในบทความนี้ในภายหลัง การตั้งค่าฮาร์ดแวร์ของฉันสำหรับบทช่วยสอนนี้แสดงอยู่ด้านล่าง อย่างที่คุณเห็นฉันได้เชื่อมต่อโปรแกรมเมอร์ ST-link ของฉันกับพินการเขียนโปรแกรมซึ่งไม่เพียง แต่จะตั้งโปรแกรมบอร์ดของเรา แต่ยังทำหน้าที่เป็นแหล่งพลังงานด้วย
ทำความเข้าใจ GPIO Pinouts บน STM8S103F
ตอนนี้กลับมาที่คำถามทำไม PA2 สำหรับอินพุตและทำไม PA3 สำหรับเอาต์พุต? เพื่อให้เข้าใจถึงสิ่งนั้นลองมาดู pinout ของไมโครคอนโทรลเลอร์ซึ่งแสดงไว้ด้านล่าง
ตามแผนภาพพินเอาต์เรามีพอร์ตสี่พอร์ตในไมโครคอนโทรลเลอร์ของเรา ได้แก่ พอร์ต A, B, C และ D แสดงโดย PA, PB, PC และ PD ตามลำดับ พิน GPIO แต่ละอันยังมาพร้อมกับฟังก์ชันพิเศษอื่น ๆ ตัวอย่างเช่น PB5 (พิน 5 ของ PORT B) ไม่เพียง แต่ทำงานเป็นพิน GPIO เท่านั้น แต่ยังใช้เป็นพิน SDA สำหรับการสื่อสาร I2C และเป็นพินเอาต์พุตของ Timer 1 ดังนั้นหากเราใช้พินนี้เพื่อวัตถุประสงค์ GPIO ง่ายๆเช่นการเชื่อมต่อ LED เราจะไม่สามารถใช้ I2C และ LED ในเวลาเดียวกันได้ น่าเสียดายที่ LED ออนบอร์ดเชื่อมต่อกับพินนี้ดังนั้นเราจึงไม่มีทางเลือกมากนักที่นี่และในโปรแกรมนี้เราจะไม่ใช้ I2C ดังนั้นจึงไม่มีปัญหามากนัก
คำอธิบาย Pinout และคำแนะนำสำหรับการเลือก GPIO STM8S103F
พูดตามความจริงมันไม่เจ็บที่จะใช้ PA1 พินอินพุตและมันก็ใช้งานพินได้ แต่ฉันจงใจนำสิ่งนี้ขึ้นมาเพื่อให้ฉันมีโอกาสแสดงกับดักทั่วไปบางอย่างที่คุณอาจตกอยู่ในการเลือกพิน GPIO บนไมโครคอนโทรลเลอร์ตัวใหม่ วิธีที่ดีที่สุดในการหลีกเลี่ยงกับดักคือการอ่านรายละเอียดพินและคำอธิบายพินที่ให้ไว้ในแผ่นข้อมูล STM8S103F3P6 สำหรับรายละเอียดคำอธิบายพินไมโครคอนโทรลเลอร์ STM8S103F3P6 ที่ระบุไว้ในแผ่นข้อมูลแสดงอยู่ด้านล่างภาพ
พินอินพุตบนไมโครคอนโทรลเลอร์ของเราอาจเป็นแบบลอยตัวหรือแบบดึงขึ้นอย่างอ่อนก็ได้และพินเอาต์พุตอาจเป็นแบบเปิดหรือแบบดัน ความแตกต่างระหว่างพิน Open Drain และ Push-Pull Output ได้รับการกล่าวถึงแล้วดังนั้นเราจะไม่ลงรายละเอียดของสิ่งนั้น เพื่อให้เข้าใจง่ายขาเอาท์พุท Open Drain สามารถทำให้เอาต์พุตต่ำไม่สูงเท่าในขณะที่พินเอาต์พุตแบบกดดึงสามารถทำให้เอาต์พุตทั้งสูงและสูง
นอกเหนือจากตารางด้านบนคุณยังสามารถสังเกตได้ว่าขาเอาต์พุตอาจเป็นเอาต์พุตแบบเร็ว (10 Mhz) หรือเอาต์พุตช้า (2 MHz) สิ่งนี้กำหนดความเร็ว GPIO หากคุณต้องการสลับพิน GPIO ระหว่างสูงและต่ำเร็วมากเราสามารถเลือกเอาต์พุตแบบเร็วได้
หมุด GPIO บางตัวบนคอนโทรลเลอร์ของเรารองรับTrue Open Drain (T)และHigh Sink Current (HS)ดังที่กล่าวไว้ในภาพด้านบน ความแตกต่างอย่างมากระหว่าง Open Drain และ True Open Drain คือไม่สามารถดึงเอาท์พุทที่เชื่อมต่อกับท่อระบายน้ำแบบเปิดได้สูงกว่าแรงดันไฟฟ้าที่ใช้งานของไมโครคอนโทรลเลอร์ (Vdd) ในขณะที่ขาเอาท์พุทท่อระบายน้ำจริงสามารถดึงได้สูงกว่า Vdd พินที่มีความสามารถในการซิงก์สูงหมายความว่าสามารถจมกระแสได้มากขึ้น แหล่งจ่ายและกระแสไฟจมของพิน GPIO HS คือ 20mA ในขณะที่สายไฟสามารถใช้พลังงานได้ถึง 100 mA
จากภาพด้านบนคุณจะสังเกตเห็นว่าหมุด GPIO เกือบทั้งหมดเป็นประเภท High Sink Current (HS) ยกเว้น PB4 และ PB5 ซึ่งเป็น True Open Drain Type (T) ซึ่งหมายความว่าพินเหล่านี้ไม่สามารถทำให้สูงได้พวกเขาจะไม่สามารถให้ 3.3V ได้แม้ว่าพินจะสูงก็ตาม นี่คือสาเหตุที่ไฟ LED ออนบอร์ดเชื่อมต่อกับ 3.3V และต่อสายดินผ่าน PB5 แทนที่จะจ่ายไฟโดยตรงจากพิน GPIO
อ้างอิงถึงหน้า 28 ในแผ่นข้อมูลสำหรับคำอธิบายพินโดยละเอียด ดังที่ได้กล่าวไว้ในภาพด้านบน PA1 ได้รับการกำหนดค่าโดยอัตโนมัติเป็นแบบดึงขึ้นที่อ่อนแอและไม่แนะนำให้ใช้เป็นพินเอาต์พุต อย่างไรก็ตามมันสามารถใช้เป็นพินอินพุตพร้อมกับปุ่มกดได้ แต่ฉันตัดสินใจใช้ PA2 เพียงเพื่อลองเปิดใช้งานการดึงขึ้นจากโปรแกรม สิ่งเหล่านี้เป็นเพียงสิ่งพื้นฐานบางประการซึ่งจะเป็นประโยชน์เมื่อเราเขียนโปรแกรมที่ซับซ้อนมากขึ้น สำหรับตอนนี้มันโอเคถ้าหลาย ๆ อย่างเด้งออกมาจากหัวของคุณเราจะเข้าสู่เลเยอร์นั้นในบทแนะนำอื่น
การเขียนโปรแกรม STM8S สำหรับอินพุตและเอาต์พุต GPIO โดยใช้ SPL
สร้างพื้นที่ทำงานและโครงการใหม่ตามที่เราพูดถึงในบทช่วยสอนแรกของเรา คุณสามารถเพิ่มไฟล์ส่วนหัวและไฟล์ต้นฉบับทั้งหมดหรือเพิ่มเฉพาะไฟล์ gpio, config และ stm8s เปิดไฟล์ main.c และเริ่มเขียนโปรแกรมของคุณ
ตรวจสอบให้แน่ใจว่าคุณได้รวมไฟล์ส่วนหัวตามที่แสดงในภาพด้านบน เปิดไฟล์ main.c และเริ่มต้นรหัส คุณสามารถดูรหัส main.c ที่สมบูรณ์ได้ที่ด้านล่างของหน้านี้และคุณจะสามารถดาวน์โหลดไฟล์โครงการได้จากที่นั่น คำอธิบายของรหัสมีดังต่อไปนี้คุณสามารถดูคู่มือผู้ใช้ SPL หรือวิดีโอที่เชื่อมโยงที่ด้านล่างของหน้านี้หากคุณสับสนเกี่ยวกับส่วนการเข้ารหัส
การยกเลิกการเตรียมใช้งานพอร์ตที่ต้องการ
เราเริ่มโปรแกรมของเราโดยการยกเลิกการเริ่มต้นพอร์ตที่ต้องการ ดังที่เราได้กล่าวไว้ก่อนหน้านี้พิน GPIO แต่ละตัวจะมีฟังก์ชันอื่น ๆ อีกมากมายที่เกี่ยวข้องนอกเหนือจากการทำงานเหมือนอินพุตและเอาต์พุตปกติ หากพินเหล่านี้เคยใช้กับแอพพลิเคชั่นอื่นมาก่อนก็ควรยกเลิกการเตรียมใช้งานก่อนที่เราจะใช้ ไม่บังคับ แต่เป็นแนวทางปฏิบัติที่ดี โค้ดสองบรรทัดต่อไปนี้ใช้เพื่อยกเลิกการเตรียมใช้งานพอร์ต A และพอร์ต B เพียงใช้ไวยากรณ์ GPIO_DeInit (GPIOx) และระบุชื่อพอร์ตแทน x
GPIO_DeInit (GPIOA); // เตรียม Port A สำหรับการทำงาน GPIO_DeInit (GPIOB); // เตรียมพอร์ต B สำหรับการทำงาน
อินพุตและเอาต์พุต GPIO Declaration
ต่อไปเราต้องประกาศว่าพินใดที่จะใช้เป็นอินพุตและอันไหนเป็นเอาต์พุต ในกรณีของเราพิน PA2 จะถูกใช้เป็นอินพุตเราจะประกาศพินนี้ด้วย Pull-up ภายในเพื่อที่เราจะได้ไม่ต้องใช้พินภายนอก ไวยากรณ์คือ GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . โดยที่ x คือชื่อพอร์ต y คือหมายเลขพินและ z คือโหมด GPIO Pin
// ประกาศ PA2 เป็นพินดึงอินพุต GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
ต่อไปเราต้องประกาศพิน PA3 และ PB5 เป็นเอาต์พุต การประกาศเอาต์พุตอีกหลายประเภทเป็นไปได้ แต่เราจะใช้ “ GPIO_MODE_OUT_PP_LOW_SLOW” ซึ่งหมายความว่าเราจะประกาศให้เป็นพินเอาต์พุตของประเภท push-pull ด้วยความเร็วที่ช้า และโดยค่าเริ่มต้นค่าจะต่ำ ไวยากรณ์จะเหมือนกัน
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // ประกาศ PB5 เป็นพินพุชดึงขาออก GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
ภาพรวมด้านล่างจากคู่มือผู้ใช้ SPL กล่าวถึงโหมด GPIO ที่เป็นไปได้ทั้งหมด (z)
ไม่มีที่สิ้นสุดในขณะที่วนซ้ำ
หลังจากการประกาศพินเราจำเป็นต้องสร้างลูปที่ไม่มีที่สิ้นสุดภายในซึ่งเราจะกะพริบ LED ตลอดไปและตรวจสอบสถานะของปุ่มกดเพื่อสลับ LED ห่วงอนันต์ทั้งสามารถสร้างด้วย ในขณะที่ (1) หรือสำหรับ(;;) ที่นี่ฉันใช้ ในขณะที่ (1)
ในขณะที่ (1) {}
ตรวจสอบสถานะของขาอินพุต
เราต้องตรวจสอบสถานะของขาอินพุตไวยากรณ์ที่ต้องทำคือ GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); โดยที่ x คือชื่อพอร์ตและ y คือหมายเลขพิน ถ้าพินสูงเราจะได้ '1' และถ้าพินอยู่ต่ำเราจะได้ '0' เราใช้ใน if ลูปเพื่อตรวจสอบว่าพินสูงหรือต่ำ
ถ้า (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // ถ้ากดปุ่ม
การสร้าง GPIO Pin สูงหรือต่ำ
ในการสร้างพิน GPIO สูงหรือต่ำเราสามารถใช้ GPIO_WriteHigh (GPIOx, GPIO_PIN_y); และ GPIO_WriteLow (GPIOx, GPIO_PIN_y); ตามลำดับ ที่นี่เราได้ทำให้ LED เปิดขึ้นหากกดปุ่มแล้วปิดหากไม่ได้กดปุ่ม
ถ้า (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // ถ้ากดปุ่ม GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED ON อื่น ๆ GPIO_WriteHigh (GPIOA, GPIO_PIN_3); // LED ดับ
การสลับ GPIO Pin
ในการสลับพิน GPIO เรามี GPIO_WriteReverse (GPIOx, GPIO_PIN_y); การเรียกใช้ฟังก์ชันนี้จะเปลี่ยนสถานะของขาเอาต์พุต ถ้าพินสูงจะเปลี่ยนเป็นต่ำและถ้าต่ำจะเปลี่ยนเป็นสูง เรากำลังใช้ฟังก์ชั่นนี้เพื่อกะพริบ LED ออนบอร์ดบน PB5
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
ฟังก์ชันหน่วงเวลา
ซึ่งแตกต่างจาก Arduino ตรงที่คอมไพเลอร์จักรวาลไม่มีฟังก์ชันหน่วงเวลาที่กำหนดไว้ล่วงหน้า ดังนั้นเราต้องสร้างขึ้นมาเอง ฟังก์ชันหน่วงเวลาของฉันได้รับด้านล่าง ค่า doe ความล่าช้าจะได้รับในตัวแปร ms และเราจะใช้สองค่าสำหรับการวนรอบเพื่อเก็บหรือเรียกใช้โปรแกรม Like _asm (“ nop”) คือคำสั่งประกอบที่ย่อมาจาก no operation ซึ่งหมายความว่าคอนโทรลเลอร์จะวนเข้าสู่ลูป for โดยไม่ต้องดำเนินการใด ๆ จึงทำให้เกิดความล่าช้า
ความล่าช้าเป็นโมฆะ (int ms) // นิยามฟังก์ชัน {int i = 0; int j = 0; สำหรับ (i = 0; i <= ms; i ++) {สำหรับ (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // ไม่ดำเนินการ // รหัสประกอบ}}
การอัปโหลดและทดสอบโปรแกรม
เมื่อโปรแกรมของเราพร้อมแล้วเราสามารถอัปโหลดและทดสอบได้ เมื่ออัปโหลดแล้วฮาร์ดแวร์ของฉันทำงานได้ตามที่คาดไว้ ไฟ LED สีแดงบนบอร์ดกะพริบทุกๆ 500 มิลลิวินาทีและไฟ LED สีเขียวภายนอกจะเปิดขึ้นทุกครั้งที่ฉันกดสวิตช์
การทำงานทั้งหมดสามารถพบได้ในวิดีโอที่เชื่อมโยงด้านล่าง เมื่อคุณมาถึงจุดนี้แล้วคุณสามารถลองเชื่อมต่อสวิตช์และ LED กับพินต่างๆและเขียนโค้ดใหม่เพื่อทำความเข้าใจแนวคิด คุณยังสามารถเล่นกับเวลาหน่วงเพื่อตรวจสอบว่าคุณเข้าใจแนวคิดอย่างชัดเจนหรือไม่
หากคุณมีคำถามใด ๆ โปรดทิ้งไว้ในส่วนความคิดเห็นด้านล่างและสำหรับคำถามทางเทคนิคอื่น ๆ คุณสามารถใช้ฟอรัมของเรา ขอขอบคุณที่ติดตามพบกันในบทแนะนำถัดไป