AVR의 UART를 폴링 할 필요가없는 방법이 있습니까?


10

다른 AVR에서 UART를 통해 데이터를 수신하고 있습니다. 그러나 나는 다른 일을하고 있으므로 끊임없이 UART를 계속 폴링하고 싶지 않습니다. 인터럽트가 있다는 것을 알고 있지만 수신 완료에 대한 인터럽트 만 볼 수 있습니다. 전송을 완료하려면 여전히 폴링이 필요하다고 가정합니다.


1
전송을 시작하기 위해 폴링해야하는 이유는 무엇입니까? 어쨌든 전송 완료를위한 인터럽트도 있습니다. 저는 AVR에 익숙하지 않지만 "TX 비어 있음"또는 "FIFO 비어 있음"또는 FIFO 임계 값 "또는 이와 유사 할 수 있습니다.
Eugene Sh.

답변:


20

AVR에는 RXC 및 TXC (RX 및 TX 완료)에 대한 인터럽트 벡터가 있습니다. 원치 않는 한 이들을 위해 설문 조사를 할 필요가 없습니다.

AVRFreaks는 이것에 대한 좋은 게시물 을 가지고 있으며 제조업체도 마찬가지 입니다.


3
"모든 AppNote 링크가 Microchip을 가리키는 이유는 Atmel 제품입니다!" 나는 마이크로 칩은 아트멜, 당신은 ... 5 년간 마이크로 컨트롤러에서 물러 구입 한 것을 들어 본 적이없는 믿을 수 없어
자크 Faragher

2
@ZacFaragher NXP + Freescale + Qualcomm. 아날로그 + LT. ON + 페어차일드. 인피니언 + IR. 지난 1-2 년 동안이 모든 것. 최악의 유일한 경쟁자를 찾아서 합병하십시오.
Lundin

1
@Lundin Qualcomm NXP는 발생하지 않았으며 더 이상 공개적으로 고려 되지 않는 것으로 보입니다 . 그것은 여전히 ​​또는 다른 무엇이든 할 수 있습니다-Atmel을 살려고했던 Dialog가 항상있었습니다.
Chris Stratton

2

인터럽트 루틴은 데이터를 버퍼에 저장합니다 (put 및 get 포인터가있는 원형 버퍼). 메인 루프는 버퍼에 데이터가 있는지 확인하고 데이터가 있으면 꺼내줍니다. 메인 루프는 다른 작업을 수행 할 수 있지만 인터럽트 버퍼가 오버플로되기 전에 (퍼팅이 get과 만날 때) 데이터를 확인하고 제거해야합니다.

컴파일되지는 않지만 메소드를 보여줍니다.

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.