Обсуждаем контроллеры компании Atmel.
Ответить

Зацикливается прерывание USART_RXC_vect

Пн мар 29, 2021 18:49:38

Подскажите по какой причине, при отправке одного байта в контроллер, в ответ начинают приходить бесконечное кол-во данных? Вроде как функцтя прерывантя дожна сработать один раз. Отправляю одно двоеточие(:) в аски.

Код:

#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL

#define REDE_PORT PORTD
#define REDE_PIN PD2
#define TRANSMIT    REDE_PORT|=1<<REDE_PIN;
#define RECIEVE    REDE_PORT&=~(1<<REDE_PIN);

void USART_Init( unsigned int ubrr)//Инициализация модуля USART
{
   /* Задаем скорость работы USART */
   UBRRH = (unsigned char)(ubrr>>8);
   UBRRL = (unsigned char)ubrr;
   /* Разрешаем прием и передачу по USART */
   UCSRB=(1<<RXEN)|( 1<<TXEN);
   UCSRB |= (1<<RXCIE);
   UCSRC |= (1 << URSEL)|
   (1 << UCSZ1)|(1 << UCSZ0);
}

void USARTTransmitChar(char c) {
  while(!( UCSRA & (1<<UDRE)));
  UDR = c;
}

ISR(USART_RXC_vect )
{
   TRANSMIT
   USARTTransmitChar('H');
   RECIEVE
   _delay_ms(100);
}

int main(void)
{
   sei();
   USART_Init(51);
   while (1){}
}




На картинке пришедшие данные
Вложения
Screenshot_2021-03-29_21-52-12.png
(82.67 KiB) Скачиваний: 85

Re: Зацикливается прерывание USART_RXC_vect

Пн мар 29, 2021 19:20:17

Попробуйте отключить прерывание при вхождении в USART_RXC_vect. Потом снова включить перед выходом из обработки прерывания.

Добавлено after 4 minutes 49 seconds:
В USARTTransmitChar сделайте ожидание окончании передачи перед выходом из функции.

Re: Зацикливается прерывание USART_RXC_vect

Вт мар 30, 2021 11:59:02

Не увидел в вашем прерывании чтения UDR, по которому контроллер понимает что байт прочитан и снимает флаг прерывания. Ну или можете попытаться сами снять флаг, но это сложнее.
Попробуйте отключить прерывание при вхождении в USART_RXC_vect. Потом снова включить перед выходом из обработки прерывания.
Без крайней нужды так делать не стоит. При входе в прерывание глобальные прерывания автоматически запрещаются, потом перед самым выходом вы их вручную разрешаете, но остается небольшой зазор, когда прерывание уже разрешено, но еще не завершилось, то есть не освободило стек. И если в этот момент возникнет еще одно, а потом еще... В общем, срыв стека так и выглядит.

Re: Зацикливается прерывание USART_RXC_vect

Вт мар 30, 2021 13:07:11

Не увидел в вашем прерывании чтения UDR, по которому контроллер понимает что байт прочитан и снимает флаг прерывания.

Огромное спасибо. Добавил чтение UDR. Все заработало. Бессонная ночь подошла к концу.
Ответить