ฉันจะอ่านอินพุตดิจิตอลบน ATmega16 ได้อย่างไร


18

ฉันจะทำอะไรต้องทำเพื่ออ่านสัญญาณแบบดิจิตอล (ปุ่มกด) บนATmega16 ? ฉันต้องเปิดใช้งานตัวต้านทานแบบ pullup หรือฉันสามารถใช้ 10 kohm ได้หรือไม่ รหัสง่ายๆอะไรจะเป็นอย่างไร เพียงแค่ 'เปิดไฟ LED เมื่อมันกด'

มีแบบฝึกหัดสำหรับผู้เริ่มต้นไหม ฉันได้ลองใช้ googling และAVR Freaksแล้ว แต่ทุกสิ่งก็พัฒนาไปสู่การต่อสู้ที่นั่นและฉันก็ไม่ได้รับคำตอบ ฉันไม่พบบทเรียนเกี่ยวกับสิ่งนี้จริงๆ มีสิ่งต่าง ๆ มากมาย แต่ไม่มีอะไรง่าย ๆ เกี่ยวกับไมโครคอนโทรลเลอร์AVRของฉัน...


4
นี้จะได้รับคำตอบในแบบฝึกหัดของผู้เริ่มต้นและฉันกลัวว่าคำตอบที่สมบูรณ์ที่นี่จะบ่อนทำลายความเข้าใจของคุณมากกว่าความช่วยเหลือ คุณพยายามเรียนรู้อะไรมาก่อน?
Yann Vernier

ไม่แน่ใจว่าคุณเห็นโพสต์ของฉันหรือคุณสามารถดูได้ (ขออภัยยังสับสนเกี่ยวกับเว็บไซต์นี้ ... ) แต่ฉันรู้รหัสให้พูดว่าคำถามของฉันคือ: ฉันเพิ่งเชื่อมต่อพินกับ GND และต่ำหรือไม่
อยากรู้อยากเห็น

2
ทำไมไม่แก้ไขโพสต์ของคุณให้ถูกต้องมากกว่านี้และรวมโพสต์ด้านล่างในโพสต์ต้นฉบับด้วย
Amos

ลองจากรอยขีดข่วน AVR กวดวิชาในนี้หน้า AVR ประหลาด คุณจะพบสิ่งต่าง ๆ มากมายที่นั่น
Leon Heller

คำตอบ:


24

สวัสดีชาวบราซิล!

ก่อนอื่นขอบคุณ Joby สำหรับตัวอย่างของคุณ ประการที่สองตัวอย่างของเขามีข้อผิดพลาดเล็กน้อย หมายเลข 0x20 ไม่ถูกต้อง ควรเป็น 0x04 นอกจากนี้เช่นเดียวกับข้อเสนอแนะฉันจะไม่ใช้ตัวเลขฐานสิบหกเช่น 0xFB, 0x20 หรือ 0x04 ในรหัส ฉันขอแนะนำให้ใช้คำจำกัดความพอร์ต PIN ที่พบใน io.h และอื่น ๆ ที่อ้างอิงโดยไฟล์ส่วนหัว ฉันได้เขียนตัวอย่างของ Joby ใหม่ด้านล่างพร้อมความคิดเห็นสำหรับผู้เริ่มต้น

# include <avr/io.h>

int main (void)
{
    // set all pins on PORTB for output
    DDRB = 0xFF;

    // set port pin PORTD2 as input and leave the others pins 
    // in their originally state (inputs or outputs, it doesn't matter)
    DDRD &= ~(1 << PD2);        // see comment #1

    while (1) 
    {
        if (PIND & (1<<PD2))    // see comment #2
            PORTB |= (1<<PB2);  // see comment #3
        else
            PORTB &= ~(1<<PB2); // see comment #4
    }
    return 0;
}

/ *

ความคิดเห็นสำหรับผู้เริ่มต้น

ความคิดเห็น # 1: (1 << PD2) สร้างไบนารี 00000100 การดำเนินการ "~" จะพลิกตัวเลขทั้งหมดเช่นไบนารีตอนนี้คือ 11111011 ในที่สุดเครื่องหมาย & = ใช้ตรรกะ "AND" ระหว่าง DDRD และ 11111011 และวางผลลัพธ์อีกครั้ง ในหน่วยความจำ DDRD หมายเหตุ: สิ่งที่ผู้ประกอบการ "และ" ทำสำหรับแต่ละบิตในหน่วยความจำ DDRD มันเปรียบเทียบกับเลขฐานสองข้างต้น หากบิตใน DDRD เป็น 0 และบิตในไบนารีที่ตำแหน่งการกัดเดียวกันคือ 1 ดังนั้นบิตที่ได้คือ 0 หาก DDRD คือ 1 และบิตในไบนารีเป็น 1 บิตที่ได้คือ 1 และหาก บิตใน DDRD คือ 1 หรือ 0 และบิตในไบนารีคือ 0 ดังนั้นบิตที่ได้คือ 0 เสมอ โดยสรุปคำสั่ง DDRD & = ~ (1 << PD2) เปลี่ยนเพียงบิต PD2 เป็นศูนย์และปล่อยให้คนอื่น (ศูนย์หรือคน) ไม่ถูกแตะต้อง ดูเหมือนว่าจะซับซ้อนเล็กน้อย แต่หลังจากที่คุณชินกับมันแล้วมันเป็นวิธีที่ดีที่สุดในการเปลี่ยนการกัดโดยไม่ต้องเปลี่ยนบิตอื่น ๆ

ความคิดเห็น # 2 : (1 << PD2) สร้างไบนารี 00000100 โดยใช้ตรรกะเดียวกัน "และ" ที่อธิบายไว้ในความคิดเห็น # 1 คำสั่ง "PIND & 0000100" จะตรวจสอบเฉพาะถ้า PIND2 (พินอินพุตของเราที่เชื่อมต่อปุ่มกด ถึง) ตั้งค่าไว้สูงหรือไม่ หมุดอื่น ๆ ทั้งหมดจะเป็น FALSE ตั้งแต่ไบนารีบิตถูกตั้งค่าเป็น 0 และเนื่องจากไบนารีบิต # 2 ถูกตั้งค่าเป็น 1 คำสั่ง IF จะเป็น TRUE เฉพาะถ้าอินพุต PD2 ถูกตั้งค่าเป็นสูงหรือ FALSE ถ้าอินพุต PD2 เป็น ตั้งเป็นต่ำ

ความคิดเห็น # 3 : ตามตรรกะที่อธิบายไว้ในความคิดเห็น # 1 คำสั่งนี้ตั้ง PINB2 เอาท์พุทในพอร์ต PORTB เป็นไฟฟ้าแรงสูง หาก LED ของคุณเชื่อมต่ออย่างถูกต้องกับพอร์ตพินนี้ด้วยตัวต้านทาน ~ 300 โอห์มและตัวต้านทานนั้นเชื่อมต่อกับกราวด์ LED ควรเปิด

ความคิดเห็น # 4 : LED ควรปิดด้วยเหตุผลเดียวกันที่อธิบายไว้ในความคิดเห็นก่อนหน้า

ข้อพิจารณาสุดท้าย:

a) เพื่อหลีกเลี่ยงการสั่นของแรงดันไฟฟ้าในขาอินพุต PD2 เมื่อไม่กดปุ่ม (วงจรเปิด) ฉันแนะนำให้วางตัวต้านทานแบบดึงลง (1 kOhm หรือสูงกว่า) เพื่อไม่ให้ LED ติดสว่างขึ้นโดยไม่ตั้งใจ ถึงการสั่นของแรงดันไฟฟ้าแบบสุ่ม

b) ข้อความปฏิเสธความรับผิดชอบ: แนวคิดที่อธิบายไว้ที่นี่จะใช้เพื่อการศึกษาเท่านั้นและไม่ควรใช้ในระบบจริงใด ๆ ก่อนที่จะปรึกษาผู้เชี่ยวชาญด้านอุปกรณ์อิเล็กทรอนิกส์

* /


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

ในทางกลับกันไม่ได้ - # 3 เลี้ยวไฟเลี้ยวออก # 4 เลี้ยวหลอดไฟ LED ใช่ไหม
sitilge

2

https://www.mainframe.cx/~ckuethe/avr-c-tutorial/

https://www.mainframe.cx/~ckuethe/avr-c-tutorial/#digital-in

#include <avr/io.h>

/*
 * Assumptions:
 *  - LED connected to PORTB.2
 *  - Switch connected to PORTD.2
 */

int main (void)
{
    /* set PORTB for output*/
    DDRB = 0xFF;
    /* set PORTD for input*/
    DDRD &= 0xFB;
    PORTD |= 0x04;

    while (1) {
        if (PIND & 0x04)
            PORTB &= ~0x20;
        else
            PORTB |= 0x20;
    }
    return 0;
}

ขอบคุณที่ @joby Taffey สำหรับลิงก์ที่ให้มา ฉันกำลังค้นหาฟังก์ชั่น EEPROM และฉันได้รับความช่วยเหลือมากมายจาก: mainframe.cx/~ckuethe/avr-c-tutorial/lesson11.cขอบคุณมาก
Bishal Paudel

2

Hackaday มีการเขียนที่ยอดเยี่ยมสำหรับการเขียนโปรแกรม AVR แต่ก็มีข้อมูลจำนวนมากที่สามารถช่วยคุณได้

http://hackaday.com/2010/11/19/avr-programming-04-writing-code-etc/

http://hackaday.com/2010/11/05/avr-programming-03-reading-and-compiling-code/

http://hackaday.com/2010/10/25/avr-programming-02-the-hardware/

http://hackaday.com/2010/10/23/avr-programming-introduction/



0

อย่างอื่นที่ควรพิจารณาเมื่อจัดการกับอินพุตแบบดิจิทัลจากสวิตช์เชิงกลคือผู้ติดต่อที่ตีกลับ - การเปลี่ยนสิ่งที่ควรจะกดปุ่มเดียวเป็นสิ่งที่ดูเหมือนว่าหลายดัน

สำหรับสิ่งที่ต้องการเปิดไฟ LED เมื่อกดปุ่มค้างไว้คุณอาจไม่ต้องกังวลกับการเปิดตัว สำหรับบางสิ่งที่ซับซ้อนกว่าเล็กน้อย (เช่นการสลับไฟ LED บนปุ่มกด) คุณต้องทำการ debouncing

Jack Ganssle มีคำแนะนำที่ดีสำหรับการเปิดตัว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.