Перенастроить таймер во время прерывания таймера прерывания 8051

Я использую компилятор SDCC.

Я пытаюсь перенастроить Timer0 в режиме автоматической перезагрузки 2 во время его собственного обработчика прерываний. Вот код C:

void reconf(void)  __interrupt(1){
    TR0=0;
    TH0=0xC0;
    TL0=0xC0;
    TR0=1;
}

Вот вопросы:

  1. Можно ли перенастроить TL0 и TH0 для Timer0 в режиме автоматической перезагрузки режима 2 во время выполнения собственного обработчика прерываний?

  2. Нужно ли останавливать Timer0 во время реконфигурации или нет, потому что он не работает во время прерывания?

  3. ЗАПИСЫВАЮТСЯ ли значения TH0 и TL0 в стек перед запуском процедуры обработки прерывания? Если эти значения помещаются в стек, а затем во время выполнения обработчика подпрограммы я перенастраиваю эти значения, будут ли эти значения отменены значениями POPed из стека при выходе из прерывания?


person distortedbsd    schedule 24.09.2013    source источник
comment
Я просмотрел файл HEX, который создается sdcc после компиляции кода C, и кажется, что TH0 и TL0 не помещаются в стек перед выполнением каких-либо процедур прерывания.   -  person distortedbsd    schedule 25.09.2013
comment
Кроме того, я попытался перенастроить timer0 с помощью процедуры прерывания, и он работает.   -  person distortedbsd    schedule 25.09.2013


Ответы (1)


Прежде чем ответить на ваши вопросы, я думаю, стоит указать, что такое TR0, TH0 и TL0. Это не переменные, локальные для функции или сидящие в стеке (при условии, что у вас есть стек вызовов, которого нет в большинстве приложений 8051 - ищите оверлеи памяти). Это регистры специальных функций, обычно сокращенно SFR. Вы можете узнать больше о SFR, но для целей вашего вопроса вы можете рассматривать их как глобальные переменные с точки зрения области видимости.

  1. Вы можете изменить регистры TL0 и TH0 в любое время, в том числе в обработчике прерывания периферийного устройства Таймера 0.

  2. Необязательно останавливать таймер, чтобы изменить его значение, но имейте в виду, что он будет продолжать отсчет, пока вы это делаете. Это может быть проблемой, если вы пишете так же, как младший байт перекатывается, и вы можете получить значение таймера, отличное от того, что вы планировали.

    <previous code>  // Timer increments to 0x12fe
    TH0 = 0xff;      // Timer is now 0xffff
                     // Timer increments to 0x0000
    TL0 = 0x52;      // Timer is now 0x0052
                     // Timer increments to 0x0053
    

    Вы пытались установить таймер на 0xff52, но в итоге получили 0x0052. Это крайний пример, но есть риск. Вы можете быть менее рискованными, написав сначала TL0, а затем TH0, но выключение таймера - самое простое решение.

  3. Поскольку теперь вы знаете, что TL0 и TH0 являются SFR с глобальной областью видимости, вам не нужно беспокоиться о том, что стек или какой-либо другой механизм передачи аргументов функции мешает им.

person Phil Wetzel    schedule 25.09.2013