Интервальный таймер 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

msp430