Без описания |
Поиск в теме | Версия для печати |
Artem |
Отправлено: 27 Марта, 2013 - 15:22:59
|
Главнокомандующий
Сообщений всего: 347
Дата рег-ции: Май 2012
|
Здравствуйте
Осваиваю программирование микроконтроллеров, в данный момент разбираюсь с внешними прерываниями. Значит, подключил 2 кнопки, мигаю светодиодами, всё замечательно, но никак не получается реализовать вот этот код:
CODE:#define F_CPU 1000000UL // указываем частоту в герцах
#include <avr/io.h> // подключаем библиотеку АВР
#include <util/delay.h> // подключаем библиотеку задержек
#include <avr/interrupt.h> // подключаем библиотеку прерываний
#define nop() {asm("nop");}
int s = 50000; // переменная для задержки
unsigned int x;
void delay(int t)
{
for (x=t; x>0 ;x--)
nop ();
}
SIGNAL(SIG_INTERRUPT0)//обработка прерываний INT0
{
cli();//запрещение прерываний на время обработки прерывания
PORTC |=_BV(PC4);
s=s+50000;
_delay_ms(200);
PORTC &=~_BV(PC4);
_delay_ms(200);
sei();//разрешение прерываний
}
SIGNAL(SIG_INTERRUPT1)//обработка прерываний INT1
{
cli();//запрещение прерываний на время обработки прерывания
PORTC |=_BV(PC4);
s=s-50000;
_delay_ms(200);
PORTC &=~_BV(PC4);
_delay_ms(200);
sei();//разрешение прерываний
}
int main(void)
{
DDRC = 0xFF; //все вывод
DDRD = 0x00; //все вход
GICR=0b11000000; //разрешаем прерывание int0 и int1 - кнопка
MCUCR=0b00001010;// int by rising front - для кнопки 1 и 2
sei();//разрешение прерываний
while (1==1)//вечный цикл
{
PORTC |=_BV(PC5);
delay(s);
PORTC &=~_BV(PC5);
delay(s);
}
}
взят он вот отсюда: http://avrlab.com/node/37
вобщем, я убрал светодиодную дорожку и оставил один светодиод, для наглядности, в обработчиках прерываний, помимо изменения переменной мигаю другим светодиодом. так вот в чём проблема: светодиод мигает всегда с одинаковой частотой, не зависимо от того нажимаю я на кнопки или нет, а дожно быть вот как: нажал на кнопку, сработало прерывание, значение переменной s увеличилось на 50000 и светодиод начал мигать реже. При этом, когда я нажимаю на кнопки светодиоды мигают, как описанно в подпрограмме обработчике прерываний. Я не знаю в чём может быть проблема, но наверно она в подпрограмме задержки, я не совсем понимаю, как она работает.
Помогите!!!
заранее спасибо |
|
|
Artem |
Отправлено: 27 Марта, 2013 - 16:27:54
|
Главнокомандующий
Сообщений всего: 347
Дата рег-ции: Май 2012
|
А, понятно, сейчас попробуем, но почему у автора статьи нет никакого квалификатора переменной?
(Добавление)
Да, вы правы, теперь всё заработало как нужно
Но непонятно одно, почему когда я нажимаю на одну кнопку светодиод мигает всё чаще и чаще( переменная уменьшается) и через некоторое количество нажатий на кнопку светодиод опять начинает мигать с прежней частотой, переменная как бы уменьшается, уменьшается, а затем опять возвращается в первоначальное значение, почему это происходит? |
|
|
Artem |
Отправлено: 27 Марта, 2013 - 16:45:53
|
Главнокомандующий
Сообщений всего: 347
Дата рег-ции: Май 2012
|
killgur пишет:А откуда взялось такое значение 50000!?
число взялось экспериментальным путём, потому что при таком числе повторений программы задержки мигание светодиода становяться различимы.killgur пишет:что то включать выключать в прерывании верный способ словить неприятностей.
да, я уже понял, уже убрал включение и выключение светодиода из обработчика прерываний.
killgur пишет:Эта программа созданна каким то генератором кода?
нет, программа в этом виде написана мной, а вот шаблон взят из ссылки, которую я привёл. |
|
|
killgur |
Отправлено: 27 Марта, 2013 - 16:47:18
|
Гуру
Сообщений всего: 1189
Дата рег-ции: Февр. 2010
|
Artem пишет:А, понятно, сейчас попробуем, но почему у автора статьи нет никакого квалификатора переменной?
(Добавление)
Да, вы правы, теперь всё заработало как нужно
Но непонятно одно, почему когда я нажимаю на одну кнопку светодиод мигает всё чаще и чаще( переменная уменьшается) и через некоторое количество нажатий на кнопку светодиод опять начинает мигать с прежней частотой, переменная как бы уменьшается, уменьшается, а затем опять возвращается в первоначальное значение, почему это происходит?
Потому как при очередном сложении значение обнулилось т.к. превысило размерность используемого для подсчетов регистра. (или превысило размерность использованного типа данных)
Надо контроль ввести если значение больше предельного то не прибавлять. |
|
|
killgur |
Отправлено: 27 Марта, 2013 - 16:59:50
|
Гуру
Сообщений всего: 1189
Дата рег-ции: Февр. 2010
|
Artem пишет:killgur пишет:Потому как при очередном сложении значение обнулилось т.к. превысило размерность используемого для подсчетов регистра. (или превысило размерность использованного типа данных)
Надо контроль ввести если значение больше предельного то не прибавлять.
Понятно, значит нужно поменьше значение переменной, а нельзя, в функции задержки, вместо "нет операции" поставить просто задержку _delay_ms(100);-это ничего не измени? зато можно будет уменьшить количество повторений, а следовательно и значение переменной s.
наверно даже нужно так сделать. и прибавлять не 50000 а 1 ))
автор исходного кода того же мнения
http://avrlab.com/delay-routine(Отредактировано автором: 27 Марта, 2013 - 17:05:11) |
|
|
killgur |
Отправлено: 28 Марта, 2013 - 14:46:54
|
Гуру
Сообщений всего: 1189
Дата рег-ции: Февр. 2010
|
Artem пишет:killgur пишет:Atmega 64 -6 векторов
6 векторов-это внешние прерывания, или все вместе?
Потому что если считать все, то и в ATmega8 шесть штук наберётся
ну даташит посмотрите, сколько ног INT
Можно еще использовать групповые прерывания их даже в attiny2313 7 штук
http://rln.nnov.ru/index.php?ind=reviews&op=entry_view&iden=224(Отредактировано автором: 28 Марта, 2013 - 15:03:32) |
|
|
|
Поиск в теме | Версия для печати |
Страниц (2): [1] 2 » |
« Программирование микроконтроллеров » |
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
|
|
|
|
|