vesago 0 2 сентября, 2008 Опубликовано 2 сентября, 2008 · Жалоба К LPC2214 подключена ADM485 у которой приемник постоянно включен. Т.е. при передаче я отключаю прерывание приемника, включаю разрешение пердачи ADM485 и передаю данные. Далее контролирую опустошение передатчика UART и сдвигового регистра и при фиксации сего, чищу фифо и активирую прерывание приемника. Проблема в том, что сразу после передчи и разрешения прерывания приемника, происходит прерывание и принимается переданный байт, не смотря на то, что я почистил фифо. Получается, фифо не всегда чистится или при каких-то условиях прерывание остается взведенным. Если под отладкой выполнять по шагам, такого не происходит. Помогите разобраться с данной ситуацией. Параметры уарта - скорость 38400, глубина фифо - 1 байт, остальное стандартно. Вот такой у меня иср уарта: //******************************************************************************** ********** //Обработчик прерывания UART0 //******************************************************************** ********************** void UART0_Handler(void) __irq { u8_t data; u8_t tmphead; u8_t tmptail; switch((data = U0IIR) & INTERRUPT_SOURCE_MASK) { //Прием case SOURCE_RX: data = U0RBR; if((uart0.flags & (1<<UART0_FLAG_TX_IN_PROGRESS)) == 0) { tmphead = (uart0.rx_head + 1) & UART0_RX_BUFFER_MASK; uart0.rx_head = tmphead; if(tmphead == uart0.rx_tail) { //ERROR! Receive buffer overflow uart0.flags |= (1<<UART0_FLAG_ERR); } uart0.rx_buf[tmphead] = data; } if(((data == 0x03) || (data == 0x06) || (data == 0x15)) && (avr.counter == 0)) { data = 0x03;//Это для отлавливания ошибочной ситуации } break; //Прередача case SOURCE_THRE: tmptail = uart0.tx_tail; if(uart0.tx_head != tmptail) { tmptail = (uart0.tx_tail + 1) & UART0_TX_BUFFER_MASK; uart0.tx_tail = tmptail; U0THR = uart0.tx_buf[tmptail]; } else { uart0.flags &= ~(1<<UART0_FLAG_TX_IN_PROGRESS); uart0.flags |= (1<<UART0_FLAG_TX_COMPLETE); } break; //Таймаут приема case SOURCE_RX_TIMEOUT: data = U0LSR; data = U0RBR; break; //Ошибка case SOURCE_ERROR: data = U0LSR; data = U0RBR; break; //Хрень какая-то default: data = U0LSR; data = U0RBR; } VICVectAddr = 0; } Функции разрешения/запрещения передачи: //:::::::::::::::::::::::::::::::::::::::::::::::::::::: // Запрет приема //:::::::::::::::::::::::::::::::::::::::::::::::::::::: void UART0_DisableReciveIRQ(void) { U0IER &= ~(1<<U0IER_RBR_Interrupt_Enable_BIT); } //:::::::::::::::::::::::::::::::::::::::::::::::::::::: // Разрешение приема //:::::::::::::::::::::::::::::::::::::::::::::::::::::: void UART0_EnableReciveIRQ(void) { u8_t temp; temp = U0LSR; U0FCR = (1<<U0FCR_FIFO_Enable_BIT) | (1<<U0FCR_Tx_FIFO_Reset_BIT) | (1<<U0FCR_Rx_FIFO_Reset_BIT); U0IER |= (1<<U0IER_RBR_Interrupt_Enable_BIT); } //:::::::::::::::::::::::::::::::::::::::::::::::::::::: // Старт передачи //:::::::::::::::::::::::::::::::::::::::::::::::::::::: void UART0_Transmit_On(void) { UART0_DisableReciveIRQ(); IO0SET |= (1<<GL_BUS_DIR); //Включим передатчик RS485 } //:::::::::::::::::::::::::::::::::::::::::::::::::::::: // Стоп передачи //:::::::::::::::::::::::::::::::::::::::::::::::::::::: void UART0_Transmit_Off(void) { IO0CLR |= (1<<GL_BUS_DIR); //Отключим передатчик RS485 UART0_EnableReciveIRQ(); //Разрешим прием } Проверка опустошения сдвигового регистра: u8_t UART0_Check_Shift_Reg_Emty(void) { if((uart0.flags & (1<<UART0_FLAG_TX_COMPLETE)) != 0) { if((U0LSR & (1<<U0LSR_TEMT_BIT) != 0) && (U0LSR & (1<<U0LSR_THRE_BIT) != 0)) { uart0.flags &= ~(1<<UART0_FLAG_TX_COMPLETE); return 1; } } return 0; } Применеие в майне: system.state = SYSTEM_STATE_SCPU_BOOT; while(1) { UART0_Transmit_On(); UART0_Transmit(0x15); system.start_timer = TIME; do { if(UART0_Check_Shift_Reg_Emty() != 0) { UART0_Buf_Clr(); UART0_Transmit_Off(); } }while(system.start_timer != 0); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 2 сентября, 2008 Опубликовано 2 сентября, 2008 · Жалоба Т.е. при передаче я отключаю прерывание приемника, включаю разрешение пердачи ADM485 и передаю данные. Далее контролирую опустошение передатчика UART и сдвигового регистра и при фиксации сего, чищу фифо и активирую прерывание приемника. Читать все написанное не стал, ибо зачем такие дивные навороты, если можно просто принимать свое эхо и выкидывать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vesago 0 2 сентября, 2008 Опубликовано 2 сентября, 2008 · Жалоба Спасибо, как-то я не подумал про такое. Еще увидел интересное решение - пинсел переключается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться