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

Почему одно прерывание блокирует другое?

27.07.2013, 01:05. Просмотров 841. Ответов 4
Метки нет (Все метки)

Не могу понять, что не так. В программе два прерывания. Одно прерывание по переполнению счетчика С0. Внешний сигнал генерирую с помощью свободной ножки PC3. Второе прерывание по совпадению значения таймера Т1 с числом. Проблема в том, что прерывание OVF0 никогда не выполняется и соответственно строчка out PortD, R1 тоже. А вот если Закомментировать строчки
Assembler
1
2
3
4
5
  
                        .org 6 
                        rjmp OC1A ; Прерывание при совпадении значения таймера Т1 с числом А
                        OC1A:
                        reti
тогда все пучком. Подскажите, что здесь не так?

Assembler
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
; *********************************************************
; Для AVR: AtMega8                                        *
; Тактовая частота: 8МГц                                  *
;**********************************************************
 
; Выполняемые функции: отображает частоту входного сигнала на трех
; семисегментных индикаторах
 
.device         atmega8
.nolist
.include "m8def.inc"   
.list
 
; =======================
; Обьявления
 
.def   temp            =r16
 
; =======================
; Начало программы
 
.org 0 
rjmp Init  
.org 6 
rjmp OC1A ; Прерывание при совпадении значения таймера Т1 с числом А
.org 9
rjmp OVF0 ; переход по переполнению счетчика С0     
 
 
 ; =======================
 ; Прерывание при переполнении счетчика С0
 OVF0:
   out  PortD, R1 
 reti  
 
 ; Прерывание при совпадении значения таймера Т1 с числом А
 OC1A:
 
 reti 
 
; =======================
Init:
 
  ; загрузка цифр
  ldi   temp,  0b11101110  ; 0
  mov   R0,    temp
  ldi   temp,  0b00100100  ; 1
  mov   R1,    temp
 
  ; Инициализация стека
  LDI temp,Low(RAMEND)
  OUT SPL,temp
  LDI temp,High(RAMEND)
  OUT SPH,temp
 
  ; Инициализация порта В. Светодиод, кварц, кнопки
  ldi   temp,  0b00001111   ; PB0-PB2 - не исп., PB3-голубой светодиод (указывает на кГц)
  out   DDRB,  temp         ; PB4-PB5 - кнопки (не используются), PB6, PB7 - кварц. 
  ldi   temp,  0b00110000   ; Подтяжка включена только для неиспользуемых кнопок
  out   PortB, temp    
 
  ; Инициализация порта С. Выбор семисегментного индикатора (разряда)
  ; для последовательного отображения цифры
  ldi   temp,  0b111111     ; Разряд 1: PС0, разряд 2: PС1, разряд 3: PС2 
  out   DDRC,  temp         ; PС3-соединен с ножкой PD4(T0), PC4-PС6 - не используются
  ldi   temp,  0b000010
  out   PortC, temp         ; все разряды выключены 
 
  ; Инициализация порта D. Подсветка сегментов, тактирующий вход для измерения частоты
  ldi   temp,  0b11101111   ; Светодиодный индикатор: PD0-g, PD1-f, PD2-c, 
  out   DDRD,  temp         ; PD3-d, PD4-внешнее тактирование, PD5-b, PD6-a, PD7-e.
  clr   temp
  out   PortD, R0         ; Подтяжка выключена, все выходы выключены 
 
  ; Настройка параметров счетчика Counter0
  ldi   temp,  0b00000111   ; 111 - тактирование по возрастанию импульса
  out   TCCR0, temp         ; остальные биты не используются
  ldi   temp,  0b00000001   ; 1 - прерывание по переполнению счетчика разрешено
  out   TIMSK, temp         ; остальные биты для других таймеров
 
  ; Настройка параметров 16-битного таймера Timer1
  ldi   temp,   0b00000010  ; тактовая частота / 8
  out   TCCR1B, temp        ; получаем частоту 1000000
  ldi   temp,   0b00010000  ; 
  out   TIMSK, temp         ; разрешить прерывание по совпадению
  ldi   temp,   0b00000000  ; младший байт числа для сравнения
  out   OCR1AL, temp        ;  
  ldi   temp,   0b11111010  ; старший байт числа для сравнения
  out   OCR1AH, temp        ; получаем число 64000
  ; это число тактов будет достигнуто за 0.064 сек.
 
  sei                       ; Разрешаем прерывания
 
 ; =======================
 ; Основное тело программы
 Start:
 
    ldi  temp,  0b001010
    out  PortC, temp
 
    ldi  temp,  0b000010
    out  PortC, temp
 
 rjmp Start
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.07.2013, 01:05
Ответы с готовыми решениями:

Четыре кнопки на одно прерывание
Возникла необходимость отслеживать четыре кнопки и мгновенно реагировать на нажатие одной из них,...

Несколько двойных кнопок на одно прерывание
Возникла необходимость подключить несколько кнопок, а прерываний мало и они нужны будут в другом...

Распознать как одно USB устройство как другое
Доброго времени суток! Скажите, пожалуйста, возможно ли, имея драйвер для одного МК (допустим,...

Почему программа на линуксе считает одно а на 7-ке другое?
#include <stdio.h> #include <math.h> #define w 4 double temp_matrix; void get_matrix(double...

Не вызывается 2 раза одно и тоже прерывание
Почему компилируется, а .com вылетает с ошибкой типа процессор выполнил недопустимую инструкцию...

4
paskal
455 / 303 / 29
Регистрация: 15.08.2011
Сообщений: 943
27.07.2013, 15:40 2
Все правильно. Прерывания не допускают вложенности как у подпрограмм. Прерывания одного уровня приоритета во всяком случае. А в AVR приоритеты прерываний не меняется как например в MCS51 насколько я знаю.

Добавлено через 1 час 23 минуты
Хотя дело тут похоже в другом:
Цитата Сообщение от Jurchello Посмотреть сообщение
А вот если Закомментировать строчки
Assembler
1
2
3
4
5
  
                        .org 6 
                        rjmp OC1A ; Прерывание при совпадении значения таймера Т1 с числом А
                        OC1A:
                        reti
тогда все пучком. Подскажите, что здесь не так?
Вы закомментировали переход на обработку прерывания, а прерывание от этого не исчезнет. Только обрабатывать первое прерывание теперь будет обработчик второго. Так что не все пучком, разбирайтесь где не так запрограммировали регистры.
И еще соображение. Эти 2 прерывания не должны возникать одновременно, IMHO блокировка одного прерывания другим здесь не при чем.
2
Jurchello
0 / 0 / 0
Регистрация: 15.10.2008
Сообщений: 33
27.07.2013, 17:35  [ТС] 3
Так у меня здесь вроди нет вложенности?
Как лучше сделать, чтобы они не дрались между собой?
0
paskal
455 / 303 / 29
Регистрация: 15.08.2011
Сообщений: 943
27.07.2013, 18:03 4
Вы невнимательно читаете. Я дальше и написал что у вас нет вложенности. Просто прерывание OVF0 не вызывается совсем.
1
Grey
Тутошний я
1758 / 916 / 162
Регистрация: 03.11.2009
Сообщений: 2,865
Записей в блоге: 1
27.07.2013, 23:13 5
Видимо в 79,80 строках ты включаешь прерывание по переполнению а в 85,86 отключаешь. Попробуй эти строки объеденить.
2
27.07.2013, 23:13
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.07.2013, 23:13

Одно под другое
Приветствую! Тут такое дело. Ковыряюсь с меню, пришла мысль. Сделать под круглой кнопкой меню...

Как пересчитать одно в другое?
b|g 0|0000000000 1|0000000001 2|0000000011 3|0000000111 4|0000000101 5|0000000100...

разделить одно число на другое
разделить одно число на другое, затем частное умножить на то же самое число и прибавить остаток(т.е...


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

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

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