สารบัญ:

ไมโครคอนโทรลเลอร์ AVR สลับ LED โดยใช้สวิตช์ปุ่มกด กดปุ่ม Deboucing.: 4 ขั้นตอน
ไมโครคอนโทรลเลอร์ AVR สลับ LED โดยใช้สวิตช์ปุ่มกด กดปุ่ม Deboucing.: 4 ขั้นตอน

วีดีโอ: ไมโครคอนโทรลเลอร์ AVR สลับ LED โดยใช้สวิตช์ปุ่มกด กดปุ่ม Deboucing.: 4 ขั้นตอน

วีดีโอ: ไมโครคอนโทรลเลอร์ AVR สลับ LED โดยใช้สวิตช์ปุ่มกด กดปุ่ม Deboucing.: 4 ขั้นตอน
วีดีโอ: AVR Microcontroller. Toggle LED’s using a Push Button Switch. Push Button Debouncing. 2024, กรกฎาคม
Anonim
Image
Image

ในส่วนนี้ เราจะเรียนรู้วิธีสร้างรหัสโปรแกรม C สำหรับ ATMega328PU เพื่อสลับสถานะของ LED สามดวงตามอินพุตจากสวิตช์ปุ่ม นอกจากนี้เรายังได้สำรวจวิธีแก้ปัญหาคือ 'Switch Bounce' ตามปกติเราจะประกอบวงจรไฟฟ้าบนฐานของ AVR ATmega328 เพื่อตรวจสอบการทำงานของรหัสโปรแกรม

ขั้นตอนที่ 1: การเขียนและสร้างแอปพลิเคชันไมโครคอนโทรลเลอร์ AVR ในรหัส C โดยใช้แพลตฟอร์มการพัฒนาแบบบูรณาการ Atmel Studio 7

การเขียนและสร้างแอปพลิเคชันไมโครคอนโทรลเลอร์ AVR ในรหัส C โดยใช้แพลตฟอร์มการพัฒนาแบบบูรณาการ Atmel Studio 7
การเขียนและสร้างแอปพลิเคชันไมโครคอนโทรลเลอร์ AVR ในรหัส C โดยใช้แพลตฟอร์มการพัฒนาแบบบูรณาการ Atmel Studio 7
การเขียนและสร้างแอปพลิเคชันไมโครคอนโทรลเลอร์ AVR ในรหัส C โดยใช้แพลตฟอร์มการพัฒนาแบบบูรณาการ Atmel Studio 7
การเขียนและสร้างแอปพลิเคชันไมโครคอนโทรลเลอร์ AVR ในรหัส C โดยใช้แพลตฟอร์มการพัฒนาแบบบูรณาการ Atmel Studio 7
การเขียนและสร้างแอปพลิเคชันไมโครคอนโทรลเลอร์ AVR ในรหัส C โดยใช้แพลตฟอร์มการพัฒนาแบบบูรณาการ Atmel Studio 7
การเขียนและสร้างแอปพลิเคชันไมโครคอนโทรลเลอร์ AVR ในรหัส C โดยใช้แพลตฟอร์มการพัฒนาแบบบูรณาการ Atmel Studio 7

หากคุณไม่มี Atmel Studio คุณควรดาวน์โหลดและติดตั้ง

www.microchip.com/mplab/avr-support/atmel-studio-7

สองสามบรรทัดแรกที่เรามีบางคอมไพเลอร์กำหนด

F_CPU กำหนดความถี่สัญญาณนาฬิกาในเฮิรตซ์และเป็นเรื่องปกติในโปรแกรมที่ใช้ไลบรารี avr-libc ในกรณีนี้ รูทีนการหน่วงเวลาจะใช้เพื่อกำหนดวิธีการคำนวณการหน่วงเวลา

#ifndef F_CPU

#define F_CPU 16000000UL // บอกความถี่คริสตัลคอนโทรลเลอร์ (16 MHz AVR ATMega328P) #endif

#include // ส่วนหัวเพื่อเปิดใช้งานการควบคุมการไหลของข้อมูลบนพิน กำหนดพิน พอร์ต ฯลฯ

ไฟล์รวมแรกเป็นส่วนหนึ่งของ avr-libc และจะถูกใช้ในโครงการ AVR ที่คุณทำงานอยู่เกือบทั้งหมด io.h จะกำหนด CPU ที่คุณใช้ (ซึ่งเป็นสาเหตุที่คุณระบุส่วนเมื่อคอมไพล์) และรวมส่วนหัวคำจำกัดความ IO ที่เหมาะสมสำหรับชิปที่เราใช้อยู่ มันเพียงกำหนดค่าคงที่สำหรับพิน พอร์ต รีจิสเตอร์พิเศษ ฯลฯ ทั้งหมดของคุณ

#include // ส่วนหัวเพื่อเปิดใช้งานฟังก์ชั่นการหน่วงเวลาในโปรแกรม

util/delay.h ไลบรารี่มีรูทีนบางอย่างสำหรับการดีเลย์สั้นๆ ฟังก์ชันที่เราจะใช้คือ _delay_ms()

เราใช้การกำหนดเพื่อประกาศปุ่มและพอร์ตและพินของ LED และ LED การใช้คำสั่ง define แบบนี้ทำให้เราต้องแก้ไข 3 บรรทัดที่หาง่ายเท่านั้น ถ้าเราย้าย LED ไปยังพิน I/O อื่นหรือใช้ AVR อื่น

#define BUTTON1 1 // สวิตช์ปุ่มเชื่อมต่อกับพอร์ต B ขา 1

#define LED1 0 // Led1 เชื่อมต่อกับพอร์ต B pin 0 #define LED2 1 // Led2 เชื่อมต่อกับพอร์ต C pin 1 #define LED3 2 // Led3 เชื่อมต่อกับพอร์ต D pin 2

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

#define DEBOUNCE_TIME 25 // เวลาที่รอขณะปุ่ม "ยกเลิกการตีกลับ"

#define LOCK_INPUT_TIME 300 // เวลารอหลังจากกดปุ่ม

เป็นโมฆะ init_ports_mcu()

{

ฟังก์ชันนี้ถูกเรียกเพียงครั้งเดียวในช่วงเริ่มต้นของโปรแกรมของเรา เพื่อเริ่มต้นอินพุตเอาต์พุตพินที่เราจะใช้

สำหรับปุ่ม เราจะใช้ PORT และ PIN ลงทะเบียนสำหรับการเขียนและการอ่าน ด้วย AVR เราอ่านพินโดยใช้การลงทะเบียน PINx และเราเขียนไปยังพินโดยใช้การลงทะเบียน PORTx เราจำเป็นต้องเขียนถึงปุ่มลงทะเบียนเพื่อเปิดใช้งานการดึงข้อมูล

สำหรับ LED เราจำเป็นต้องใช้ PORT register เพื่อเขียนเท่านั้น อย่างไรก็ตาม เรายังต้องใช้ data direction register (DDR) เนื่องจากพิน I/O ถูกตั้งค่าเป็นอินพุตโดยค่าเริ่มต้น

ขั้นแรก เรากำลังตั้งค่าพิน I/O ของ LED เป็นเอาต์พุตโดยใช้การลงทะเบียนทิศทางข้อมูล

DDRB=0xFFu; // ตั้งค่าพินทั้งหมดของ PORTB เป็นเอาต์พุต

ถัดไป ตั้งค่าพินของปุ่มเป็นอินพุตอย่างชัดเจน

DDRB &= ~(1<

ถัดไป พิน PORTB ถูกตั้งค่าสูง (+5 โวลต์) เพื่อเปิดใช้งาน พินเอาต์พุตสูงในขั้นต้น และเนื่องจาก LED ของเราต่อสายแบบแอ็คทีฟสูง ไฟจะถูกเปิดเว้นแต่เราจะปิดมันอย่างชัดแจ้ง

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

PORTB = 0xFF; // ตั้งค่าพินทั้งหมดของ PORTB เป็น HIGH ไฟ LED เปิดอยู่

// ยังเปิดใช้งานตัวต้านทาน Pull Up ภายในของพิน PORTB แรกด้วย DDRC=0xFFu; // ตั้งค่าพินทั้งหมดของ PORTC เป็นเอาต์พุต PORTC=0x00u; // ตั้งค่าพินทั้งหมดของ PORTC ให้ต่ำ ซึ่งจะปิด DDRD=0xFFu; // ตั้งค่าพินทั้งหมดของ PORTD เป็นเอาต์พุต PORTD=0x00u; // ตั้งค่าพินทั้งหมดของ PORTD ให้ต่ำ ซึ่งจะปิด }

ถ่านที่ไม่ได้ลงชื่อ button_state()

{

ฟังก์ชันนี้จะคืนค่าบูลีนที่ระบุว่ามีการกดปุ่มหรือไม่ นี่คือบล็อกของรหัสที่มีการดำเนินการอย่างต่อเนื่องในลูปที่ไม่มีที่สิ้นสุดและด้วยเหตุนี้จึงเป็นการสำรวจสถานะของปุ่ม นี่คือที่ที่เรายกเลิกสวิตช์

ตอนนี้ จำไว้ว่าเมื่อเรากดสวิตช์ พินเอาท์พุตอินพุตจะถูกดึงลงกับพื้น ดังนั้นเราจึงรอให้พินลดต่ำลง

/* ปุ่มถูกกดเมื่อ BUTTON1 บิตชัดเจน */

ถ้า (!(PINB & (1<

เราทำเช่นนั้นโดยตรวจสอบว่าบิตนั้นชัดเจนหรือไม่ หากบิตชัดเจน ซึ่งแสดงว่าปุ่มถูกกด ขั้นแรกเราจะหน่วงเวลาตามระยะเวลาที่กำหนดโดย DEBOUNCE_TIME ซึ่งก็คือ 25 มิลลิวินาที จากนั้นให้ตรวจสอบสถานะของปุ่มอีกครั้ง หากปุ่มถูกกดหลังจาก 25 มิลลิวินาที สวิตช์จะถือว่าถูกดีบักและพร้อมที่จะทริกเกอร์เหตุการณ์ ดังนั้นเราจะคืนค่า 1 ไปที่รูทีนการโทรของเรา หากปุ่มไม่ถูกกด เราจะคืนค่า 0 ไปที่รูทีนการโทรของเรา

_delay_ms(DEBOUNCE_TIME);

ถ้า (!(PINB & (1<

int หลัก (เป็นโมฆะ)

{

กิจวัตรหลักของเรา ฟังก์ชันหลักมีเอกลักษณ์เฉพาะตัวและแตกต่างจากฟังก์ชันอื่นๆ ทั้งหมด โปรแกรม C ทุกโปรแกรมต้องมีฟังก์ชัน main() เพียงฟังก์ชันเดียว หลักคือจุดที่ AVR เริ่มรันโค้ดของคุณเมื่อเปิดเครื่องครั้งแรก จึงเป็นจุดเริ่มต้นของโปรแกรม

ถ่านที่ไม่ได้ลงชื่อ n_led = 1; // เริ่มแรก LED จำนวนตอนนี้

การเรียกใช้ฟังก์ชันเพื่อเริ่มต้นพิน I/O ที่ใช้:

init_ports_mcu();

วนไม่สิ้นสุดที่โปรแกรมของเราทำงาน:

ในขณะที่ (1)

{

เมื่อ button_state ส่งคืนค่าหนึ่งที่ระบุว่ามีการกดปุ่มและ debounce จากนั้นจึงสลับสถานะปัจจุบันของ LED ตามพารามิเตอร์ n_led

if (button_state()) // หากกดปุ่ม ให้สลับสถานะของ LED และหน่วงเวลา 300ms (#define LOCK_INPUT_TIME)

{ สวิตช์ (n_led) { กรณีที่ 1: PORTB ^= (1<<LED1); PORTC ^= (1<<LED2); หยุดพัก;

คำสั่งเหล่านี้ใช้ตัวดำเนินการระดับบิต C คราวนี้ใช้โอเปอเรเตอร์ OR แบบเอกสิทธิ์เฉพาะบุคคล เมื่อคุณ XOR PORT ด้วยค่าบิตของบิตที่คุณต้องการสลับ บิตหนึ่งจะถูกเปลี่ยนโดยไม่ส่งผลต่อบิตอื่นๆ

กรณีที่ 2:

PORTC ^= (1<<LED2); PORTD ^= (1<<LED3); หยุดพัก; กรณีที่ 3: PORTD ^= (1<<LED3); PORTB ^= (1<<LED1); n_led=0; // รีเซ็ตตัวแบ่งตัวเลข LED; } n_led++; // LED ถัดไปเปิด _delay_ms(LOCK_INPUT_TIME); } } ส่งคืน (0); }

ดังนั้น เมื่อคุณรันโปรแกรมนี้ คุณควรจะสามารถกดปุ่มเพื่อสลับ LED ได้ เนื่องจากความล่าช้าของเรากำหนดโดย LOCK_INPUT_TIME คุณสามารถกดปุ่มค้างไว้ซึ่งจะทำให้ไฟ LED ปิดและเปิดในอัตราที่สม่ำเสมอ (มากกว่าทุกๆ 275ms เล็กน้อย)

การเขียนโปรแกรมเสร็จสมบูรณ์

ขั้นตอนต่อไปคือการสร้างโปรเจ็กต์และเขียนโปรแกรมไฟล์ hex ลงในไมโครคอนโทรลเลอร์โดยใช้โปรแกรม avrdude

คุณสามารถดาวน์โหลดไฟล์ main.c ด้วยโปรแกรมในรหัส c:

ขั้นตอนที่ 2: ถ่ายโอนไฟล์ HEX ของโปรแกรมไปยังหน่วยความจำแฟลชของ Chip

การถ่ายโอนไฟล์ HEX ของโปรแกรมไปยังหน่วยความจำแฟลชของ Chip
การถ่ายโอนไฟล์ HEX ของโปรแกรมไปยังหน่วยความจำแฟลชของ Chip
การถ่ายโอนไฟล์ HEX ของโปรแกรมไปยังหน่วยความจำแฟลชของ Chip
การถ่ายโอนไฟล์ HEX ของโปรแกรมไปยังหน่วยความจำแฟลชของ Chip

ดาวน์โหลดและติดตั้ง AVRDUDE เวอร์ชันล่าสุดที่มีคือ 6.3: ดาวน์โหลดไฟล์ zip

ขั้นแรก ให้คัดลอกไฟล์ฐานสิบหกของโปรแกรมไปที่ไดเร็กทอรี AVRDUDE ในกรณีของฉันคือ ButtonAVR.hex

จากนั้นพิมพ์คำสั่งในหน้าต่างพรอมต์ DOS: avrdude –c [ชื่อโปรแกรมเมอร์] –p m328p –u –U flash:w:[ชื่อไฟล์ hex ของคุณ]

ในกรณีของฉันคือ: avrdude –c ISPProgv1 –p m328p –u –U flash:w:ButtonAVR.hex

คำสั่งนี้เขียนไฟล์ฐานสิบหกลงในหน่วยความจำของไมโครคอนโทรลเลอร์

ดูวิดีโอพร้อมคำอธิบายโดยละเอียดของการเบิร์นหน่วยความจำแฟลชของไมโครคอนโทรลเลอร์:

การเบิร์นหน่วยความจำแฟลชไมโครคอนโทรลเลอร์…

ตกลง! ตอนนี้ไมโครคอนโทรลเลอร์ทำงานตามคำแนะนำของโปรแกรมของเรา มาลองดูกัน!

ขั้นตอนที่ 3: ฮาร์ดแวร์สวิตช์ Debounding

ฮาร์ดแวร์สวิตช์ Debounding
ฮาร์ดแวร์สวิตช์ Debounding

นอกเหนือจาก Software switch debounding แล้ว เรายังสามารถใช้เทคนิค hardware switch debounding ได้อีกด้วย แนวคิดพื้นฐานที่อยู่เบื้องหลังเทคนิคดังกล่าวคือการใช้ตัวเก็บประจุเพื่อกรองการเปลี่ยนแปลงอย่างรวดเร็วในสัญญาณสวิตช์

ควรเลือกตัวเก็บประจุค่าใด? ในที่สุดนี้จะขึ้นอยู่กับประสิทธิภาพของปุ่มเกี่ยวกับปัญหานี้โดยเฉพาะ ปุ่มบางปุ่มสามารถแสดงพฤติกรรมการตีกลับอย่างมาก แต่บางปุ่มอาจมีน้อยมาก ค่าตัวเก็บประจุต่ำ เช่น 1.0 nanofarads จะตอบสนองเร็วมาก โดยมีผลเพียงเล็กน้อยหรือไม่มีเลยต่อการกระดอน ในทางกลับกัน ค่าตัวเก็บประจุที่สูงกว่า เช่น 220 นาโนฟารัด (ซึ่งยังค่อนข้างเล็กในแง่ของตัวเก็บประจุ) จะทำให้การเปลี่ยนแปลงช้าจากจุดเริ่มต้นเป็นแรงดันสิ้นสุด (5 โวลต์ถึง 0 โวลต์) อย่างไรก็ตาม การเปลี่ยนแปลงที่เห็นด้วยความจุ 220 นาโนฟารัดนั้นยังค่อนข้างเร็วในโลกแห่งความเป็นจริง ดังนั้นจึงสามารถใช้กับปุ่มที่มีประสิทธิภาพต่ำได้

ขั้นตอนที่ 4: วงจรไฟฟ้า

วงจรไฟฟ้า
วงจรไฟฟ้า
วงจรไฟฟ้า
วงจรไฟฟ้า
วงจรไฟฟ้า
วงจรไฟฟ้า

เชื่อมต่อส่วนประกอบตามแผนผังไดอะแกรม

แนะนำ: