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

 
 
> Пишу код для часов. Не работают прерывания по переполнению таймера
bookerist
сообщение Jul 2 2011, 08:41
Сообщение #1





Группа: Новичок
Сообщений: 4
Регистрация: 28-06-11
Пользователь №: 65 932



Написал программу электронных часов, работающие на режиме СТС таймера0. Но прерывания упорно не хотят прерыватьсяsm.gif
Частоту работы таймера я еще не настроил, потому что еще нету кварца на таймер, поэтому там два значения которые напрямую зависят от частоты я написал "от балды". Вот сама программа (для амеги64):

Код
;программа электронных часов
;16.06.2011г.
;Черепанов Сергей Андреевич
;для ATMega64
.device ATMega64;
.nolist;
.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m64def.inc";
.list;
.def temp=r16;
.def seconds=r17;
.def minutes=r18;
.def hours  =r19;
.def incr   =r20;
.def min_ed =r21;
.def min_des=r22;
.def hs_ed  =r23;
.def hs_des =r24;

;===============================================================
            ;здесь находятся макросы
.macro pushf;
     push r16;
     in  r16,sreg;
     push r16;
.endm

.macro popf;
     pop r16;
     out sreg,r16;
     pop r16;
.endm;

.macro delenie_min;
            ;первый макрос-раскидывает значение minutes по переменным, а именно:
            ;десятки минут в переменную min_des, а единицы в min_ed
     push minutes ;сохраняем первоначальное значение minutes;
     pushf;
loop:
     cpi  minutes,10;
     brmi ostatok ;если число >10, то вылезет флаг отриц. числа, и произойдет переход
     sbci minutes,10;
     inc  min_des;
     jmp  loop;

ostatok:
     mov  min_ed,minutes;
     popf;
     pop  minutes ;вытаскиваем обратно значение minutes
    
.endm;

.macro delenie_hs ;аналогично только работает со значениями hours, hs_ed, hs_des
     push hours;сохраняем первоначальное значение hours;
     pushf;
loop:
     cpi  hours,10;
     brmi ostatok ;если число меньше 10, то вылезет флаг отриц. числа, и произойдет переход
     sbci hours,10;
     inc  hs_des;
     jmp  loop;

ostatok:
     mov  hs_ed,hours;
     popf;
     pop  hours;вытаскиваем обратно значение hours
    
.endm;

.macro select     ;выбирает правильный код, который выводится на индикатор
     pushf;

     cpi  temp,0;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,1;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,2;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,3;
     brne pc+2;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,4;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,5;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,6;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,7;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,8;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;

     cpi  temp,9;
     brne pc+3;
     ldi  temp,0b00111111;
     rjmp exit;
exit:
     popf;
.endm;
;===============================================================



;===============================================================
.cseg;
.org 0xff;видимо с 250-ой строки начинается eeprom, и вылетает ошибка,
    ;поэтому код начинается со строки 0xff

;таблица прерываний:  
.org        0x0000 jmp Init; Reset Handler
.org        0x0002 reti; IRQ0 Handler
.org        0x0004 reti; IRQ1 Handler
.org        0x0006 reti; IRQ2 Handler
.org        0x0008 reti; IRQ3 Handler
.org        0x000A reti; IRQ4 Handler
.org        0x000C reti; IRQ5 Handler
.org        0x000E reti; IRQ6 Handler
.org        0x0010 reti; IRQ7 Handler
.org        0x0012 reti; Timer2 Compare Handler
.org        0x0014 reti; Timer2 Overflow Handler
.org        0x0016 reti; Timer1 Capture Handler
.org        0x0018 reti; Timer1 CompareA Handler
.org        0x001A reti; Timer1 CompareB Handler
.org        0x001C reti; Timer1 Overflow Handler
.org        0x001E reti; Timer0 Compare Handler
.org        0x0020 rjmp timer_ok; Timer0 Overflow Handler
.org        0x0022 reti; SPI Transfer Complete Handler
.org        0x0024 reti; USART0 RX Complete Handler
.org        0x0026 reti; USART0,UDR Empty Handler
.org        0x0028 reti; USART0 TX Complete Handler
.org        0x002A reti; ADC Conversion Complete Handler
.org        0x002C reti; EEPROM Ready Handler
.org        0x002E reti; Analog Comparator Handler
.org        0x0030 reti; Timer1 CompareC Handler
.org        0x0032 reti; Timer3 Capture Handler
.org        0x0034 reti; Timer3 CompareA Handler
.org        0x0036 reti; Timer3 CompareB Handler
.org        0x0038 reti; Timer3 CompareC Handler
.org        0x003A reti; Timer3 Overflow Handler
.org        0x003C reti; USART1 RX Complete Handler
.org        0x003E reti; USART1,UDR Empty Handler
.org        0x0040 reti; USART1 TX Complete Handler
.org        0x0042 reti; Two-wire Serial Interface Handler
.org        0x0044 reti; SPM Ready Handler

rjmp init;

;===============================================================
    ;подпрограмма срабатывающая при прерывании, инкрементирует значение incr,и
    ;сравнивает с определенной константой, зависящей от частоты работы таймера
    ;в случае равенства incr сбрасывается, а seconds инкрементируется
timer_ok:
     pushf;
     inc  incr;
     cpi  incr,100;вот эта сотня по идее и написана "от балды"
     breq equal;
     jmp  exit;

equal:
     clr incr;
     inc seconds;

exit:
     popf;
     reti;
;===============================================================

init:

    
     clr  r16;            на всякий случай подчистим регистры
     clr  r17;
     clr  r18;
     clr  r19;
     clr  r20;
     clr  r21;
     clr  r22;
     clr  r23;
     clr  r24;
     out  sreg,temp;

     LDI  R16,Low(RAMEND);инициализируем стек   |
     OUT  SPL,R16;                               |
;                                                |
     LDI  R16,High(RAMEND);                      |
     OUT  SPH,R16;                           ____|

    
     ldi temp,0x99;грузим значение, до которого будет бегать таймер (0х99-число абсолютно случайное, я его потом поменяю)
     out ocr0,temp;

     ldi temp,(WGM01<<1)|(WGM00<<0)|(CS02<<1)|(CS01<<1)|(CS00<<1);поставил таймер в
     out tccr0,temp; режим СТС и прескалер =1024
    
     ldi temp,(TOIE0<<1);разрешам прерывания локально
     out TIMSK,temp;

     ldi temp,(TOV0<<1);
     out tifr,temp;
;===============================================================

Start:
;на всякий случай еще раз разрешам прерывания локально:
     ldi temp,0b00000001;
     out TIMSK,temp;
     out TIFR,temp;

;эта часть кода выводит на индикаторы значение минут и секунд
     delenie_min;
     delenie_hs;
    
     cpi min_ed,10;     ;brmi может не достать до инит, поэтому юзать jmp
     brmi pc+2          ;brmi работает по принципу Rd-const, и если min_ed>10 то
     rjmp init;         ;получится положительное число, чего быть не должно
                        ;значит программа сбилась...
     mov temp,min_ed    ;т.к. макрос работает только с темп, то туда и грузим значение
     select;
     out porta,temp     ;на выходе получаем в качестве темр нужное число

     cpi min_des,10     ;здесь аналогичная проверка
     brmi pc+2;
     rjmp init;

       mov temp,min_des;в след. трех случаях аналогично используем макрос
     select;
     out portb,temp;

     cpi hs_ed,10     ;здесь аналогичная проверка
     brmi pc+2;
     rjmp init;

     mov temp,hs_ed;
     select;
     out portc,temp;

     cpi hs_des,10     ;здесь аналогичная проверка
     brmi pc+2;
     rjmp init;

     mov temp,hs_des;
     select;
     out portd,temp;
                        
                        
;здесь уже начинается проверка на увеличение переменных                        
                        ;
     cpi  seconds,60;
     breq pc+2          ;здесь срабатывает если прошла одна минута
     rjmp start         ;значит еще не прошла одна минута
    
     clr  seconds;
     inc  minutes;
     cpi  minutes,60;
     breq pc+2          ;срабатывает если прошел один час
     rjmp start         ;еще не прошел один час

     clr  minutes;
     inc  hours;
     cpi  hours,24;
     breq pc+2          ;аналогично
     rjmp start;
    
     clr  hours;
     rjmp start;


Сообщение отредактировал bookerist - Jul 2 2011, 08:43
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 06:10
Рейтинг@Mail.ru


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