Таймеры/счётчики в AVR
-
watchmaker
- Поставщик валерьянки для Кота
- Сообщения: 2183
- Зарегистрирован: Вс ноя 15, 2009 23:13:59
- Откуда: Харьков
- Контактная информация:
Re: Таймеры/счётчики в AVR
Кстати, цеплял к тиньке кварц 3.2768 МГц - тоже завышало порядка 0.1% независимо от конденсаторов. ЧЯДНТ?
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
- Реклама
Re: Таймеры/счётчики в AVR
Подскажите, пожалуйста, почему не срабатывает прерывание по совпадению таймера, точнее прерывание то есть, только оно попадает на другой вектор почему то. МК - ATmega164. Вроде все перепроверил, все настройки правильные, но в AVR Studio 6 и в Proteuse прерывание попадает на строку компаратора или АЦП в таблице векторов
Спойлер
Код: Выделить всё
.include "m164pdef.inc"
.def temp = r16 ; Буфер
.def Counter = r17 ; Переменная цикла
.equ deley_vkl_0 = 35
.cseg ; Выбор сегмента программного кода
;------------------------- Начало программного кода
.org 0 ; Установка текущего адреса на ноль
jmp RESET ; Переход на начало программы
reti ; jmp EXT_INT0 ; Внешнее прерывание 0
reti ; jmp INT1 ; Внешнее прерывание 1
reti ; jmp INT2
reti ; jmp PCINT0 ; PCINT0 Handler
reti ; jmp PCINT1 ; PCINT1 Handler
reti ; jmp PCINT2 ; PCINT2 Handler
reti ; jmp PCINT3
reti ; jmp WDT ; Watchdog Timer Handler
reti ; jmp TIMER2_COMPA ; Timer2 Compare A Handler
reti ; jmp TIMER2_COMPB ; Timer2 Compare B Handler
reti ; jmp TIMER2_OVF ; Timer2 Overflow Handler
reti ; jmp TIMER1_CAPT ; Timer1 Capture Handler
jmp TIMER1_COMPA ; Timer1 Compare A Handler
reti ; jmp TIMER1_COMPB ; Timer1 Compare B Handler
reti ; jmp TIMER1_OVF ; Timer1 Overflow Handler
reti ; jmp TIMER0_COMPA ; Timer0 Compare A Handler
reti ; jmp TIMER0_COMPB ; Timer0 Compare B Handler
reti ; jmp TIMER0_OVF ; Timer0 Overflow Handler
reti ; jmp SPI, STC ; SPI Transfer Complete Handler
reti ; jmp USART0, RX ; USART, RX Complete Handler
reti ; jmp USART0, UDRE ; USART, UDR Empty Handler
reti ; jmp USART0, TX ; USART, TX Complete Handler
reti ; jmp ANA_COMP
reti ; jmp ADC ; ADC Conversion Complete Handler
reti ; jmp EE_RDY ; EEPROM Ready Handler
reti ; jmp TWI ; 2-wire Serial Interface Handler
reti ; jmp SPM_RDY ; Store Program Memory Ready Handler
reti ; jmp USART1, RX
reti ; jmp USART1, UDRE
reti ; jmp USART1, TX
; ------------------------- Модуль инициализации --------------------------------------
RESET:
;-------------------------- Инициализация портов ВВ ---------------------------------
clr temp ; Записываем 0 в регистр temp
out PORTD, temp ; порт PD0-PD5: выход =0, PD6: вход =Z
ldi temp, 0x7B
out DDRD, temp ; 01111011 - "1"-выход, "0"-вход, 2-й бит на вход - внешнее прерывание INT0
clr temp
out PORTB, temp
ldi temp, 0xFF ; 11111111 все на выход
out DDRB, temp
ldi temp, 0x80 ; Аналог. компаратор откл.
out ACSR, temp
;-------------------------- Инициализация таймера T1 ------------------------------------
ldi temp, 0x0A ; 00001010 - режим СТС - сброс по совпадению и запуск таймера
sts 0x81, temp ; TCCR1B
ldi temp, deley_vkl_0
sts 0x88, temp ; в OCR1A записали число 35
ldi temp, 0x02
sts 0x6F, temp ; разрешаем прерывание по событию "Совпадение А" TIMSK1
;-------------------------- Инициализация стека ------------------------------------------
ldi temp,low(RAMEND) ; Выбор адреса вершины стека (адрес конца RAM)
out SPL,temp ; Запись его в регистр стека
ldi temp,high(RAMEND) ;
out SPH, temp
sei
;-------------------------- Начало основной программы
lp00:
loop5: sbic PIND, 7 ; ждём приход 1 втечение 0.51(мс) если 6-й бит регистра PIND = 0, то след. команда пропускается
jmp loop6
in temp, TIFR1
sbrs temp, 1
jmp loop5
jmp lp00
loop6:
;====================
; Подпрограмма обработки прерываний
;====================
TIMER1_COMPA:
clr temp
reti- Вложения
-
- ATmega164.gif
- (188.49 КБ) 521 скачивание
Истина где-то рядом...
Re: Таймеры/счётчики в AVR
Если ещё актуально. Проще явно указать адрес вектора
Регистр OCR1A двухбайтовый и для таких регистров периферии есть определенный порядок записи/чтения
Регистр OCR1A двухбайтовый и для таких регистров периферии есть определенный порядок записи/чтения
Спойлер
Код: Выделить всё
.org 0 ; Установка текущего адреса на ноль
jmp RESET ; Переход на начало программы
reti ; jmp EXT_INT0 ; Внешнее прерывание 0
reti ; jmp INT1 ; Внешнее прерывание 1
reti ; jmp INT2
reti ; jmp PCINT0 ; PCINT0 Handler
reti ; jmp PCINT1 ; PCINT1 Handler
reti ; jmp PCINT2 ; PCINT2 Handler
reti ; jmp PCINT3
reti ; jmp WDT ; Watchdog Timer Handler
reti ; jmp TIMER2_COMPA ; Timer2 Compare A Handler
reti ; jmp TIMER2_COMPB ; Timer2 Compare B Handler
reti ; jmp TIMER2_OVF ; Timer2 Overflow Handler
reti ; jmp TIMER1_CAPT ; Timer1 Capture Handler
.org 0x001A ; Установка вектора сравнения таймера 1А
jmp TIMER1_COMPA ; Timer1 Compare A Handler
;
;
;
;
;
;
;-------------------------- Инициализация таймера T1 ------------------------------------
LDI XH,HIGH(deley_vkl_0)
LDI XL,LOW(deley_vkl_0)
STS OCR1AH,XH
STS OCR1AL,XL
LDI R16,1<<OCIE1A
STS TIMSK1,R16 ; разрешаем прерывание по событию "Совпадение А" TIMSK1
LDI R16,1<<WGM12|1<<CS11
STS TCCR1B,R16 ;режим СТС - сброс по совпадению и запуск таймера Fclk/8
; ldi temp, 0x0A ; 00001010 - режим СТС - сброс по совпадению и запуск таймера
; sts 0x81, temp ; TCCR1B
; ldi temp, deley_vkl_0
; sts 0x88, temp ; в OCR1A записали число 35
; ldi temp, 0x02
; sts 0x6F, temp ; разрешаем прерывание по событию "Совпадение А" TIMSK1
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: Таймеры/счётчики в AVR
Попадает оно на тот вектор, это Вы таблицу векторов неправильно заполнили. Поглядите таблицу векторов в ДШ, у данного камня один вектор занимает два слова памяти программ. Команда-затычка RETI однословная команда. На Вашем скрине как раз видно, что программный счетчик указывает на 0x1A, т.е. это адрес нужного Вам вектора.artemik32 писал(а):только оно попадает на другой вектор почему то.
Можно вставить двухсловные команды на неиспользуемые вектора, например
Код: Выделить всё
jmp RESETКод: Выделить всё
nop
nopМожно в вектор вставить директиву .dw 0x0000.
Или воспользуйтесь директивой .ORG, как указал akl.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Таймеры/счётчики в AVR
тем более что для каждого адреса вектора уже определены соответствующие символьные константы. И это не только проще, но и правильнее - я об этом неоднократно говорил, и буду говорить.akl писал(а):Проще явно указать адрес вектора
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
Re: Таймеры/счётчики в AVR
Да спасибо, я уже написал конкретный адрес перехода на вектор как предложил akl. Так нормально работает, а с младшими мегами таких проблем не было, у которых используется команда rjmp вместо jmp, и памяти у них 8 кб и меньше.
Истина где-то рядом...
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Таймеры/счётчики в AVR
[uquote="akl",url="/forum/viewtopic.php?p=3132093#p3132093"][/uquote]
Неправильно! JMP - два слова. RETI - одно слово. И два RETI займет один вектор. Правильно нужно писать так:
Такая запись будет верной:
Код: Выделить всё
.org 0 ; Установка текущего адреса на ноль
jmp RESET ; Переход на начало программы
reti ; jmp EXT_INT0 ; Внешнее прерывание 0
reti ; jmp INT1 ; Внешнее прерывание 1
reti ; jmp INT2
reti ; jmp PCINT0 ; PCINT0 Handler
reti ; jmp PCINT1 ; PCINT1 Handler
reti ; jmp PCINT2 ; PCINT2 Handler
reti ; jmp PCINT3
reti ; jmp WDT ; Watchdog Timer Handler
reti ; jmp TIMER2_COMPA ; Timer2 Compare A Handler
reti ; jmp TIMER2_COMPB ; Timer2 Compare B Handler
reti ; jmp TIMER2_OVF ; Timer2 Overflow Handler
reti ; jmp TIMER1_CAPT ; Timer1 Capture Handler
.org 0x001A ; Установка вектора сравнения таймера 1А
jmp TIMER1_COMPA ; Timer1 Compare A Handler
Неправильно! JMP - два слова. RETI - одно слово. И два RETI займет один вектор. Правильно нужно писать так:
Код: Выделить всё
.org 0x0000
jmp RESET ; Reset Handler
.org OC2addr
jmp TIM2_COMP ; Timer2 Compare Handler
.org URXC0addr
jmp RS232_VESS; USART0 RX Complete Handler
.org ADCCaddr
jmp ADC_Complet
.org URXC1addr
jmp USART1_RXC; USART1 RX Complete Handler
.org UDRE1addr
jmp USART1_UDRE; USART1 TX Complete Handler
Код: Выделить всё
.org UDRE1addr
reti ; jmp USART1_UDRE; USART1 TX Complete Handler
-
forfrends
- Вымогатель припоя
- Сообщения: 546
- Зарегистрирован: Вс дек 30, 2012 00:32:06
- Откуда: Николаев / Украина
- Контактная информация:
Re: Таймеры/счётчики в AVR
Друзья, всем привет.
Пытаюсь разобраться с таймерами, и столкнулся с непонятной для меня информацией. Пишу в Ардуино ИДЕ. Микроконтроллер: Атмега168
Цель: нужно вызывать функцию 1 раз в секунду (по сути это часы, только назначение другое). Решил все это делать на таймере. Залез в даташит: 0-й и 2-й таймеры 8-мибитные, значит отпадают, остается 1-й таймер. По настройке немного сложно, делаю в первый раз, но в принципе разобраться можно.
Вот примерно что я собираюсь делать, Так правильно? и нужно ли делать сброс таймера?:
Добавлено after 44 minutes 55 seconds:
Пробую, но ничего не работает... код:
Пытаюсь разобраться с таймерами, и столкнулся с непонятной для меня информацией. Пишу в Ардуино ИДЕ. Микроконтроллер: Атмега168
Цель: нужно вызывать функцию 1 раз в секунду (по сути это часы, только назначение другое). Решил все это делать на таймере. Залез в даташит: 0-й и 2-й таймеры 8-мибитные, значит отпадают, остается 1-й таймер. По настройке немного сложно, делаю в первый раз, но в принципе разобраться можно.
Вот примерно что я собираюсь делать, Так правильно? и нужно ли делать сброс таймера?:
Код: Выделить всё
TCCR1B |= (1<<WGM12);
TCCR1B |= (1<<CS12); // делитель 256
TIMSK |=(1<<OCIE1A); // прерывание по совпадению
OCR1AH = 0b11110100; // число для сравнения 62500
OCR1AL = 0b00100100;
....
ISR (TIMER1_COMPA_vect)
{
// какое-то действие
}Пробую, но ничего не работает... код:
Код: Выделить всё
int i=10;
ISR (TIM1_COMPA)
{
// какое-то действие
i=i+1;
}
void setup(void) {
// flip screen, if required
// u8g.setRot180();
TCCR1B |= (1<<WGM12);
TCCR1B |= (1<<CS12); // делитель 256
TIMSK1 |=(1<<OCIE1A); // прерывание по совпадению
OCR1AH = 0b11110100; // число для сравнения 62500
OCR1AL = 0b00100100;
Serial.begin(9600);
}
void loop(void) {
Serial.println(i);
// rebuild the picture after some delay
delay(100);
}Сделать своими руками всегда интересней чем просто купить и пользоваться
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Таймеры/счётчики в AVR
в режиме СТС он сам сбрасывается
Добавлено after 2 minutes 38 seconds:
разрешение прерываний (глобальное)?
Добавлено after 2 minutes 38 seconds:
разрешение прерываний (глобальное)?
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
-
forfrends
- Вымогатель припоя
- Сообщения: 546
- Зарегистрирован: Вс дек 30, 2012 00:32:06
- Откуда: Николаев / Украина
- Контактная информация:
Re: Таймеры/счётчики в AVR
Да вроде как по умолчанию они включены.
Пробовал дописывать sei() но это ничего не изменило. В общем я в ступоре... Может что-то элементарное пропускаю? С тем же ISR не все понятно. В одних местах он прописан как TIM1_COMPA в других по-другому. Пробовал и так и так - нет результата.
Пробовал дописывать sei() но это ничего не изменило. В общем я в ступоре... Может что-то элементарное пропускаю? С тем же ISR не все понятно. В одних местах он прописан как TIM1_COMPA в других по-другому. Пробовал и так и так - нет результата.
Сделать своими руками всегда интересней чем просто купить и пользоваться
- hosturik
- Потрогал лапой паяльник
- Сообщения: 354
- Зарегистрирован: Чт июл 24, 2014 23:09:23
- Откуда: Киев
Re: Таймеры/счётчики в AVR
[uquote="forfrends",url="/forum/viewtopic.php?p=3161707#p3161707"]Пробую, но ничего не работает...[/uquote]
Попробуйте так. Глобальные прерывания нужно разрешать в вашем случае.
Попробуйте так. Глобальные прерывания нужно разрешать в вашем случае.
Спойлер
Код: Выделить всё
int i=10;
ISR (TIMER1_OVF_vect)
{
TCNT1 = 0xC2F7;
// какое-то действие
i++;
}
void setup(void) {
//Инициализация таймера 1
TCCR1B = 0b101; // делитель на 1024
TIMSK1 |= (1<<TOIE1); //активировать прерывание по переполнению таймера
TCNT1 = 0xC2F7; // частота прерываний 1 Гц для F_CPU = 16 000 000
Serial.begin(9600);
sei();
}
void loop(void) {
Serial.println(i);
// rebuild the picture after some delay
delay(100);
}- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: Таймеры/счётчики в AVR
volatile int i=10;forfrends писал(а):Пробую, но ничего не работает
Re: Таймеры/счётчики в AVR
[uquote="forfrends",url="/forum/viewtopic.php?p=3161707#p3161707"]... Так правильно?
[/uquote]Замечу, в OCR1x(ICR1) для точной выдержки времени нужно заносить значение на 1 меньшее, особенно при использовании предделителя. Т.е. 62500-1
Код: Выделить всё
TCCR1B |= (1<<WGM12);
TCCR1B |= (1<<CS12); // делитель 256
TIMSK |=(1<<OCIE1A); // прерывание по совпадению
OCR1AH = 0b11110100; // число для сравнения 62500
OCR1AL = 0b00100100;
...
ISR (TIMER1_COMPA_vect)
{
// какое-то действие
}Re: Таймеры/счётчики в AVR
Помогите. В протеусе все симулирует чётко. Загружаю в МК не отрабатывает прерывание по переполнению таймера1. Мк аттини85.
Правильно ли инициализировал прерывание?
Правильно ли инициализировал прерывание?
Код: Выделить всё
//инициализация таймера1
void timer1_ini (void){
TCCR1 |= (1 << CTC1) //режим CTC
|(0<<COM1A1)|(0<<COM1A0) //отключаем OC1A
|(1 << CS13)|(0 << CS12)|(1 << CS11)|(0 << CS10); //Делитель 512
TCNT1 = 0x00; //сброс счетчика
OCR1A = 0xFF; //регистр сравнения
TIMSK |=(1<<TOIE1); //включаем прерывания по переполнению
}
//обработка прерывания таймера1
ISR(TIMER1_OVF_vect){
PORTB |= (1<<PB1);
}Re: Таймеры/счётчики в AVR
SEI не хватает.
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Таймеры/счётчики в AVR
[uquote="akl",url="/forum/viewtopic.php?p=3205345#p3205345"]SEI не хватает.[/uquote]
В функции инициализации глобальное включение прерываний не обязано быть. Только после инициализации всей нужной периферии.
В функции инициализации глобальное включение прерываний не обязано быть. Только после инициализации всей нужной периферии.
Re: Таймеры/счётчики в AVR
SEI есть в программе, даже есть ещё одно прерывание по таймеру0 (TIMER0_COMPA_vect) и оно работает, а по этому вектору нет, да и интересно почему в протеусе все как надо работает, а в реальном МК нет? мб МК бракованный >_<
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18561
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Таймеры/счётчики в AVR
МК бракованный... еще может быть компилятор лажает - это две любимые причины всех проблем начинающих.fulky писал(а):интересно почему в протеусе все как надо работает, а в реальном МК нет? мб МК бракованный
у вас схема протеуса на 100% соответствует реальной? в реальной ошибок нет? что вы ждете от обработчика с единственным оператором, какие эффекты быть должны, а их нет? ни схемы, ни всей программы, одни загадки-догадки.
я вам точно скажу, в чем причина: у вас есть ошибка. полегчало?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Таймеры/счётчики в AVR
Думаю, прерывание по переполнению никогда не возникает, т.к. таймер работает до 0xFF. Попробуйте прерывание OCIE1A
Re: Таймеры/счётчики в AVR
из-за оптимизации такое может происходить, (-O) выставлена?МК бракованный... еще может быть компилятор лажает - это две любимые причины всех проблем начинающих.
Режимы работы реле
1. Потенциометром задается режим от 1 до 4, как на картинке, удержанием кнопки переход на следующий шаг
2. Задается время t1
3. Указываются в чем считать С, М, Ч
4. Задается время t2
5. Указываются в чем считать С, М, Ч
6. Происходит запуск (PB1 рулит реле по выбранному режиму)
Косяк в том, что нет бегающей индикации во время работы
Добавлено after 31 minute 54 seconds:
[uquote="akl",url="/forum/viewtopic.php?p=3205391#p3205391"]Думаю, прерывание по переполнению никогда не возникает, т.к. таймер работает до 0xFF. Попробуйте прерывание OCIE1A[/uquote]
т.е. сделать по вектору TIMER1_COMPA и через сравнение с OCR1A??
- Вложения
-
- AVR.rar
- код и протеус
- (85.26 КБ) 208 скачиваний



