Понимание таймера и периода прерываний - PullRequest
0 голосов
/ 10 августа 2011

Мне трудно понять какой-то код, который я нашел для использования таймера и прерываний на имеющейся у меня плате ARM.Таймер в основном включает и выключает светодиод при каждом прерывании, чтобы он мигал.

void main(void) {

    /* Pin direction */
    led_init();

    /* timer setup */
    /* CTRL */

    #define COUNT_MODE 1      /* Use rising edge of primary source */
    #define PRIME_SRC  0xf    /* Peripheral clock with 128 prescale (for 24 MHz = 187500 Hz)*/
    #define SEC_SRC    0      /* Don't need this */
    #define ONCE       0      /* Keep counting */
    #define LEN        1      /* Count until compare then reload with value in LOAD */
    #define DIR        0      /* Count up */
    #define CO_INIT    0      /* Other counters cannot force a re-initialization of this counter */
    #define OUT_MODE   0      /* OFLAG is asserted while counter is active */

    *TMR_ENBL     = 0;                    /* TMRS reset to enabled */
    *TMR0_SCTRL   = 0;
    *TMR0_CSCTRL  = 0x0040;
    *TMR0_LOAD    = 0;                    /* Reload to zero */
    *TMR0_COMP_UP = 18750;                /* Trigger a reload at the end */
    *TMR0_CMPLD1  = 18750;                /* Compare one triggered reload level, 10 Hz maybe? */
    *TMR0_CNTR    = 0;                    /* Reset count register */
    *TMR0_CTRL    = (COUNT_MODE<<13) | 
                    (PRIME_SRC<<9)   | 
                    (SEC_SRC<<7)     | 
                    (ONCE<<6)        | 
                    (LEN<<5)         | 
                    (DIR<<4)         | 
                    (CO_INIT<<3)     |
                    (OUT_MODE);
    *TMR_ENBL     = 0xf;                  /* Enable all the timers --- why not? */

    led_on();

    enable_irq(TMR);

    while(1) {
        /* Sit here and let the interrupts do the work */
        continue;
    };
}

В данный момент светодиод мигает со скоростью, которую я не могу определить в секунду.Я бы хотел, чтобы он мигал один раз в секунду.Однако я не понимаю всего сравнения и перезагрузки.

Может кто-нибудь лучше объяснить этот код?

Ответы [ 2 ]

1 голос
/ 12 сентября 2017

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

Как периферийный блок таймераработает? Это аппаратный модуль, который встроен в микроконтроллер вместе с процессором и другими периферийными устройствами.Все периферийные модули внутри микроконтроллера синхронизированы с общим источником синхронизации.Что касается кода, то частота таймера для таймера составляет 24 МГц, который затем предварительно масштабируется до 128, что означает, что он будет работать на частоте 187500 Гц.Теперь эта частота будет зависеть от конфигурации часов и генератора.

Теперь модуль таймера имеет регистр счетчика, который может считать до своего размера в битах, который может быть 8,16 или 32 в целом.Как только вы включите счет, этот счетчик начнет увеличивать или уменьшать счет нарастания или спада или на обоих краях.Теперь у вас есть выбор: хотите ли вы увеличить счет (от 0 до 255 для 8-битного) или уменьшить счет (от 255 до 0), и вы хотите рассчитывать, на каком фронте тактовой частоты.

Теперь, на187500 Гц, 1 цикл = 5,333333 сша, если вы рассчитываете один раз в 1 цикле либо при нарастающем, либо при спадающем фронте и, например, если значение счетчика = 100 (счет с повышением), общее прошедшее время составляет 5,33333 * 100 = 533us.Теперь вам нужно установить значение сравнения для счетчика, чтобы установить этот период, который будет зависеть от вашей скорости вспышки.Это значение сравнения будет сравниваться со значением вашего счетчика в компараторе Timer, и как только оно совпадет, оно отправит сигнал прерывания, если вы включили генерацию прерываний при сравнении сравнения, где вы можете переключить свой светодиод.

Я надеюсь,Вы поняли, как работает таймер.В вашем примере кода Timer настроен на получение события сравнения сравнения с частотой 10 Гц.так что сравнивайте значение 187500/10 = 18750., в течение 1 секунды вы можете оставить его 187500/1.у вас есть регистр управления таймером TMR0_CTRL, где вы можете настроить, хотите ли вы считать вверх или вниз, рассчитывать на падение / повышение / оба фронта, считать только один раз / непрерывно, считать до сравниваемого значения и затем сбрасывать или продолжать считать до его предела.Обратитесь к руководству по микроконтроллеру для получения подробной информации о каждом битовом поле.

1 голос
/ 10 августа 2011

Поскольку таймеры являются специфической функцией поставщика и части (не является частью архитектуры ARM), я могу дать только общее руководство, если вы не упомянете, с каким ЦП или микроконтроллером вы имеете дело.

Таймеры имеютнесколько функций:

  1. Размер, например 16 битов, что означает, что они могут считать вверх или вниз до / от 65535.
  2. Вход тактовой частоты, заданный как тактовая частота (возможно,от тактовой частоты процессора или внешнего кристалла), а также прескалер, который делит эту тактовую частоту на другое значение (или делит на 1).
  3. Прерывание при переполнении - когда таймер возвращается к 0, обычноопция для запуска прерывания.
  4. Сравнение прерываний - когда таймер встречает установленное значение, он выдаст прерывание.

В вашем случае я вижу, что вы используетефункция сравнения вашего таймера.Определив вход таймера и рассчитав новые значения для прескалера и регистра сравнения, вы сможете достичь частоты 1 Гц.

...