Страница 8 из 26
Re: Помогите опросить кнопку
Добавлено: Чт дек 12, 2013 10:03:44
service47
Получается и так и есть в протеусе, что при нажатии кнопки и не отпускании происходит прерывание по спадающему фронту (т.е. получается теоретически лог.0), порт настроен на вход DDRD=0x00; с подтягивающими резисторами PORTD=0xff; (которые если отключить то прерывание не будет работать) бит PUD в регистре MCUCR отключен, прерывания разрешены и глобально разрешены.
Пишу в обработчике прерываний:
Код: Выделить всё
ISR(INT1_vect) //MINUS PIND3
{_delay_ms(200);
if (PIND3 == 0)
{s--;}
}
и в протеусе нет реакции на нажатие кнопки, т.е. на входе порта нет лог.0. но если прописать if (PIND3 == 3) то прерывание работает, да и это же условие выполняется если кнопка не нажата.
С другой стороны в коде Alex'a прописаны:
Код: Выделить всё
#define ACT_BUTT_LEV 0 // Активный уровень нажатых кнопок
т.е. мне туда прописывать эту тройку, но тогда дальше:
Код: Выделить всё
if((mButt_1.cur==ACT_BUTT_LEV) && (mButt_1.prev!=ACT_BUTT_LEV)) // Если текущее значение - "нажата" и предыдущее - "не нажата"
не будет работать из-за этой тройки, срабатывающей всегда.
Задача стоит такая сделать отслеживание кнопок от таймера:
При нажатии любой кнопки происходит увеличение или уменьшении значения на индикаторе на 1 (это работает, но не на таймере, а на векторах прерываний),
При нажатии и удержании в течении 3сек. происходит запуск обратного отсчета (работает если отслеживать циклом while флаги в регистре EIFR).
Re: Помогите опросить кнопку
Добавлено: Чт дек 12, 2013 10:33:16
Аlex
но если прописать if (PIND3 == 3) то прерывание работает, да и это же условие выполняется если кнопка не нажата
А Вас не смущает, что Вы пин (т.б. 1 бит) сравниваете с числом 3 ?

Re: Помогите опросить кнопку
Добавлено: Чт дек 12, 2013 10:55:04
service47
Новая концепция: записывать чтобы-там ни было на входе порта в переменную и работать уже с ней:
Только такое условие работает с каждой кнопкой по отдельности, а вместе они почему то конфликтуют.
Код: Выделить всё
int Knopka_Staroe, Knopka_Novoe;
int Knopka_Star2, Knopka_Nov2;
Knopka_Staroe = (PIND&=(1<<3)); // Записываем старое состояние кнопки в переменную Knopka_Staroe.
if (Knopka_Staroe) // Если Knopka_Staroe равно 1 (кнопка не нажата), то...
{
_delay_ms(80); // Пауза для подавления дребезга контактов.
Knopka_Novoe = (PIND&=(1<<3)); //...считываем новое состояние кнопки.
if (!Knopka_Novoe) // Новое состояние кнопки должно быть равно 0 (нажата).
{ // В этом случае падающий фронт сформирован и можно инвертировать пины.
_delay_ms(80); // Пауза для подавления дребезга контактов.
s--;
}
}
// Knopka_Star2 = (PIND&=(1<<2)); // Записываем старое состояние кнопки в переменную Knopka_Staroe.
// if (Knopka_Star2) // Если Knopka_Staroe равно 1 (кнопка не нажата), то...
// {
// _delay_ms(80); // Пауза для подавления дребезга контактов.
// Knopka_Nov2 = (PIND&=(1<<2)); //...считываем новое состояние кнопки.
//
// if (!Knopka_Nov2) // Новое состояние кнопки должно быть равно 0 (нажата).
// { // В этом случае падающий фронт сформирован и можно инвертировать пины.
// _delay_ms(80); // Пауза для подавления дребезга контактов.
// s++;
// }
// }
Re: Помогите опросить кнопку
Добавлено: Чт дек 12, 2013 11:14:40
a_skr
Аlex писал(а):но если прописать if (PIND3 == 3) то прерывание работает, да и это же условие выполняется если кнопка не нажата
А Вас не смущает, что Вы пин (т.б. 1 бит) сравниваете с числом 3 ?


А если учесть, что PIND3 является просто числом 3...
#define PIND3 3
Re: Помогите опросить кнопку
Добавлено: Чт дек 12, 2013 12:04:27
zero648
Вот что прописано в файле m88def.inc:
да и вообще если прерывание наступило, зачем тогда в прерывании проверять кнопку, если и так понятно, что она нажата, можно смело выходить из прерывания, и уже в основном цикле проверять это нажатие еще несколько раз на антидребезг, отвыкайте от паузного антидребезга и забудьте слово пауза, есть другое слово - игнор.
Re: Помогите опросить кнопку
Добавлено: Чт дек 12, 2013 12:49:36
Аlex
a_skr писал(а):
А если учесть, что PIND3 является просто числом 3...
#define PIND3 3
В таком случае, я - балерина
Это как же нужно себя не уважать, чтобы делать такие объявления ?

Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 08:19:25
Alexeyslav
Это определение бита а НЕ ПОРТА, все правильно. PIND3 - константа, которую НАДО подставлять в сравнение вроде PORTD = (1<<PIND3). На этой концепции построено все.
PINB3=PINC3=PIND3=3 ведь все эти биты портов 3-и по счету!!! Разница в имени константы, указывающая на порт всего лишь для удобства.
Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 10:31:24
service47
Тут:
http://www.fanatnauki.ru/index.php?opti ... &Itemid=64
пишут, что:
PORTD = 0b10000000; // Подключаем подтягивающий PULL-UP резистор к 7 пину порта D.
DDRD = 0b00000000; // Настроим порт D на ввод информации.
// Важна последовательность! Сперва подключаем PULL-UP резистор,
// и только потом настраиваем порт на ввод, иначе кнопка работать не будет.
даже это не помогло.
Вобщем в связи с новой концепцией посмотрите код вначале цикла while(1), почему конфликтуют обе кнопки, но ведь если по отдельности то работают. Второй блок кнопки закомментирован, прерывания отключены:
Спойлер
Код: Выделить всё
#define F_CPU 1000000UL
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#define COUNTDOWN 1
volatile char FLAG = 0;
volatile char s = 6; //Переменная цифры
volatile char a = 6;
volatile char b = 1; //Начальный сброс флага
volatile char c = 6;
volatile char j = 6; //Перескок через ШИМ
// массив знаков на индикатор
char digits[11] = {0b00111111, 0b00000110, 0b00011011, 0b00001111, 0b00100110, 0b00101101, 0b00111101, 0b00000111, 0b00111111, 0b00101111, 0b00101111}; // PORTC 0,1,2,3,4,5,6,7,8,9,x
char digita[11] = {0b00000000, 0b00000000, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000000, 0b00000001, 0b00000001, 0b00000001}; // PORTB
/******************************************************************/
#define ACT_BUTT_LEV 0 // Активный уровень нажатых кнопок
#define ACT_BUTT_LEV_2 0
//---------------------
#define PORT_BUTT_1 PIND // Порт кнопки №1
#define PIN_BUTT_1 2 // Номер бита порта кнопки №1
#define PORT_BUTT_2 PIND // Порт кнопки №2
#define PIN_BUTT_2 3 // Номер бита порта кнопки №2
//---------------------
#define PORT_LED_1 PORTB // Светики
#define DDR_LED_1 DDRB //
#define PIN_LED_1 2 //
#define PORT_LED_2 PORTB //
#define DDR_LED_2 DDRB //
#define PIN_LED_2 7 //
/******************************************************************/
int Knopka_Staroe, Knopka_Novoe;
int Knopka_Star2, Knopka_Nov2;
/******************************************************************/
typedef struct{
unsigned cur: 1; // Текущее состояние
unsigned prev: 1; // Предыдущее состояние
unsigned down: 1; // Была нажата
unsigned up: 1; // Была отжата
}tButt;
volatile tButt mButt_1 = {0,!ACT_BUTT_LEV,0,0}; // Объявляем структуру mButt_1 для нашей кнопки и иним её.
typedef struct{
unsigned cur: 1; // Текущее состояние
unsigned prev: 1; // Предыдущее состояние
unsigned down: 1; // Была нажата
unsigned up: 1; // Была отжата
}tButt2;
volatile tButt2 mButt_2 = {0,!ACT_BUTT_LEV_2,0,0}; // Объявляем структуру mButt_2 для нашей кнопки и иним её.
/******************************************************************/
/******************************************************************/
ISR (TIMER1_OVF_vect) { s=3; //interrupt [TIM1_OVF] void timer1_ovf_isr(void){ //TIMER1_OVF_vect_num
static unsigned char cnt_ms_butt=20; // Счётчик для формирования периода в 20 мс.
TCNT1 -= 4000; // Перезапускаем таймер на 1 мс.
//----------------------//
if(!--cnt_ms_butt){ // Формируем 20-ти миллисек. периоды
cnt_ms_butt=20;
mButt_1.cur = (PORT_BUTT_1&(1<<PIN_BUTT_1))!=0; // Считываем текущее значение вывода.
// Дальше работаем с этим битом, т.к. порт может измениться в любой момент.
if((mButt_1.cur==ACT_BUTT_LEV) && (mButt_1.prev!=ACT_BUTT_LEV)) // Если текущее значение - "нажата" и предыдущее - "не нажата"
mButt_1.down = 1; // Устанавливаем флаг down
if((mButt_1.cur!=ACT_BUTT_LEV) && (mButt_1.prev==ACT_BUTT_LEV)) // Если текущее значение - "не нажата" и предыдущее - "нажата"
mButt_1.up = 1; // Устанавливаем флаг up
mButt_1.prev=mButt_1.cur; // Сохраняем текущее значение. Оно для следующего входа будет предыдущим
mButt_2.cur = (PORT_BUTT_2&(1<<PIN_BUTT_2))!=0; // Считываем текущее значение вывода.
if((mButt_2.cur==ACT_BUTT_LEV_2) && (mButt_2.prev!=ACT_BUTT_LEV_2)) // Если текущее значение - "нажата" и предыдущее - "не нажата"
mButt_2.down = 1; // Устанавливаем флаг down
if((mButt_2.cur!=ACT_BUTT_LEV_2) && (mButt_2.prev==ACT_BUTT_LEV_2)) // Если текущее значение - "не нажата" и предыдущее - "нажата"
mButt_2.up = 1; // Устанавливаем флаг up
mButt_2.prev=mButt_2.cur;
}
//----------------------//
}
/******************************************************************/
ISR(INT1_vect) //MINUS PIND3
{_delay_ms(200);
if (PIND3 == 0) //(PIND3 <= 3) работает (PIND3 <= 2,95) (PIND3 == 3)
{s--;}
}
ISR(INT0_vect) //PLUS PIND2
{_delay_ms(200);
if (PIND2 == 0) //(PIND2 == 2)(PIND2 >= 2,995) работает, а если (PIND2 >= 3) то не работает
{s++;}
}
void shim_start()
{
if (j==6)
{goto jstop;
}
// ASSR=0x00;
// // Установим биты COM1A1-COM1A0:0b10,означает сброс вывода канала A при сравнении Clear OC1A/OC1B on Compare Match, set OC1A/OC1B at BOTTOM (non-inverting mode), for Fast PWM. page135
// TCCR1A |= (1 << COM1A1)|(0 << COM1A0)|(0 << WGM11)|(1 << WGM10);
// // Установим биты WGM13-10:0b0101, согласно таблице это будет режим - Fast PWM, 8-bit, где верхний предел счета задается битом ICR1. page136
// TCCR1B |= (0 << WGM13)|(1 << WGM12)|(1 << CS12)|(0 << CS11)|(0 << CS10);
// // Битами CS12-10:0b100 задаем источник тактового сигнала для таймера МК, clkI/O/256 (From prescaler)=31250Hz. page137
// TCNT1 = 0x00; // начальная установка счетчика
// TIMSK1=0x00;
// ICR1 = 0x20; // задаем период ШИМ, здесь у нас число 255,
// // по формуле fPWM=fclk_I/O/N*(1+ICR1) вычисляем частоту ШИМ, она будет равна 8MHz/256(1+2)=10416Hz
// // для FR3706 надо 50000Hz, irlm0030 надо 16666Hz<
// OCR1A = 0x50; // начальный коэффициент заполнения ШИМ 0xC8=200, 0x50=1/3
jstop:
j=0;
}
int main(void)
{
DDRC=0x3f; //0b00111111 0-ввод 1-вывод
PORTC=0x00; //
PORTD=0xff; // 0b11111111 PORTD=0xff;
DDRD=0x00; //0b00001100 DDRD=0x0C;
DDRB=0xFF; //0b11000111 PB1(OC1A)-ШИМ DDRB=0xC7;
PORTB=0x00; //PORTB=0x00;
EICRA = (1<<ISC11) | (0<<ISC10) | (1<<ISC01) | (0<<ISC00); // настройка срабатывания прерываний The falling edge of INT1 generates an interrupt request
PCICR |= (1<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);// разрешение прерываний PCINT23...16
PCMSK2=0b11000000; //разрешаем прерывание pcint23 pcint22
EIMSK=0b00000000; //разрешаем прерывание int0 и int1 - кнопка EIMSK=0b11000011;
//MCUCR=0b00001111;// IVSEL, IVCE
sei(); //Глобальное разрешение прерываний
//Установка таймера0
//TCCR0A |= (0 << COM1A1)|(0 << COM1A0)|(1 << WGM01)|(0 << WGM00); //биты COM Normal port operation, OC0A disconnected, WGM T/C in CTC mode
//TCCR0B |= (0 << WGM02)|(0 << CS02)|(0 << CS01)|(1 << CS00); //биты CS fclk_I/O/1
//TCNT0=0x00;
//OCR0A=0x80;
//----------------------//
//TCCR0A=0x00; //TCCR0=0x00;
// TCCR0B=0x01; //TCCR0=0x00;
// TCNT0=0x00;
// Timer/Counter 1 initialization
TCCR1A=0x00; //для Compare Output Mode, non-PWM COM1A1/COM1B1=0 COM1A0/COM1B0=0 Normal port operation, OC1A/OC1B disconnected.
TCCR1B=0x01; //Waveform Generation Mode Bit Description WGM10-13=0 Normal //CS12-10=001 No prescaling
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
//OCR1AH=0x00;
//OCR1AL=0x00;
OCR1BH=0x00; //OCR1B compared with the counter value (TCNT1)
OCR1BL=0x00;
// Timer/Counter 2 initialization
//ASSR=0x00;
//TCCR2=0x00; //TCCR2=0x00;
//TCNT2=0x00;
//OCR2=0x00; //OCR2=0x00;
MCUCR=0x00;
//TIMSK0=0x04; //TIMSK=0x04;
// TIMSK1=0x04; //TIMSK=0x04; //OCIE1B=1
//ACSR=0x80;
//SFIOR=0x00;
//----------------------//
while(1)
{
Knopka_Staroe = (PIND&=(1<<3)); // Записываем старое состояние кнопки в переменную Knopka_Staroe.
if (Knopka_Staroe) // Если Knopka_Staroe равно 1 (кнопка не нажата), то...
{
//_delay_ms(80); // Пауза для подавления дребезга контактов.
Knopka_Novoe = (PIND&=(1<<3)); //...считываем новое состояние кнопки.
if (!Knopka_Novoe) // Новое состояние кнопки должно быть равно 0 (нажата).
{ // В этом случае падающий фронт сформирован и можно инвертировать пины.
//_delay_ms(80); // Пауза для подавления дребезга контактов.
s--;
}
}
// Knopka_Star2 = (PIND&=(1<<2)); // Записываем старое состояние кнопки в переменную Knopka_Staroe.
// if (Knopka_Star2) // Если Knopka_Staroe равно 1 (кнопка не нажата), то...
// {
// //_delay_ms(80); // Пауза для подавления дребезга контактов.
// Knopka_Nov2 = (PIND&=(1<<2)); //...считываем новое состояние кнопки.
//
// if (!Knopka_Nov2) // Новое состояние кнопки должно быть равно 0 (нажата).
// { // В этом случае падающий фронт сформирован и можно инвертировать пины.
// //_delay_ms(80); // Пауза для подавления дребезга контактов.
// s++;
// }
// }
//if (PIND3 == 3) //(PIND3 == 3) работает если кнопка не нажата
//{s=8;}
//if (PIND2 == 2) //(PIND2 == 2) работает если кнопка не нажата
//{s=8;}
//----------------------//
if(mButt_1.up){ // Если кнопка была нажата -> отжата
mButt_1.up=0; // Сбрасываем флаг
PORT_LED_1 ^=(1<<PIN_LED_1); // Инвертируем светодиод №1
s++;
}
//----------------------//
if(mButt_1.down){ // Если кнопка была отжата -> нажата
mButt_1.down=0; // Сбрасываем флаг
PORT_LED_2 ^=(1<<PIN_LED_2); // Инвертируем светодиод №2
s++;
}
//----------------------//
//----------------------//
if(mButt_2.up){ // Если кнопка была нажата -> отжата
mButt_2.up=0; // Сбрасываем флаг
PORT_LED_1 ^=(1<<PIN_LED_1); // Инвертируем светодиод №1
s--;
}
//----------------------//
if(mButt_2.down){ // Если кнопка была отжата -> нажата
mButt_2.down=0; // Сбрасываем флаг
PORT_LED_2 ^=(1<<PIN_LED_2); // Инвертируем светодиод №2
s--;
}
//----------------------//
start:
if (b == 1)
{s=5;
FLAG &= ~ COUNTDOWN;
b++;
}
if (s > 9)
s--;
else if (s == 0)
s++;
if (FLAG == COUNTDOWN)
{
//cli();
char i = 0;
while (s > -1)
{
if (s > -1)
{
a = 5;
c = 5;
if (FLAG != COUNTDOWN)
{
goto start;
}
PORTB |= _BV(PB6); // чтобы мигала точка на индикаторе
_delay_ms(250);
PORTB &= ~_BV(PB6);
_delay_ms(250);
}
PORTC = digits[s];
PORTB = digita[s];
_delay_ms(500);
PORTB &= ~_BV(PB7); //Красный светодиод
_delay_ms(500);
PORTB |= _BV(PB7);
s--;
if (s == 0)
{
PORTC = digits[s];
PORTB = digita[s];
j=0;
shim_start();
PORTB &= ~_BV(PB2); //Зеленый светодиод
_delay_ms(250);
PORTB |= _BV(PB2);
_delay_ms(250);
}
i++;
if (i>=10)
{ICR1 = 0x00;
OCR1A = 0x00;}
}
sei();
FLAG &= ~ COUNTDOWN;
}
PORTC = digits[s];
PORTB = digita[s];
}
}
Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 10:57:15
a_skr
// Важна последовательность! Сперва подключаем PULL-UP резистор,
// и только потом настраиваем порт на ввод, иначе кнопка работать не будет.
Чушь несусветная. И "настраивать на ввод" необязательно. Там по включению итак нули.
Knopka_Staroe = (PIND&=(1<<3)); // Записываем старое состояние кнопки в переменную Knopka_Staroe.
Зачем там &= ?
Где _BV(), где (1<<PBx), где (1<<3). Опишите задачу. Составьте алгоритм. Очень сложно читать код.
Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 11:40:26
service47
a_skr писал(а):Knopka_Staroe = (PIND&=(1<<3)); // Записываем старое состояние кнопки в переменную Knopka_Staroe.
Зачем там &= ?
Где _BV(), где (1<<PBx), где (1<<3). Опишите задачу. Составьте алгоритм. Очень сложно читать код.
Как я понимаю (PIND&
=(1<<3)) это чтение состояния третьего пина порта, в любом случае что-бы это ни-было функция в протеусе действительно считывает замыкание кнопки на землю и реагирует на это.
Задача уже писал, вот она:
При нажатии любой кнопки происходит увеличение или уменьшении значения на индикаторе на 1 (это работает, но не на таймере, а на векторах прерываний),
При нажатии и удержании обоих клавиш в течении 3сек. происходит запуск обратного отсчета (работает если отслеживать циклом while флаги в регистре EIFR).
Алгоритм:
1. Опрос кнопок
2. Замкнута 1якнопка goto3 else goto4
3. Увеличить значение на 1
4. Замкнута 2якнопка goto5 else goto6
5. Уменьшить значение на 1
6. Замкнуты обе кнопки и удерживаются в течении 3сек. goto7 else goto1
7. Запуск обратного отсчета
Остальной код работает. Постараюсь выкладывать код покомпактнее.
Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 12:02:43
a_skr
Как я понимаю (PIND&=(1<<3)) это чтение состояния третьего пина порта
Это не так. a = (PIND&=(1<<3)); соответствует следующему коду:
Код: Выделить всё
PIND = PIND & (1<<3); // - не имеет смысла, т.к. регистр PIND только на чтение
a = PIND; // - в "a" попадут все биты PIND
Правильные варианты:
Код: Выделить всё
a = PIND & (1<<3); // - в "a" будет или ноль или 8
a = PIND & (1<<3) ? 1 : 0; // - в "a" будет или ноль или 1
a = (PIND>>3) & 1; // - тоже самое, займет меньше кода
Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 13:08:44
Аlex
Alexeyslav писал(а):Это определение бита а НЕ ПОРТА, все правильно. PIND3 - константа, которую НАДО подставлять в сравнение вроде PORTD = (1<<PIND3)
Интересно, если это константа, зачем тогда в имени буква "D" ? Она (эта константа) как то привязана конкретно к этому порту ?
Глупое, на мой взгляд, имя для объявления константы-номера бита, малоинформативное. Я, например, увидев её, даже и не понял, что под ней может скрываться цифра 3. На первый взгляд, PIND3 - Это 3-ий пин порта D.
Где логика ....

Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 13:32:58
a_skr
Чисто гипотетически, вдруг выйдет контроллер, в котором какая-нибудь ножка PD8 будет адресоваться через бит 0 в регистре PINDH, и тогда логично объявить константы PIND8 и PD8, равные нулю...

а в порту C не будет ножки PC8, тогда константы PINC8 не будет и компилятор даст ошибку при ее использовании.
PS. ну есть же контроллеры, в которых только порт B, например и не все 8 бит задействованы...
Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 13:35:53
service47
В таком коде срабатывает первое if когда кнопка не нажата, а при нажатии кнопки, т.е. замыкании ее на землю второй if не срабатывает.
Код: Выделить всё
Knopka_Staroe = PIND3; // Записываем старое состояние кнопки в переменную Knopka_Staroe.
if (Knopka_Staroe) // Если Knopka_Staroe равно 1 (кнопка не нажата), то...
{
_delay_ms(80); // Пауза для подавления дребезга контактов.
Knopka_Novoe = PIND3; //...считываем новое состояние кнопки.
if (!Knopka_Novoe) // Новое состояние кнопки должно быть равно 0 (нажата).
{ // В этом случае падающий фронт сформирован и можно инвертировать пины.
_delay_ms(80); // Пауза для подавления дребезга контактов.
s--;
}
}
Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 13:45:18
a_skr
В этом коде вообще НЕТ опроса кнопок. "PIND3" - это просто "3". Выше дал "Правильные варианты" опроса.
Re: Помогите опросить кнопку
Добавлено: Пт дек 13, 2013 13:58:30
service47
a_skr спасибо, заработали обе кнопки, только три раза через раз срабатывают.
Код: Выделить всё
Knopka_Staroe = PIND & (1<<3) ? 1 : 0; // Записываем старое состояние кнопки в переменную Knopka_Staroe.
if (Knopka_Staroe) // Если Knopka_Staroe равно 1 (кнопка не нажата), то...
{
_delay_ms(80); // Пауза для подавления дребезга контактов.
Knopka_Novoe = PIND & (1<<3) ? 1 : 0; //...считываем новое состояние кнопки.
if (!Knopka_Novoe) // Новое состояние кнопки должно быть равно 0 (нажата).
{ // В этом случае падающий фронт сформирован и можно инвертировать пины.
_delay_ms(80); // Пауза для подавления дребезга контактов.
s--;
}
}
Knopka_Star2 = PIND & (1<<2) ? 1 : 0; // Записываем старое состояние кнопки в переменную Knopka_Staroe.
if (Knopka_Star2) // Если Knopka_Staroe равно 1 (кнопка не нажата), то...
{
_delay_ms(80); // Пауза для подавления дребезга контактов.
Knopka_Nov2 = PIND & (1<<2) ? 1 : 0; //...считываем новое состояние кнопки.
if (!Knopka_Nov2) // Новое состояние кнопки должно быть равно 0 (нажата).
{ // В этом случае падающий фронт сформирован и можно инвертировать пины.
_delay_ms(80); // Пауза для подавления дребезга контактов.
s++;
}
}
Re: Помогите опросить кнопку
Добавлено: Пн дек 16, 2013 09:51:00
service47
Данный код в цикле while(1); работает раз через три, как сделать чтобы если нажата одна кнопка срабатывала одна команда, если другая то соответственно другая и стабильно. Прерывания отключены. Может дело в дэлэях, может есть способ их не использовать...
Спойлер
Код: Выделить всё
Knopka_Staroe = PIND & (1<<3) ? 1 : 0;
if (Knopka_Staroe) //кнопка не нажата тогда if=1
{
_delay_ms(20);
Knopka_Novoe = PIND & (1<<3) ? 1 : 0;
Knopka_Nov2 = PIND & (1<<2) ? 1 : 0;
if(!Knopka_Novoe && Knopka_Nov2) //кнопка нажата и кнопка не нажата тогда if=1
{
PORTB |= _BV(PB6); //точка на индикаторе загорается
_delay_ms(100);
s--;
}
PORTB &= ~_BV(PB6); //точка на индикаторе гаснет
}
Knopka_Star2 = PIND & (1<<2) ? 1 : 0;
if (Knopka_Star2)
{
_delay_ms(20);
Knopka_Novoe = PIND & (1<<3) ? 1 : 0;
Knopka_Nov2 = PIND & (1<<2) ? 1 : 0;
if(Knopka_Novoe && !Knopka_Nov2)
{
PORTB |= _BV(PB6); //точка на индикаторе загорается
_delay_ms(100);
s++;
}
PORTB &= ~_BV(PB6); //точка на индикаторе гаснет
}
Re: Помогите опросить кнопку
Добавлено: Вт дек 17, 2013 00:47:04
shads
Ды не изобретай велосипед... вот пару вариантов, глянь, может что подойдет...
http://asis-kbr.ru/forum/viewtopic.php?f=13&t=173
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 03, 2014 14:26:33
Мikа
Добрый день, Коты! Получилась такая тема: остались свободными 2 ножки МК, которые как раз INT0 и INT1. И мне как раз нужно сделать 2 кнопки. И вот я думаю, что легче для программы, подключить библиотеку нажатия кнопок, в которой ловится 0 на ноге, потом заданное количество раз перепроверяется и даёт на выходе разрешение на выполнение кода. Или использовать внешнее прерывание, допустим, по спадающему фронту на ножках?
Re: Помогите опросить кнопку
Добавлено: Пт апр 04, 2014 00:38:40
shads
Подключение через INT0 или INT1 оправдано только если надо выводить устройство из энергосберегающих режимов...
В других случаях лучше периодически (в прерывании) опрашивать линии кнопок.