มีวิธีที่ไม่ต้องสำรวจ UART ของ AVR หรือไม่?


10

ฉันกำลังรับข้อมูลผ่าน UART จาก AVR ตัวอื่น อย่างไรก็ตามฉันกำลังทำสิ่งอื่น ๆ ดังนั้นไม่ต้องการให้มีการสำรวจ UART อย่างต่อเนื่อง ฉันรู้ว่ามีการขัดจังหวะ แต่ฉันเห็นได้เพียงครั้งเดียวว่าจะได้รับสมบูรณ์ซึ่งฉันคิดว่ายังคงต้องการให้ฉันสำรวจเพื่อให้การถ่ายโอนเสร็จสมบูรณ์


1
ทำไมคุณต้องสำรวจความคิดเห็นเพื่อเริ่มต้นการโอนเงิน อย่างไรก็ตามมีการขัดจังหวะการส่งสัญญาณให้เสร็จสมบูรณ์เช่นกัน ฉันไม่ค่อยเข้าสู่ AVR มากนัก แต่สิ่งเหล่านี้สามารถเรียกว่า "TX empty" หรือ "FIFO empty" หรือ FIFO threshold "หรือคล้ายกัน
Eugene Sh.

คำตอบ:


20

มีเวกเตอร์ขัดจังหวะสำหรับทั้ง RXC และ TXC (RX และ TX เสร็จสมบูรณ์) ใน AVRs คุณไม่ควรทำแบบสำรวจความคิดเห็นเหล่านี้จนกว่าคุณจะต้องการ

AVRFreaks มีโพสต์ที่ดีเกี่ยวกับเรื่องนี้และผู้ผลิตก็เช่นกัน


3
ฉันจะเป็นทั้งหมด "ทำไมลิงค์ AppNote ถึงชี้ไปที่ Microchip เป็นผลิตภัณฑ์ของ Atmel!" ฉันไม่อยากจะเชื่อเลยว่าฉันไม่เคยได้ยินว่า Microchip ซื้อ Atmel คุณก้าวออกจากไมโครคอนโทรลเลอร์เป็นเวลา 5 ปี ...
Zac Faragher

2
@ZacFaragher NXP + Freescale + Qualcomm อะนาล็อก + LT ON + แฟร์ไชลด์ Infineon + IR ทั้งหมดนี้ใน 1-2 ปีที่ผ่านมา ค้นหาคู่แข่งที่เลวร้ายที่สุด / คนเดียวของคุณ
Lundin

1
@Lundin Qualcomm NXP ไม่ได้เกิดขึ้นและไม่ปรากฏว่าอยู่ในการพิจารณาของสาธารณชนอีกต่อไป มันอาจจะยังคงอยู่หรืออย่างอื่นก็ทำได้ - มันมีอยู่ตลอดเวลาที่เป็น Dialog ที่กำลังจะซื้อ Atmel
Chris Stratton

2

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

มันจะไม่รวบรวม แต่นี่แสดงให้เห็นถึงวิธีการ

char circ_buf[BUFFER_SIZE];
int get_index, put_index;

void initialize(void) {
    get_index = 0;
    put_index = 0;
}

isr serial_port_interrupt(void) {                       // interrupt
    circ_buf[put_index++] = SERIAL_PORT_REGISTER;
    if(put_index==get_index) error("buffer overflow");  // oops
    if(put_index==BUFFER_SIZE) put_index = 0;           // circular buffer
}

void background routine(void) {
    while(put_index!=get_index) {                       // or if()
        ch = circ_buf[get_index++];
        // do something with ch
        if(get_index==BUFFER_SIZE) get_index = 0;
        }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.