USART Atmega328p как отключить прием данных в нужный момент

Обсуждаем контроллеры компании Atmel.
Ответить
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

USART Atmega328p как отключить прием данных в нужный момент

Сообщение a_b_r_a »

Всем привет. Делаю простенький бортовой комп, который берет данные из ECU по к-line. Для приема данных создал кольцевой буфер. Данные в него кладу во время прерывания по Rx. Когда я начинаю передавать данные, то ECU кидает мне эхо. Мне это эхо мешает обрабатывать принятые данные. Я пытался отключать прерывания по приему данных во время передачи своих данных. Пытался отключать бит RXCIE0 во время передачи данных. Все равно это от ECU оказывается в кольцевом приемном буфере. Подскажите, где я туплю?

Код: Выделить всё

ISR(USART_RX_vect)
{
	
	//asm("nop");
	Put_Byte(UDR0);
}




void USART_Transmit(uint8_t data)
{   UCSR0B &= ~(1<<RXCIE0);  // отключаю прерывание по приему
	UCSR0B &= ~(1<<RXEN0); // Отключаю прием данных для избавления от эха
	/* Ожидание опустошения буфера передачи данных */
	while (!(UCSR0A & (1<<UDRE0)));
	/* Если буфер пустой, толкаем данные */
	UDR0 = data;
	UCSR0B |= (1<<RXEN0);
	UCSR0B|=(1<<RXCIE0);
}

uint8_t USART_Receive(void)
{
	/* Wait for data to be received */
	while (!(UCSR0A & (1<<RXC0)));
	
	/* Get and return received data from buffer */
	return UDR0;
}

//"очищает" приемный буфер
 void USART_Flus_cycleBuf(void)
{
	
	tail = 0;
	head = 0;
	rxcount = 0;
	
}
//возвращает колличество байт находящихся в приемном буфере
uint8_t USART_GetRxCount(void)
{
	return rxcount;
}

// Положить байт в буфер
void Put_Byte(uint8_t dt)
{
	if (rxcount < SIZE_BUF)  //если в буфере еще есть место
	{   
		cycleBuf[tail] = dt;    //помещаем в него байт
		rxcount++;           //инкрементируем счетчик байтов
		tail++;                //и индекс хвоста буфера
		if (tail == SIZE_BUF) tail = 0;
	}
}

//взять байт из буфера
uint8_t Get_Byte(void)
{
	uint8_t dt = 0;
	if (rxcount > 0)                  //если буфер не пустой
	{                           
		dt = cycleBuf[head];              //считываем байт из буфера
		rxcount--;                                   //уменьшаем счетчик байтов
		head++;                                  //инкрементируем индекс головы буфера
		if (head == SIZE_BUF) head = 0;
		return dt;
	}
	return 0;
}

void KWPconnect(void)
{
	blockCounter = 0;
	currAddr = 0;
	// answer: 0x55, 0x01, 0x8A
	uint8_t i=0;
	uint8_t s[3];
	
		if (connect_ok==0 && connect_ini==1) // Выполняется однократно
		{
			while(USART_GetRxCount()>0) // Пока в буфере есть непрочитанные байты
			{
				s[i]=Get_Byte(); // Читаем в массив
				i++;
			}
		}
			if ( (s[0]==0x55) && (s[1]==0x01) && (s[2]==0x8A) ) // Если ECU ответил корректно
			{
				blockCounter++;
				currAddr = 1;
				uint8_t a=s[2];
				a=a^0xFF;
				USART_Transmit(a); // Отсылаем ECU подтверждение корректности принятых данных
				connect_ok=1;
				
			}		
}

while
{
KWPconnect();
}

В итоге в cycleBuf попадает ответ от ECU, который я пытаюсь игнорить

Добавлено after 5 hours 50 minutes 46 seconds:
Решено. K-line устроен таким образом, что при отправки данных по пину TX на пине RX всегда такие же данные. Поэтому эти данные всегда будут присутствовать в приемном регистре UDR0. Проблему решил так:

Код: Выделить всё

void USART_Transmit(uint8_t data)
{  
	UCSR0B &=~(1<<RXCIE0);
	/* Ожидание опустошения буфера передачи данных */
	while (!(UCSR0A & (1<<UDRE0)));
	/* Если буфер пустой, толкаем данные */
	UDR0 = data;
    data=USART_Receive();// Прежде чем разрешить прерывание, нужно сбросить бит RXC0 чтением приемного регистра
	UCSR0B |=(1<<RXCIE0);
	
}
Реклама
technik-1017
Открыл глаза
Сообщения: 42
Зарегистрирован: Вс сен 03, 2017 19:43:57
Контактная информация:

Re: USART Atmega328p как отключить прием данных в нужный мом

Сообщение technik-1017 »

Оставьте, пусть принимает, дополнительная проверка. Если переданные данные соответствуют принятым, значит линия целая.
Реклама
a_b_r_a
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 27, 2010 21:53:52

Re: USART Atmega328p как отключить прием данных в нужный мом

Сообщение a_b_r_a »

А смысл? Это всегда будут те же данные, которые я посылаю. А вот счетчик кольцевого буфера (приемного) будет инкрементироваться по эху. И потом разобрать всю эту кашу будет очень сложно.
Ответить

Вернуться в «AVR»