Atmega128 тормозит? AVRStudio+Proteus
Добавлено: Сб фев 12, 2011 17:56:13
Ситуация следующая: пишу в аврстудии на си, эмулирую в протеусе, МК - Atmega128. Поставил ему частоту 8МГц, рассуждая, что при такой частоте каждый такт будет длится 1/8 микросекунды.
Захотел это проверить.
Предположил, что команды типа записи в регистр и побитной инверсии должны выполнятся за один такт. Предположил, что в эмуляции ножки у МК мгновенно состояние меняют.
В протеусе прицепил осцилограф к ноге МК и запустил вот такой код:
По осциллографу увидел, что состояние ноги меняется через целую (!) микросекунду (я надеялся увидеть ту самую 1/8).
Далее, включил таймер-счетчик с частотой МК (без предделения), в режиме СТС и сбросом через 1 такт (OCR = 1 то есть).
И проверил два кусочка кода (вроде бы совершенно аналогичных).
Первый кусочек, через прерывание:
Второй кусочек, через флаг:
И опять осциллографом на ногу смотрел.
Увиденное меня просто поразило - при использовании флага состояние ноги менялось через каждые ~5 мкс, а при использовании прерывания - через ~10 мкс. Почему так долго?!
Вопрос такой: это я дурак и что-то неправильно делаю (или непонимаю), протеус глючит или все нормально и быстрее таймер тикать и не может?
Захотел это проверить.
Предположил, что команды типа записи в регистр и побитной инверсии должны выполнятся за один такт. Предположил, что в эмуляции ножки у МК мгновенно состояние меняют.
В протеусе прицепил осцилограф к ноге МК и запустил вот такой код:
Код: Выделить всё
PORTF = ~PORTF;
PORTF = ~PORTF;
PORTF = ~PORTF;
PORTF = ~PORTF;
PORTF = ~PORTF;
PORTF = ~PORTF;
По осциллографу увидел, что состояние ноги меняется через целую (!) микросекунду (я надеялся увидеть ту самую 1/8).
Далее, включил таймер-счетчик с частотой МК (без предделения), в режиме СТС и сбросом через 1 такт (OCR = 1 то есть).
И проверил два кусочка кода (вроде бы совершенно аналогичных).
Первый кусочек, через прерывание:
Код: Выделить всё
ISR(TIMER1_COMPA_vect)
{
PORTF=~PORTF;
}
Второй кусочек, через флаг:
Код: Выделить всё
while(1)
{
if(TIFR & (1 << OCF1A)); // CTC Flag
{
TIFR |= 1 << OCF1A; // drop flag
TCCR1B = 0; // stop timer
TCNT1 = 0;
PORTF=~PORTF;
TCCR1B = (1 << WGM12) | (1 << CS10); //resume timer
}
И опять осциллографом на ногу смотрел.
Увиденное меня просто поразило - при использовании флага состояние ноги менялось через каждые ~5 мкс, а при использовании прерывания - через ~10 мкс. Почему так долго?!
Вопрос такой: это я дурак и что-то неправильно делаю (или непонимаю), протеус глючит или все нормально и быстрее таймер тикать и не может?
