1 / 1 / 0
Регистрация: 16.11.2015
Сообщений: 18
1

Внешние прерывания

02.01.2016, 22:36. Показов 590. Ответов 4
Метки нет (Все метки)

Всем привет! пытаюсь осуществить светодиодную подсветку лестницы. Вверху и внизу стоят датчики движения. Начинаешь подыматься ступеньки последовательно загораются, (при спуске тоже самое) проходит некоторое время и ступеньки так же последовательно затухают. Использую мега8, внешние прерывания (их там 2 (инт0,инт1)),таймер Т1.
Проблема в том что когда мк обрабатывает прерывание, допустим инт0, то надо сделать так чтобы он не видел прерывание по инт1 и наоборот.В начале и конце каждого кода обработки прерывания запрещаю и разрешаю внешние прерывания.Схему симулирую в протеусе, может на железе будет всё работать, просто слышал что протеус бывает гонит с прошивками мк. Или может есть еще какие пути решения проблемы, прошу помощи!!!!Вот код:

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
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//F = 4 mHz, коэффециент предделителя 1024
#include <mega8.h>
 
void wait2(void) // функция задержки времени на 16сек, используется несколько раз для выключения светодиодов
{
 
 TCNT1 = 0;
 while (TCNT1 <65534)
 {
 
 }
 
}
 
void wait1(void)//функция задержки времени на 400 мс, используется для последовательного включения светодиодов
{
 
TCNT1 = 0;
while(TCNT1 <1540)
{
}
 
}
interrupt [EXT_INT0] void ext_int0_isr(void)  //низ, начало лестницы
{
 #asm ("cli")// выключаем глобальные прерывания,чтобы не считывался сигнал от верхнего датчика 
 PORTB = 0b00000001;
 wait1();
 PORTB = 0b00000011;
 wait1();
 PORTB = 0b00000111;
 wait1();
 PORTB = 0b00001111;
 wait1();
 PORTB = 0b00011111;
 wait1();
 PORTB = 0b00111111;
 wait1();
 PORTB = 0b01111111;
 wait1();
 PORTB = 0b11111111;
 //выключение светодиодов через 32 сек
 
 wait2();  
 wait2(); 
 PORTB = 0b11111110;
 wait1();
 PORTB = 0b11111100;
 wait1();
 PORTB = 0b11111000;
 wait1();
 PORTB = 0b11110000;
 wait1();
 PORTB = 0b11100000;
 wait1();
 PORTB = 0b11000000;
 wait1();
 PORTB = 0b10000000;
 wait1();
 PORTB = 0b00000000;
 #asm("sei")
}
 
 
interrupt [EXT_INT1] void ext_int1_isr(void)  //верх, конец лестницы
{
 #asm("cli") //выключаем глобальные прерывания,чтобы не считывался сигнал от нижнего датчика
 PORTB = 0b10000000;
 wait1();
 PORTB = 0b11000000;
 wait1();
 PORTB = 0b11100000;
 wait1();
 PORTB = 0b11110000;
 wait1();
 PORTB = 0b11111000;
 wait1();
 PORTB = 0b11111100;
 wait1();
 PORTB = 0b11111110;
 wait1();
 PORTB = 0b11111111;
 //выключение светодиодов через 32 сек
  
 wait2();
 wait2();
 PORTB = 0b01111111;
 wait1();
 PORTB = 0b00111111;
 wait1();
 PORTB = 0b00011111;
 wait1();
 PORTB = 0b00001111;
 wait1();
 PORTB = 0b00000111;
 wait1();
 PORTB = 0b00000011;
 wait1();
 PORTB = 0b00000001;
 wait1();
 PORTB = 0b00000000;
 
 #asm("sei")
 
}
 
void main(void)
{
 
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
 
 
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
 
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
 
 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (1<<PORTD3) | (1<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
 
 
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 11,719 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 5,5924 s
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
 
 
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: On
// INT1 Mode: Falling Edge
GICR|=(1<<INT1) | (1<<INT0);
MCUCR=(1<<ISC11) | (0<<ISC10) | (1<<ISC01) | (0<<ISC00);
GIFR=(1<<INTF1) | (1<<INTF0);
 
 
// Global enable interrupts
#asm("sei")
 
while (1)
      {
      
 
      }
}
P.S.: Я начинающий поэтому прошу сильно не судить, недавно освоил таймер, раньше использовал delay_ms()
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.01.2016, 22:36
Ответы с готовыми решениями:

Внешние прерывания
нужно что бы при нажатии на кнопку отрабатывало прерывание. Я сделал так (все на мегае16, на...

Внешние прерывания
Добрый вечер, у меня на меге 8 работает ацп + необходимо обрадатывать внешнее прерывание от пина...

Внешние прерывания ATMega128
Всем привет. У меня задача такая: есть меиндр с изменяющейся частой и надо замерять время между...

мега48, внешние прерывания
всем здрасти) ситуация такова: планируется устройство с емкостной сенсорной клавиатурой, каждый...

4
977 / 601 / 100
Регистрация: 15.05.2012
Сообщений: 3,554
03.01.2016, 09:24 2
C
1
2
3
interrupt [EXT_INT0] void ext_int0_isr(void) *//низ, начало лестницы
{
*#asm ("cli")
Бессмысленно, т.к. при входе в обработчик микроконтроллер сам по железу запрещает прерывания, а при выходе по команде reti разрешает.
Непонятен алгоритм обработки. Нарисуйте.

Не по теме:

Вот сделаю себе лестницу - тоже надо будет подумать о подсветке.

1
1930 / 1245 / 124
Регистрация: 04.01.2010
Сообщений: 4,492
03.01.2016, 13:11 3
Цитата Сообщение от Specelectrokaz Посмотреть сообщение
надо сделать так чтобы он не видел прерывание по инт1
кажется, я понял, что вы хотите сделать.
Чтобы в момент одного прерывания система не "увидела" других событий, нужно либо отключать эти события, либо сбрасывать их флаги в момент выхода из прерывания. Результат будет тот же. Сам флаг, на который действуют команды cli, sei, управляет лишь возможностью запуска разрешенных прерываний. То есть если в момент сброшенного этого флага придет один или несколько включенных событий (например, по входу), то эти флаги и будут выставлены и ждать, пока вы не разрешите общий флаг прерываний командой sei. И после разрешения проц сразу пойдет их выполнять, в порядке приоритета (по порядковому номеру, в АВР).
Короче, сбрасывайте флаг прерывания INT1 в прерывании INT0 (в строчке перед reti) и все должно получиться.
1
469 / 318 / 29
Регистрация: 15.08.2011
Сообщений: 995
03.01.2016, 13:13 4
Цитата Сообщение от Specelectrokaz Посмотреть сообщение
Использую мега8, внешние прерывания (их там 2 (инт0,инт1))
Тут время реакции порядка секунды. Для процессора это вечность. Поэтому в прерываниях необходимости нет, можно простым опросом ножек заменить. И проблема с вложенностью прерываний сама собой исчезнет.
1
1 / 1 / 0
Регистрация: 16.11.2015
Сообщений: 18
03.01.2016, 14:25  [ТС] 5
Благодарю вас парни!!!! В моём городе программированию микроконтроллеров не учат даже в университетах, спросить соответственно не у кого, благо есть интернет!!!!! Сейчас я сделал всё без прерываний в основном цикле опрашиваю пины, потом вызывается соответствующая функция. В протеусе работает, пока только сделал на 8 ступенек(задействовал портВ).Программу пришлось полностью переделать))))))))).Сейчас лестница после включения через некоторое время сама гаснет, теперь буду стремиться к тому что бы по нижнему датчику лестница засияла,по верхнему потухла и наоборот и буду мудрить с флагами прерываний, я так понял что бы осуществить задуманное всё равно без них никуда!!!!
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
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <mega8.h>
int i = 0;
int effect1[8] = {1,3,7,15,31,63,127,255};
int effect2[8] = {128,192,224,240,248,252,254,255};
 
void wait1(void)
 {
 TCNT1 = 0;
 while(TCNT1 <1539)
 {
 }
}
 
void wait2(void)
{
 
TCNT1 = 0;
while(TCNT1 < 65534)
{
}
 
}
 
void leds1(void)
 
{
 for (i = 0; i<8; i++)
 {
 PORTB = effect1[i];
 wait1();
}
 wait2();
 for (i = 0; i<8; i++)
 {
  PORTB <<=1;
  wait1();
 }
}
 
void leds2(void)
{
for(i = 0; i<8; i++)
{
 
PORTB = effect2[i];
wait1();
 
}
 
wait2();
 
for(i = 0;i<8; i++)
{
 
PORTB >>=1;
wait1();
}
}
 
void main(void)
{
 
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
 
 
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
 
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (1<<PORTC0);
 
 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (1<<PORTD3) | (1<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
 
 
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 8,3886 s
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
 
 
while (1)
 {
 
 if (PIND.2 == 0)
 {
  leds1();
 }
   
 if (PIND.3 == 0)
 {
 
 leds2();
 
 }
 
 }
}
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.01.2016, 14:25

Внешние прерывания МК ATmega8535
Народ, кто-нибудь поможет решить задачу или хотя бы подсказать с чего начать? Просто знания...

Внешние прерывания для AtMega16
Всем ,привет!)Подскажите пожалуйста:как правильно написать код программы для внешнего прерывания?Ну...

внешние прерывания tiny85 - растолкуйте даташит!
я тут типа пытаюсь мелким шаговиком управлять напрямую. ловлю внешние импульсы и по их частоте -...

Нужен совет. Atmega88 + DS1307 + внешние прерывания
Собрался тут сделать один проектик, не знаю как пойдет, но если все будет ок, то будет и раздел в...


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

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

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