Интервальный таймер MSP430

Продолжаю изучение микроконтроллера MSP430. На сей раз решил сделать мигание светодиодов по таймеру, ох и не тривиальная эта задача для меня оказалась. Всю документацию пришлось перелопатить, примеры на си пересмотреть, в итоге последним штрихом стало то, что я не проинициализировал стековый регистр SP, который нужен для работы возврата из прерывания.

Итак, чтобы обработать прерывания по интервальному таймеру, необходимо:

  1. Установить адрес нашего обработчика по адресу 0xFFF4.
  2. Для нормальной работы возврата из прерывания нужно проинициализировать стек - mov #0x280, SP.
  3. Установить нужный режим сторожевого таймера WDTCTL (0x0120).
  4. Установить бит разрешения прерываний в регистре разрешения прерываний - bis.b #WDTIE, &IE1.
  5. Разрешить прерывания - eint (bis.b #8, SR).

Теперь частота мигания светодиодов не зависит от обычного цикла задержки, при этом можно заниматься любыми другими делами (там где пустой цикл while_1).

.include "msp430x2xx.inc"   ; Подключение файла /usr/local/share/naken430asm/include/msp430x2xx.inc

#define LED1    0x01    ; Код светодиода 1
#define LED2    0x40    ; Код светодиода 2

    org     0xFC00  ; Адрес размещения нашей программы (1кб - 0xFC00, 2кб - 0xF800, 4кб - 0xF000, 8кб - 0xE000)
init:
    mov     #0x0280, SP ; инициализируем указатель стека

    mov.b   #LED1+LED2, &P1DIR  ; Включить порт
    bis.b   #LED1, &P1OUT   ; Включить 1 светодиод
    bic.b   #LED2, &P1OUT   ; Выключить 2 светодиод
    clr     R15             ; Очистить счетчик замедления таймера

    mov     #WDTPW+WDTCNTCL+WDTTMSEL+WDTIS0, &WDTCTL    ; включить сторожевой таймер в режиме интервального таймера с частотой тактирования / 32768
    bis.b   #WDTIE, &IE1    ; SFR interrupt enable 1
    eint    ; разрешить прерывания

while_1:
    jmp     while_1 ; бесконечный цикл

timer:  ; обработчик прерывания таймера
    inc     R15         ; увеличить на 1
    cmp     #10, R15    ; сравнить с 10
    jl      treti       ; выйти, если меньше 10
    clr     R15         ; сбросить счетчик замедления
    xor.b   #LED1+LED2, &P1OUT  ; поменять светимость светодиодов
treti:
    reti    ; выйти из прерывания

    org     0xFFF4  ; WDTIFG
    dw      timer

    org     0xFFFE  ; Reset
    dw      init
02 января 2012