Вобщем понадобилось мне организовать программный уарт на 13 тиньке, из всего уарта мне требуется всего лишь приёмная часть. Но какие то проблемы, связанные толи с таймером толи с кодом.
расчётное время выходит больше чем длится посылка в протеусе.
Раздел: AVR
#define TIME_BIT (0xff - (F_CPU/(4800*3*8)))
struct _flags
{
uint8_t start_bit:4;
uint8_t next_bit:4;
};
static volatile struct _flags flags = {0,0};
ISR(INT0_vect)
{
flags.start_bit = 1;
}
ISR(TIM0_COMPA_vect)
{
flags.next_bit = 1;
}
void inline clock_next_bit()
{
while(!flags.next_bit);
flags.next_bit = 0;
}
void inline wait_start_receive()
{
while(!flags.start_bit);
flags.start_bit = 0;
}
uint8_t uart_receive()
{
sbi(MCUCR,ISC01); //прерывание по спадающему фронту
sbi(GIMSK,INT0); // разрешение прерывания по событию на пине
wait_start_receive();
cbi(GIMSK,INT0); // вырубаем ненужное прерывание
TCCR0A |= (1 << WGM01); //сброс счётчика по совпадению
TCCR0B |= (1 << CS01); //предделитель счётчика 8
TIMSK0 |= (1 << OCIE0A); //прерывания по сравнению
OCR0A = TIME_BIT;
clock_next_bit(); //даём смещение в пол такта
uint8_t data = 0;
PORTB ^= (1 << PB2); //начало приёма
for (uint8_t i = 0;i < 8; ++i)
{
clock_next_bit();
if (bit_is_set(PINB,PB1))
{
data |= 1 << i;
}
}
TCNT0 = 0;
TCCR0B = 0x00;
PORTB ^= (1 << PB2); // конец приёма
return data;
}
расчётное время выходит больше чем длится посылка в протеусе.
Раздел: AVR