Код: Выделить всё
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();
}
Добавлено 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);
}
