Например TDA7294

Форум РадиоКот • Просмотр темы - USART Atmega328p как отключить прием данных в нужный момент
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Ср авг 13, 2025 20:36:15

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: USART Atmega328p как отключить прием данных в нужный момент
СообщениеДобавлено: Сб май 06, 2023 19:49:58 
Открыл глаза

Карма: -3
Рейтинг сообщений: 0
Зарегистрирован: Ср янв 27, 2010 21:53:52
Сообщений: 57
Рейтинг сообщения: 0
Всем привет. Делаю простенький бортовой комп, который берет данные из 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);
   
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: USART Atmega328p как отключить прием данных в нужный мом
СообщениеДобавлено: Сб май 06, 2023 19:58:50 
Открыл глаза

Карма: 1
Рейтинг сообщений: 19
Зарегистрирован: Вс сен 03, 2017 19:43:57
Сообщений: 42
Рейтинг сообщения: 0
Оставьте, пусть принимает, дополнительная проверка. Если переданные данные соответствуют принятым, значит линия целая.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: USART Atmega328p как отключить прием данных в нужный мом
СообщениеДобавлено: Сб май 06, 2023 21:04:25 
Открыл глаза

Карма: -3
Рейтинг сообщений: 0
Зарегистрирован: Ср янв 27, 2010 21:53:52
Сообщений: 57
Рейтинг сообщения: 0
А смысл? Это всегда будут те же данные, которые я посылаю. А вот счетчик кольцевого буфера (приемного) будет инкрементироваться по эху. И потом разобрать всю эту кашу будет очень сложно.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 3 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 384


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y