реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Прерывание в Tiny по WDT
Neutron
сообщение Jun 24 2008, 07:17
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 1-10-07
Пользователь №: 30 960



Помогите пожалуйста!
Никак не могу запустить прерывание по watchdog на Tiny2313. Сбросы работают а прерывания ни в какую. help.gif Мне нужно чтобы при малом потреблении во время спячки прерывания происходили с частотой ~20 Гц.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 24 2008, 08:16
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Neutron @ Jun 24 2008, 10:17) *
Никак не могу запустить прерывание по watchdog на Tiny2313. Сбросы работают а прерывания ни в какую.
Может быть, в спячке запрещены прерывания (бит I=0 в регистре состояния)?
Go to the top of the page
 
+Quote Post
Neutron
сообщение Jun 24 2008, 09:01
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 1-10-07
Пользователь №: 30 960



Цитата(Палыч @ Jun 24 2008, 12:16) *
Может быть, в спячке запрещены прерывания (бит I=0 в регистре состояния)?

Перед SLEEP давал SEI не помогло. Даже без спячки в прерывание не уходит. Если ставлю фуз WTDON, то сбрасывается, а не ставлю, то ни на прерывание ни на сброс не уходит, хотя как в pdf устанавливаю WDE или WDIE.
У кого нибудь реально работал watchdog как источник прерываний?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 24 2008, 10:13
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Neutron @ Jun 24 2008, 12:01) *
хотя как в pdf устанавливаю WDE или WDIE.
Код приведите... Видно что-то не по DS...
Go to the top of the page
 
+Quote Post
Neutron
сообщение Jun 24 2008, 10:23
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 1-10-07
Пользователь №: 30 960



Цитата(Палыч @ 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
Go to the top of the page
 
+Quote Post
smac
сообщение Jun 24 2008, 14:36
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003



Цитата(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
Go to the top of the page
 
+Quote Post
Neutron
сообщение Jun 25 2008, 09:23
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 1-10-07
Пользователь №: 30 960



Спасибо, smac, за ответ. Прерывания действительно заработали!
Go to the top of the page
 
+Quote Post
sethi
сообщение Jun 8 2009, 08:24
Сообщение #8





Группа: Новичок
Сообщений: 2
Регистрация: 8-06-09
Пользователь №: 50 054



оживлю тему своим некропостом. для 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) из бесконечного цикла тоже не выходит (впрочем как и в примере, приведенном постом выше)
Go to the top of the page
 
+Quote Post
sethi
сообщение Jun 8 2009, 19:18
Сообщение #9





Группа: Новичок
Сообщений: 2
Регистрация: 8-06-09
Пользователь №: 50 054



как и ожидалось, в кристалле тоже не происходит прерывания. I feel somewhat embarrassed for starting this post cranky.gif


править сообщения нельзя?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 13:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01437 секунд с 7
ELECTRONIX ©2004-2016