Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.82/17: Рейтинг темы: голосов - 17, средняя оценка - 4.82
dim3740
0 / 0 / 0
Регистрация: 26.04.2014
Сообщений: 109
1

Прерывания по таймеру Т1 в Atmega8

12.11.2014, 16:40. Просмотров 3370. Ответов 6
Метки нет (Все метки)

Нужно на одном таймере Т1 (16 бит) в Atmega8 получить 2 разных вектора А и В прерывания. Даташит: «В режиме Normal блоки сравнения OCR1A и OCR1B могут использоваться для генерации прерываний…». Т.е. надо разрешить эти прерывания и задать величины сравнения. Но мой МК не «видит» этого и прерывается только на ТОР. Меня устроил бы и режим СТС, но, вообще непонятно… ибо он же сбрасывает счет по достижении более раннего, скажем, А, и если В уставка больше, то до нее никогда счетчик не досчитает(((. В сети примеры нашел только по Т0/2.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.11.2014, 16:40
Ответы с готовыми решениями:

Не срабатывают внешние прерывания INT0/INT1 в Atmega8
Помогите разобраться новичку в МК, в чем может быть проблема. Пытаюсь освоить самостоятельно...

Не работают прерывания по таймеру ATtiny13a
Добрый день, уже замучился, что только не пробовал: менял компиляторы(WinAVR, AtmelStudio4,7),...

Разница между ATMEGA8-16AI и ATMEGA8-16AU
Кто подскажет, в чем разница между ATMEGA8-16AI и ATMEGA8-16AU. Смотрю в Платане цены между ними...

Прерывания по таймеру
Подскажите как сделать что бы прерывания от таймера срабатывало раз в секунду. Сильно не ругайте...

Прерывания по таймеру в PLC 1200
Всем хорошего дня. Столкнулся с проблемой. В PLC 200 есть команды для програмирования прерываний...

6
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
12.11.2014, 17:08 2
Код выкладывайте.
Скорей всего Вы не разрешили эти прерывания.
0
dim3740
0 / 0 / 0
Регистрация: 26.04.2014
Сообщений: 109
13.11.2014, 04:19  [ТС] 3
еще посмотрите, плз, м.б. надо/важно побайтно уставки записывать?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
 
//#define F_CPU 1000000UL
#define ZERO_CROSS PD2 //Вход импульсов ZERO-CROSS (INT0)
#define Sw1 PC0        //Кнопка включения и увеличения яркости
 
#define control_triac1A PD4      //Вывод на управляющий электрод симистора
#define control_triac1B PD5      //Вывод на управляющий электрод симистора
#define v_change_brightness1A 10 //Шаг регулировки скорости изменения яркости
#define v_change_brightness1B 8 //Шаг регулировки скорости изменения яркости
 
#define t_pulse_triac 70       //Длительность отпирающего импульса симистора 20 мкс 
 
volatile unsigned int brightness1A;
volatile unsigned int brightness1B;
 
ISR (INT0_vect)                             
{
    //запуск таймера Т1A    
    OCR1A = brightness1A; 
    TCCR1B |= _BV(CS10);  // CS10  - без делителя, режим Нормал, но с сравнением
    
    //запуск таймера Т1B
    OCR1B = brightness1B;
    TCCR1B |= _BV(CS10);    
}
 
ISR (TIMER0_OVF_vect)            
if(bit_is_clear(PINC, Sw1)) brightness1A += v_change_brightness1A;   //уменьшаем яркость
  
 
 
ISR (TIMER1_COMPA_vect)  //T1 прерывание для формирования открывающего импульса симистора
{
    PORTD |= _BV(control_triac1A);  //Передний фронт отпирающего импульса симистора
    _delay_us (t_pulse_triac);    //Длительность отпирающего импульса
    PORTD &= ~_BV(control_triac1A); //Задний фронт отпирающего импульса симистора
}
 
ISR (TIMER1_COMPB_vect)  //T1 прерывание для формирования открывающего импульса симистора
{
    PORTD |= _BV(control_triac1B);  //Передний фронт отпирающего импульса симистора
    _delay_us (t_pulse_triac);    //Длительность отпирающего импульса
    PORTD &= ~_BV(control_triac1B); //Задний фронт отпирающего импульса симистора
}
 
 
int main (void)
{
    PORTC |= _BV(Sw1);//кнопки с подтягивающими резисторами
    DDRD |= _BV(control_triac1A);  //выход управляющего электрода
    DDRD |= _BV(control_triac1B);  //выход управляющего электрода
    DDRD &= ~_BV(ZERO_CROSS);    //вход детектора нуля
    PORTD |= _BV(ZERO_CROSS);    //с подтягивающим резистором 
    MCUCR |= (1 << ISC00)|(1 << ISC01);    // прерывание по росту INT0
    GICR |= _BV(INT0);           //разрешаем внешнее прерывание 0
    
       TIMSK |= _BV(TOIE0);  //разрешаем прерывания таймеров 0  
 
    TIMSK |= _BV(OCIE1A); //разрешаем прерывания таймеров 1A
    TIMSK |= _BV(OCIE1B); //разрешаем прерывания таймеров 1B
        
    TCCR0 |= _BV(CS02);          //запускаем таймер 0 с предделителем на 256 для опроса кнопок регулировки яркости
    
    sei();                       //общее разрешение прерываний
    while(1)
  {}
}
Добавлено через 10 часов 53 минуты
Вопрос решился предварительным сбросом Т1 в перед запуском в функции ISR (INT_vect). Т.е: думаю, что запуск таймера не инициализирует его, он может приостанавливаться/возобновляться. После выхода на обработчик прерывания сравнения, счетчик продолжал счет, потом в него заносилась снова уставка, но его состояние в этот момент могло быть любым. Но остается вопрос (теоретический) - как можно применять режим СТС одновременно для А и В, если более ранний вектор ОБНУЛЯЕТ счет полностью, т.е. и для канала В?
0
Voland_
1689 / 1034 / 97
Регистрация: 04.01.2010
Сообщений: 3,483
13.11.2014, 11:22 4
Цитата Сообщение от dim3740 Посмотреть сообщение
вопрос (теоретический) - как можно применять режим СТС одновременно для А и В, если более ранний вектор ОБНУЛЯЕТ счет полностью, т.е. и для канала В?
Вопрос не совсем корректный, т.к. СТС работает только в регистром А, обнуляя счетчик при его достижении. Как он (даже логически) может работатб с Б, если он его не касается?
Но... подобный вопрос можно решить алгоритмически. Вам только нужно будет использовать одно прерывание СТС, постоянно считать сколько ждать тактов до следующего прерывания и какое именно прерывание должно произойти...
На пальцах можно объяснить так: например, А = 5, В = 8. Последний такт сработки А и В = 0.
1) Считаем до А. По сработке анализируем и определяем (по счетчикам сработки), что сработало прерывание А. Расчитываем следующую сработку для А = 5 и для В - (8-0)-5 =3. Соответственно, выставляем время сработки = 3. Выставляем текущее время сработки для А=0 (т.к. он только что сработал), для В=5.
2) Следующая сработка. Теперь логикой определяем, что сработало по событию "В", сбрасываем его счетчик, и инриминируем последний такт сработки для А. Снова вычисляем время следующей сработки = 2 (расчетом следующей сработки для каждого канала А,В... и выбором минимального).
И т.д.

ЗЫ: таким нехитрым способом можно делать на одном таймере хоть 100500 асинхронных процессов, но это требует некоторых временнЫх затрат.
1
dim3740
0 / 0 / 0
Регистрация: 26.04.2014
Сообщений: 109
13.11.2014, 11:54  [ТС] 5
Что СТС только с А - это для меня новость. Посмотрю повнимательнее...
0
Voland_
1689 / 1034 / 97
Регистрация: 04.01.2010
Сообщений: 3,483
13.11.2014, 13:17 6
Цитата Сообщение от dim3740 Посмотреть сообщение
Что СТС только с А
Да дело ж не в этом! Ну как вы себе представляете счетчик, считающий одновременно до 5 и до 8? Он, например, может считать до 8 в режиме CTC (когда в А будет 8), и быть настроенным при этом на прерывание при равенстве 5 для канала В. В этом случае, вы получите два прерывания. Но период их следования будет все равно общим.
1
dim3740
0 / 0 / 0
Регистрация: 26.04.2014
Сообщений: 109
13.11.2014, 13:28  [ТС] 7
Именно. Я тоже не представляю. Вывод: на два регистра сранения можно два вектора прерывния, при этом, если применяем режим стс, то на другой регистр возможно только иный вектор прерывания. Это логично, но почему я не вижу это в даташите(((
0
13.11.2014, 13:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.11.2014, 13:28

Прерывания по таймеру на Arduino Due (Atmel SAM3X8E)
Каким образом можно организовать прерывание по таймеру на Arduino due(sam3x8e)? Стандартные...

[Вопрос] Перехват прерывания прямым доступом к вектору прерывания
Всех приветствую! В данный момент разбираюсь с обработкой аппаратного прерывания (прерывание...

Вычислить адрес вектора прерывания по номеру прерывания.
17. По заданному номеру прерывания (13 h) вычислите логические адреса хранения исходных адресов...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru