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

 
 
> Глюк с таймером-1 на AVR AT90USB162
Halfback
сообщение May 24 2009, 11:53
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



В общем жизнь приказала использовать таймер-1. Инициализировал, написал функции по запуску и останову. Вот:

Код
void Timers_Init() { // Инициализация Таймеров
// Timer/Counter 0 initialization, Clock source: System Clock, Clock value: Timer 0 Stopped, Mode: Normal top=FFh, OC0A output: Disconnected, OC0B output: Disconnected
        TCCR0A=0x00;
        TCCR0B=0x00;
        TCNT0=0x00;
        OCR0A=0x00;
        OCR0B=0x00;

// Timer/Counter 1 initialization, Clock source: System Clock, Clock value: Timer 1 Stopped, Mode: Normal top=FFFFh, OC1A output: Discon.,OC1B output: Discon, OC1C output: Discon., Noise Canceler: Off, Input Capture on Falling Edge, Timer 1 Overflow Interrupt: Off, Input Capture Interrupt: Off, Compare A Match Interrupt: Off, Compare B Match Interrupt: Off, Compare C Match Interrupt: Off
        TCCR1A=0x00;
        TCCR1B=0x00;
        TCNT1H=0x00;
        TCNT1L=0x00;
        ICR1H=0x00;
        ICR1L=0x00;
        OCR1AH=0x00;
        OCR1AL=0x00;
        OCR1BH=0x00;
        OCR1BL=0x00;
        OCR1CH=0x00;
        OCR1CL=0x00;  
        
        TMR1_CURRENT_VALUE_S=0;
            
        TMR0_BUSY=0;  
        TMR1_BUSY=0;
        };

void Timers_Interrupt_Init() { // Инициализация прерываний от таймеров
        // Timer/Counter 0 Interrupt(s) initialization
        TIMSK0=0x01;
        // Timer/Counter 1 Interrupt(s) initialization
        TIMSK1=0x01;
        };  
        
// Функции управления таймером-1
void TMR1_START(uint16 value, uint8 clkd) {
    TCCR1B=clkd;
    TCNT1H= value>>8;
    TCNT1L= value & 0x00FF;
    }  
// переполнение через каждую 1мс если считать до 125 и clkd=3
// переполнение будет через каждую 1с если считать до 31250 и clkd=4
void TMR1_STOP(void) {
    TCCR1B = 0;
    TCNT1H=0;
    TCNT1L=0;
    }


Смысл в том, если в программе забито TMR1_START(0xFF00,4) то прерывание по переполнению счетчика возникает очень быстро. А должно через T=0xFF00/31250 = 2.08 сек. Дальше - интереснее. Если же в программе забито TMR1_START(0x00FF,4) то прерывание по переполнению счетчика возникает не через Т=0x00FF/31250=0.008 сек а через 2 секунды. Т.е. все происходит с точностью до наоборот. Думал ошибка в файле 90USB162.h - нет, там всё согласно свежей версии даташита на МЦУ. Вот что в файле:

Код
#define TCNT1L (*(unsigned char *) 0x84)
#define TCNT1H (*(unsigned char *) 0x85)


В доке смещения для регистров TCNT1L и TCNT1H cоответственно 0x84 и 0x85.

Никто не подскажет что за глюк такой? Ах, да, частота кварца 8МГц, фьюз CLKDIV не активирован.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Halfback
сообщение May 24 2009, 19:12
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



smac
В асме я не силен, но сгенерированный CAVR код в двух случаях (с приведением к типи и без) одинаков. Считал для HEX-файла md5 - одинакова. Наверное по горячке глаз замылися.

Код
;// Функции управления таймером-1
;void TMR1_START(uint16 value,uint8 clkd) {
_TMR1_START:
;value= (uint16) (0xFFFF-value);
;    value -> Y+1
;    clkd -> Y+0
    LDD  R26,Y+1
    LDD  R27,Y+1+1
    LDI  R30,LOW(65535)
    LDI  R31,HIGH(65535)
    SUB  R30,R26
    SBC  R31,R27
    STD  Y+1,R30
    STD  Y+1+1,R31
;TCNT1H= value>>8;
    LDD  R30,Y+2
    STS  133,R30
;TCNT1L= value & 0x00FF;
    LDD  R30,Y+1
    LDD  R31,Y+1+1
    STS  132,R30
;TCCR1B=clkd;
    LD   R30,Y
    STS  129,R30
;}
    JMP  _0x2060003

;void TMR1_STOP(void) {
;void TMR1_STOP(void) {
_TMR1_STOP:
;TCCR1B = 0;
    CALL SUBOPT_0x25
; TCNT1H=0;
;TCNT1L=0;
;     }
    RET


Сообщение отредактировал Halfback - May 24 2009, 19:24
Go to the top of the page
 
+Quote Post
galjoen
сообщение May 24 2009, 19:30
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(Halfback @ May 24 2009, 23:12) *
smac
В асме я не силен, но сгенерированный CAVR код вот такой:

Не нужно знать асм чтобы увидеть что код в этих случаях совершенно одинаков. Хотя конечно далеко не оптимален. Видимо дело в другом. Чему равны R26 и R27 после загрузки их командами LDD?
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 14:34
Рейтинг@Mail.ru


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