การพิจารณาว่าพินใดที่เรียกใช้การขัดจังหวะของ PCINTn


9

ฉันคิดถูกไหมถ้าคุณมีสองพินที่ทำให้เกิดการขัดจังหวะ AVR PCINT แบบเดียวกัน (เช่นเวกเตอร์ PCINT0 ที่เกิดจากพิน PCINT0 หรือ PCINT1 - ฉันคิดว่าการตั้งชื่อซ้อนทับกันของเวกเตอร์และพินนั้นสับสน) วิธีเดียว (s) ที่ทำให้เกิดการขัดจังหวะคือการบันทึกสถานะของพวกเขาหลังจากการขัดจังหวะแต่ละครั้งและเปรียบเทียบค่าก่อนหน้าและปัจจุบันของหมุดทั้งหมดที่เปิดใช้งานใน PCMSKn?


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

@ gl3829 ธงเป็นหมุดต่อกลุ่มถ้าฉันเข้าใจถูกต้อง
Tom Davies

คำตอบ:


11

ฉันคิดว่าการตั้งชื่อเวกเตอร์และหมุดทับซ้อนกันทำให้เกิดความสับสน

มันคือ!

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

ฉันคิดถูกต้องหรือไม่ ... วิธีเดียวในการพิจารณาว่าพินใดทำให้เกิดการขัดจังหวะคือการบันทึกสถานะหลังจากการขัดจังหวะแต่ละครั้งและเปรียบเทียบค่าก่อนหน้าและปัจจุบันของพินทั้งหมดที่เปิดใช้งานใน PCMSKn?

ค่อนข้างมากสมมติว่าคุณใส่ใจเพียง PB0 (PCINT0) และ PB1 (PCINT1) ดังนั้นการเปลี่ยนพินจะเปิดใช้งานมาสก์ PCMSK0 เป็น 0x03

// External Interrupt Setup
...

volatile u_int8 previousPins = 0; 
volatile u_int8 pins = 0; 

ISR(SIG_PIN_CHANGE0)
{
    previousPins = pins; // Save the previous state so you can tell what changed
    pins = (PINB & 0x03); // set pins to the value of PB0 and PB1
    ...
}

ดังนั้นถ้าpinsเป็น 0x01 คุณรู้ว่ามันเป็น PB0 ... และถ้าคุณต้องการที่จะรู้ว่าสิ่งที่เปลี่ยนแปลงที่คุณต้องการจะเปรียบเทียบกับpreviousPinsสวยมากว่าสิ่งที่คุณคิดว่า

เก็บไว้ในใจในบางกรณีpinsอาจไม่ถูกต้องถ้าขามีสถานะการเปลี่ยนแปลงตั้งแต่ขัดจังหวะ pins = (PINB & 0x03)แต่ก่อน

อีกทางเลือกหนึ่งคือการใช้เวกเตอร์ขัดจังหวะแยกจากกันด้วยหนึ่งพินจากแต่ละเวกเตอร์เพื่อให้คุณทราบว่ามีการเปลี่ยนแปลงใด อีกครั้งนี้นอกจากนี้ยังมีปัญหาบางอย่างเช่นการจัดลำดับความสำคัญการขัดจังหวะและเมื่อ CPU เข้าสู่ ISR ที่ทั่วโลกขัดจังหวะเปิดใช้งานบิตI-bitในSREGจะถูกล้างเพื่อให้การขัดจังหวะอื่น ๆ ทั้งหมดถูกปิดใช้งานแม้ว่าคุณสามารถตั้งค่าภายในขัดจังหวะถ้าคุณต้องการที่จะ ขัดจังหวะซ้อน

สำหรับข้อมูลเพิ่มเติมดูที่แอปของ Atmel โดยใช้ External Interrupts สำหรับ megaAVR Devices

ปรับปรุง

นี่เป็นตัวอย่างที่สมบูรณ์รหัสฉันเพิ่งพบที่นี่

#include <avr/io.h>
#include <stdint.h>            // has to be added to use uint8_t
#include <avr/interrupt.h>    // Needed to use interrupts
volatile uint8_t portbhistory = 0xFF;     // default is high because the pull-up

int main(void)
{
    DDRB &= ~((1 << DDB0) | (1 << DDB1) | (1 << DDB2)); // Clear the PB0, PB1, PB2 pin
    // PB0,PB1,PB2 (PCINT0, PCINT1, PCINT2 pin) are now inputs

    PORTB |= ((1 << PORTB0) | (1 << PORTB1) | (1 << PORTB2)); // turn On the Pull-up
    // PB0, PB1 and PB2 are now inputs with pull-up enabled

    PCICR |= (1 << PCIE0);     // set PCIE0 to enable PCMSK0 scan
    PCMSK0 |= (1 << PCINT0);   // set PCINT0 to trigger an interrupt on state change 

    sei();                     // turn on interrupts

    while(1)
    {
    /*main program loop here */
    }
}

ISR (PCINT0_vect)
{
    uint8_t changedbits;

    changedbits = PINB ^ portbhistory;
    portbhistory = PINB;

    if(changedbits & (1 << PB0))
    {
    /* PCINT0 changed */
    }

    if(changedbits & (1 << PB1))
    {
    /* PCINT1 changed */
    }

    if(changedbits & (1 << PB2))
    {
    /* PCINT2 changed */
    }
}

เมกะมีการเปลี่ยนแปลงการขัดจังหวะสามพินโดยมีเวกเตอร์ PCINT [0-2] แต่แต่ละอันจะถูกกระตุ้นด้วยชุดหมุด คำถามของฉันเกี่ยวกับวิธีแยกแยะว่าหมุดใดในชุดนั้นทำให้เกิดการขัดจังหวะ
Tom Davies

@ TomDavies คุณถูกต้องขอบคุณฉันเปลี่ยนคำตอบของฉัน แต่มันเป็นสิ่งที่คุณคิด และฉันอ่านแผ่นข้อมูลไม่มีการตั้งค่าสถานะเพื่อระบุว่ามีการเปลี่ยนแปลงพิน
Garrett Fogerlie

@ Garret: คุณรู้หรือไม่ว่าในตัวอย่างดั้งเดิมของคุณคุณสามารถระบุได้อย่างง่ายดายว่ามันเป็นขอบตกหรือขอบที่เพิ่มขึ้นซึ่งทำให้เกิดการขัดจังหวะหรือไม่? (ดียกเว้นว่าหมุดทั้งสองเปลี่ยนในเวลาเดียวกันแน่นอน ... แต่ในกรณีนี้มีเพียงเวทมนตร์สีดำช่วย) (previous_pins> หมุด): ขอบตก (หมุดก่อนหน้า <หมุด): ขอบเพิ่มขึ้นบางทีนี่อาจเป็นมูลค่าที่กล่าวถึงข้างต้น

@TomDavies PINB ครอบคลุม PCINT0-7, PINC ครอบคลุม PCINT8-15 ฯลฯ
EkriirkE

0

ในการINTFLAGSลงทะเบียนซีรีส์ ATTINY รุ่นใหม่จะบอกคุณว่าบิตพอร์ตใดทำให้เกิดการขัดจังหวะ

นี่คือข้อความที่ตัดตอนมาจากแผ่นข้อมูล:

บิต 7: 0 - INT [7: 0]: ธงปักหมุดขัดจังหวะธง INT ถูกตั้งค่าเมื่อการเปลี่ยนแปลง / สถานะของพินตรงกับการตั้งค่าการรับรู้ของหมุด การเขียน '1' ไปยังตำแหน่งบิตของแฟล็กจะล้างค่าสถานะ

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