Easyelectronics.ru

Электроника для всех
Текущее время: 06 дек 2019, 19:01

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: прерывания
СообщениеДобавлено: 10 дек 2011, 13:55 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Здравствуйте. Решил попробовать сделать внешие прерывания. Вот код.
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

ISR(INT0_vect)
{
if (PIND == PIND&0xFE)
{
PORTA = 0xFF;
_delay_ms(200);
PORTA = 0x00;
}
else
{
PORTA = 0xFF;
}
}
int main(void)
{
PORTD = 0x00;
DDRD = 0x00;
PORTA = 0xFF;
DDRA = 0xFF;
TCCR0 = 0x05;
TCNT0 = 0x00;
ACSR = 0x80;
GICR = 1 << 6;
sei();
while (1)
{
PORTA = 0x00;
}
ну вот тут задача такая. Светодиоды не горят. Как нажимаешь на кнопку, соединенную с выводом INT0 должны гореть светодиоды. Вот. Я не понимаю, в даташите прочитал, что для разрешения внешних прерываний нужно выставить бит 6 в единицу. Что я и сделал. А на деле получается, что у меня программа сразу уходит в обработку прерываний. Светодиоды горят. Что у меня не так?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: прерывания
СообщениеДобавлено: 10 дек 2011, 23:11 
Администратор
Аватара пользователя

Зарегистрирован: 16 янв 2010, 06:09
Сообщения: 6274
Откуда: Челябинск
Ну, начнет с того, что вот это:
PORTD = 0x00;
DDRD = 0x00;
Полная фигня. На что порт настроен? На Hi-Z в условиях подключенной кнопки без подтяжки (а на PB именно они) на входе будет полна фигня. Наводки будут телепать его как попало. Так что смысла нет. Надо DDR в 0, а порт в 1, тогда будет вход с подтяжкой.

TCCR0 = 0x05;
TCNT0 = 0x00;
ACSR = 0x80;
GICR = 1 << 6;

А вот за это надо сразу бить ногами. Отучайтесь писать магическими числами. Ни к чему хорошему это никогда не приводило. Что за бит 6? что за число 05? Что за 0х80? Никто даташит наизусть не знает, где какой бит лежит не помнит и ради вас лезть и выяснять не будет. У каждого бита есть свое символическое имя. Вот его и надо использовать.


if (PIND == PIND&0xFE)

Странный ход. Поясните чего вы хотели им добиться. PIND может быть совершенно левым, наводки и прочая фигня. Так что ждать TRUE резултата сравнения с каким то конкретным числом можно до второго пришествия. Да и зачем проверять кнопку если код в нее и так нее вошел по прерыванию? Опять же, что за 0xFE ?

А что у вас происходит:

Левая наводка дрыгает хаотично порт отвечающий за инт. Он не подтянут, так что легко поддается. Срабатывает прерывание, а в нем идет сравнение с условием которое практически всегда FALSE (ну разве что вам оооочень повезет, а с таким везеньем чего вы тут делаете? Бегом покупать лотерейные билеты!) Соответсвтенно вариант у нас только один остается PORTA = 0xFF;

Опять же вы их же и зажигаете при инициализации.
PORTA = 0xFF;
DDRA = 0xFF;

Так что они будут гореть и вне зависимости от прихода прерывания.

_________________
Хозяин дома


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: прерывания
СообщениеДобавлено: 11 дек 2011, 00:19 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Спасибо, понял ошибки. Буду работать над собой и исправлять. Такого больше не повторится :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: прерывания
СообщениеДобавлено: 11 дек 2011, 00:24 
Администратор
Аватара пользователя

Зарегистрирован: 16 янв 2010, 06:09
Сообщения: 6274
Откуда: Челябинск
И разберитесь с битмасками. В вашем случае, следуя вашей изначальной задумке должно быть так:

if (PIND&0xFE)

все, ничего более не надо. Будет бит 0 в PIND = 1 будет TRUE. Не будет - FALSE

Наоборот, соответственно:
if (~(PIND&0xFE))

_________________
Хозяин дома


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: прерывания
СообщениеДобавлено: 11 дек 2011, 00:25 
Администратор
Аватара пользователя

Зарегистрирован: 16 янв 2010, 06:09
Сообщения: 6274
Откуда: Челябинск
а вообще где то в дебрях WINAVR есть удобные макросы bit_is_set(byte,bit) и bit_is_clear(byte,bit)

_________________
Хозяин дома


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: прерывания
СообщениеДобавлено: 11 дек 2011, 00:40 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Спасибо) Буду разбираться. Я просто хочу попробовать внешние прерывания. А так алгоритм можно и без прерываний реализовать.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB