Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывание в Tiny по WDT
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Neutron
Помогите пожалуйста!
Никак не могу запустить прерывание по watchdog на Tiny2313. Сбросы работают а прерывания ни в какую. help.gif Мне нужно чтобы при малом потреблении во время спячки прерывания происходили с частотой ~20 Гц.
Палыч
Цитата(Neutron @ Jun 24 2008, 10:17) *
Никак не могу запустить прерывание по watchdog на Tiny2313. Сбросы работают а прерывания ни в какую.
Может быть, в спячке запрещены прерывания (бит I=0 в регистре состояния)?
Neutron
Цитата(Палыч @ Jun 24 2008, 12:16) *
Может быть, в спячке запрещены прерывания (бит I=0 в регистре состояния)?

Перед SLEEP давал SEI не помогло. Даже без спячки в прерывание не уходит. Если ставлю фуз WTDON, то сбрасывается, а не ставлю, то ни на прерывание ни на сброс не уходит, хотя как в pdf устанавливаю WDE или WDIE.
У кого нибудь реально работал watchdog как источник прерываний?
Палыч
Цитата(Neutron @ Jun 24 2008, 12:01) *
хотя как в pdf устанавливаю WDE или WDIE.
Код приведите... Видно что-то не по DS...
Neutron
Цитата(Палыч @ Jun 24 2008, 14:13) *
Код приведите... Видно что-то не по DS...

Код
        cli
        wdr  ; Reset Watchdog Timer
        in      r16, WDTCR    ; Start timed sequence
        ori     r16, (1 << WDCE) | (1<<WDE)
        out     WDTCR, r16
        ldi     r16, (0 << WDE) |(1 << WDIE ) | (0 << WDP2) | (1 << WDP1) | (1 << WDP0)
        out     WDTCR, R16
        sei
smac
Цитата(Neutron @ Jun 24 2008, 11:17) *
Помогите пожалуйста!
Никак не могу запустить прерывание по watchdog на Tiny2313. Сбросы работают а прерывания ни в какую. help.gif Мне нужно чтобы при малом потреблении во время спячки прерывания происходили с частотой ~20 Гц.

Заинтересовала тема, написал тестовую программку, все заработало как и должно
Сперва прочитайте в даташите все про ВДТ, а не только описание регистра управления
Если после этого в моей программе что-то будет непонятно, обращайтесь
объясню более подробно.

Код
; логика работы тестовой программы

; 1. Инициализировать необходимые регистры
; 2. По прерыванию от ВДТ инвертировать PD1
; 3. По выходу из режима СЛИП инвертировать PD1
; 4. Выполнять пункты 2 и 3 пока есть питание и нет сброса

; Таймаут ВДТ 32 мс.

; в результате получаем на ноге PD1 (3 нога котроллера)
; меандр с периодом прблизительно 64 мс, на ноге PD2 меандр
; с тем же периодом, но в противофазе отностильно первого

.include "tn2313def.inc"
.org 0
rjmp start
.org    WDTaddr; Watchdog Timer Overflow
sbi pind, pd1; переворачиваем значение на ноге
reti

.org 0x20;
start:
;стек
ldi r16, low(RAMEND)
out spl, r16

; настраиваем нужные пины на выход
clr    r16
sbr r16, (1<<pd2)|(1<<pd1)
out    ddrd, r16


; инициализируем ватч дог таймер

; Turn off global interrupt
    cli
; Reset Watchdog Timer
    wdr
; Clear WDRF in MCUSR
    in r16, MCUSR
    cbr r16, (1<<WDRF)
    out MCUSR, r16
; записываем логические единицы to WDCE and WDE
; это необходимо для дальнейших операций с регистром WDTCSR
; Write logical one to WDCE and WDE
; Keep old prescaler setting to prevent unintentional time-out
    in r16, WDTCSR
    ori r16, (1<<WDCE) | (1<<WDE)
    out WDTCSR, r16; с этого момента до записи в регистр новых значений
                ; должно пройти не более четырех тактов

; Сбрасываем флаг прерываний ВДТ, разрешаем прерывания от ВДТ
; устанавливаем необходимый коэффициент деления
    sbr r16, (1<<wdif)|(1<<WDIE)|(1<<WDP0)
; запрещаем сброс от ВДТ
    cbr    r16, (1<<WDE)

; (вообще желательно конечно здесь производить запись в r16 одной
; командой например ldi r16, const, но что-то было лень считать константу)

; собственно применяем изменения
    out WDTCSR, r16
; вскидываем бит на нужной ноге
sbi portd, pd2

; устанавливаем слип мод и разрешаем слип
in    r16, mcucr
sbr r16, (1<<SE)|(1<<SM1)
out mcucr, r16
sei

met1:
        sleep        ; засыпаем
        sbi pind, pd2; "переворачиваем" значение на ноге
        rjmp    met1; бесконечный цикл


Извиняюсь за безобразное оформление кода, на скорую руку делал, поэтму мне должны быть скидки smile.gif
Neutron
Спасибо, smac, за ответ. Прерывания действительно заработали!
sethi
оживлю тему своим некропостом. для tiny2313 не могу вызвать программное прерывание по переполнению счетчика WDT. код на IAR, который по идее должен зажечь пин Б0 после срабатывание прерывания:

Код
//IAR Assembler for AVR 5.20.1 (5.20.1.50092)
#include <inavr.h>
#include <iotiny2313.h>  

#pragma vector = WDT_vect
__interrupt void WDT_ISR(void)
{
  MCUSR &= ~(1 << WDRF);            
  WDTCR |= (1<<WDIE);                // set WDIE to avoid hardware reset

  DDRB &= ~(1 << PINB0);              
  PORTB |= (1 << PINB0);             //лог 1 на пинБ0
}

void main(void)
{
  __disable_interrupt();
  __watchdog_reset();
  MCUSR &= ~(1<<WDRF);
  WDTCR |= (1<<WDCE) | (1<<WDE);
  WDTCR = (1<<WDP0) | (1<<WDP3) | (1<<WDIE);   //на 4с
  __enable_interrupt();


  while(1);
}



Proteus 7.5SP3 (7401) пишет WD Timer expired - Interrupt generated, но в обработчик прерывания не переходит. 7й бит в MCUSR выставляется в 1. Если вместо 1<<WDIE выставить 1<<WDE, мк будет хардрезетиться как и ожидалось. я чего-то не понимаю, в чем может быть дело?

avr studio 4.16 (628) из бесконечного цикла тоже не выходит (впрочем как и в примере, приведенном постом выше)
sethi
как и ожидалось, в кристалле тоже не происходит прерывания. I feel somewhat embarrassed for starting this post cranky.gif


править сообщения нельзя?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.