Например TDA7294

Форум РадиоКот • Просмотр темы - Опрос кнопок микроконтроллером
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Ср апр 24, 2024 21:22:52

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


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 321 ]     ... , , , 7, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Мелкие вопросы по МК и ПЛИС.
СообщениеДобавлено: Чт ноя 28, 2013 09:47:18 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21837
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
...задержки в ISR? :o :o :o
...очень круто...
Дальше можно не смотреть.
:cry:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Мелкие вопросы по МК и ПЛИС.
СообщениеДобавлено: Чт ноя 28, 2013 10:01:06 
Прорезались зубы

Зарегистрирован: Вт мар 12, 2013 16:05:45
Сообщений: 219
Рейтинг сообщения: 0
А каким образом можно реализовать отслеживание удержания 2-х кнопок в течении 2сек. вне обработчика прерывания?
У меня они не реагируют на команду (PIND2 == 0) или единице, пробовал через:
while(EIFR == 0b00000011)
и те же задержки.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Мелкие вопросы по МК и ПЛИС.
СообщениеДобавлено: Чт ноя 28, 2013 10:17:14 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21837
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
1. Кнопки не относятся к устройствам реального времени.
2. Кнопки анализируются циклическим ОПРОСОМ.
3. Цикл можно задавать прерыванием от таймера.
4. Циклический опрос одновременно защищает от дребезга, если интервал опроса больше времени дребезга.
Далее думайте. Когда появятся СВОИ идеи - продолжим...


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Чт ноя 28, 2013 10:25:45 
Прорезались зубы

Зарегистрирован: Вт мар 12, 2013 16:05:45
Сообщений: 219
Рейтинг сообщения: 0
Пункт 2 непонятен (что опрашивать: пин, флаг прерывания...), у меня кнопки через резистор 10кОм соединены с питанием, а другим выводом на землю и при замыкании кнопки на пине д.б. 0, пробую в программе, но код не работает.


Вернуться наверх
 
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Чт ноя 28, 2013 10:27:09 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
прочтите эту тему и все встанет на свои места.

_________________
Ставим плюсы: )


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Чт ноя 28, 2013 10:29:45 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21837
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
Причем тут прерывания?
Опрашивается КНОПКА. То есть ПИН.
А опрашивается он с интервалом прерываний от таймера.
Состояние обеих кнопок фиксируется в специальном регистре, который называется машиной состояний.
Анализ машины состояний и есть путь для решения Вашей задачи.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Чт ноя 28, 2013 10:51:03 
Прорезались зубы

Зарегистрирован: Вт мар 12, 2013 16:05:45
Сообщений: 219
Рейтинг сообщения: 0
Если под машиной состояний имеется ввиду флаг прерываний, устанавливаемый в единицу, когда происходит прерывание регистр EIFR биты INTF0 и INTF1:
опрос while(EIFR == 0b00000011)
то тут получается трудно нажать идеально одновременно обе кнопки чтобы запустился алгоритм, видимо придется опрашивать от прерывания таймера эти биты.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Чт ноя 28, 2013 10:55:10 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4510
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Цитата:
видимо придется опрашивать от прерывания таймера эти биты.
Не "видимо придётся", а так и нужно делать.
Где то в районе 4-ой страницы я выкладывал пример обработки кнопок. А на предыдущей странице есть посты, где человек запустил длинные нажатия. Почитайте темку, не ленитесь...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Чт ноя 28, 2013 11:09:04 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21837
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
service47 писал(а):
Если под машиной состояний имеется ввиду флаг прерываний, устанавливаемый в единицу, когда происходит прерывание регистр EIFR биты INTF0 и INTF1:
опрос while(EIFR == 0b00000011)
то тут получается трудно нажать идеально одновременно обе кнопки чтобы запустился алгоритм, видимо придется опрашивать от прерывания таймера эти биты.

У Вас дислексия? :cry: :facepalm:
Я РУССКИМ языком написал: ЗАБУДЬТЕ О ПРЕРЫВАНИЯХ ОТ КНОПОК.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Вт дек 10, 2013 10:54:41 
Прорезались зубы

Зарегистрирован: Вт мар 12, 2013 16:05:45
Сообщений: 219
Рейтинг сообщения: 0
Пытаюсь настроить таймер1 для опроса кнопок, но при компиляции выдает ошибку:
Код:
interrupt [TIM1_OVF] void timer1_ovf_isr(void){
//...
}

Error 1 'TIM1_OVF' undeclared here (not in a function)

Даташит на ATmega88PA: http://www.atmel.com/images/doc2545.pdf
В даташите написано на стр.59, что есть прерывания:
TIMER1 OVF и приводиться код на асме:
0x00D rjmp TIM1_OVF ; Timer1 Overflow Handler
а AtmelStudio6 предлагает вместо TIM1_OVF ввести:
timer1_ovf_isr()
TIMER1_OVF_vect
TIMER1_OVF_vect_num
а там уже другие ошибки выскакивают.

Подключены:
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>

Погуглил, тут вроде есть решение, но мне оно непонятно:
http://www.avrfreaks.net/index.php?name ... 04&start=0

Ввожу:
interrupt [TIMER1_OVF_vect] void timer1_ovf_isr(void){... }
и ошибка: Error 1 '__vector_13' undeclared here (not in a function)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Кнопки не работают от 0 и 1цы
СообщениеДобавлено: Ср дек 11, 2013 11:53:32 
Прорезались зубы

Зарегистрирован: Вт мар 12, 2013 16:05:45
Сообщений: 219
Рейтинг сообщения: 0
Ситуация интересная: если кнопка нажата и замыкается на землю, то на входе порта д.б. ноль, пробовал писать в коде ноль не работает, стал методом тыка подбирать другие значения и вот результат:

Код:
ISR(INT1_vect)  //MINUS PIND3
{_delay_ms(200);
if (PIND3 <= 2,9) //(PIND3 <= 3) работает (PIND3 <= 2,95)
      {s--;}
}

ISR(INT0_vect)  //PLUS PIND2
{_delay_ms(200);
if (PIND2 >= 3) //(PIND2 >= 2,995) работает, а если (PIND2 >= 3) то не работает
      {s++;}
}

      DDRD=0x0C; //0b00001100
      PORTD=0xff; // 0b11111111


Нужно выявить то значение константы, которое можно применять в программе, а не диапазон значений, а еще лучше сделать, чтобы было либо 0, либо 1.

Схема (кнопки S4, S5):
Изображение

В архиве схема протеуса (в которой если подгрузить прошивку .НЕХ можно погонять значения на индикаторе), прошивка, исходник для AtmelStudio6 и принципиальная схема: http://rghost.ru/50883666

Даташит на ATmega88PA: http://www.atmel.com/images/doc2545.pdf

PS: на дэлэй в обработчике внимания не обращать.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 12:57:02 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21837
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
Есть старый анекдот про прапорщика: "Х-ли думать, трясти надо!"...
Увы, Ваша маниакальная "привязанность" к кнопкам на прерываниях неизлечима....
:cry:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 13:33:34 
Прорезались зубы

Зарегистрирован: Вт мар 12, 2013 16:05:45
Сообщений: 219
Рейтинг сообщения: 0
Как раз наоборот пытаюсь сделать опрос кнопок по шаблону от Alex'a (все в архиве), а в обработчики прерывания полез чтобы в протеусе тестировать значение на портах при которых кнопка замкнута и т.д. т.к. в голове не укладывается как так может быть, что у кнопки может быть состояние отличное от логических нулей и единиц...

Спойлер
Код:
#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       //
/******************************************************************/

/******************************************************************/
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 >= 2) //(PIND3 <= 3) работает (PIND3 <= 2,95)
      {s--;}
}

ISR(INT0_vect)  //PLUS PIND2
{_delay_ms(200);
if (PIND2 >= 2,995) //(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; //
      DDRD=0x0C; //0b00001100
      PORTD=0xff; // 0b11111111
      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=0b11000011; //разрешаем прерывание int0 и int1 - кнопка
   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)
    {
      //----------//
      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: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 14:37:18 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 74
Зарегистрирован: Пн июн 18, 2012 12:01:04
Сообщений: 650
Откуда: Челябинская область, Копейск
Рейтинг сообщения: 0
Код:
      DDRD=0x0C; //0b00001100
      PORTD=0xff; // 0b11111111

А че пины для кнопок проинициализированы на выход??


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 14:50:36 
Прорезались зубы

Зарегистрирован: Вт мар 12, 2013 16:05:45
Сообщений: 219
Рейтинг сообщения: 0
Делал на основе этой статьи:
http://easyelectronics.ru/avr-uchebnyj- ... yvoda.html

DDRD=0x0C; //0b00001100 единичные биты это те две кнопки PIND2 и PIND3, поставил нули реакции нет (но еще повожусь с этими нулями, чтоб наверняка знать)...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 14:55:01 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4510
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
service47 писал(а):
поставил нули реакции нет
Какой кошмар :facepalm:
Прежде чем что-то делать, нужно хорошо понимать что ты делаешь. А с таким методом тыка можно дотыкаться до убийства портов МК (как минимум)...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 15:25:29 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 234
Зарегистрирован: Пт янв 29, 2010 10:27:40
Сообщений: 3851
Откуда: Москва
Рейтинг сообщения: 0
service47 писал(а):
DDRD=0x0C; //0b00001100 единичные биты это те две кнопки PIND2 и PIND3

Надеюсь вы эти кнопочки на настоящем контроллере не нажимали, иначе у меня для вас плохие новости...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 15:32:06 
Прорезались зубы

Зарегистрирован: Вт мар 12, 2013 16:05:45
Сообщений: 219
Рейтинг сообщения: 0
Вобщем так:
1. Таймер1В отключен и прерывание тоже по переполнению. Запуск ШИМ откл.
2. Включены прерывания INT0 и INT1 с условиями для проверки значений нажатой кнопки.
3. При старте программы прописаны условия if чтобы проверить состояние отжатой кнопки методом подбора значении (если совпадет, то на индикаторе будет цифра 8 ).

Кнопки соответственно уменьшают и увеличивают значение на индикаторе на 1.
Как только значения проясняться или все сведется к лог.0 и 1, то будет включен модуль написанный Alex'ом, там уже другие заморочки.

Спойлер
Код:
#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       //
/******************************************************************/

/******************************************************************/
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 == 3) //(PIND3 <= 3) работает (PIND3 <= 2,95) (PIND3 == 3)
      {s--;}
}

ISR(INT0_vect)  //PLUS PIND2
{_delay_ms(200);
if (PIND2 == 2) //(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; //
      DDRD=0x00; //0b00001100 DDRD=0x0C;
      PORTD=0xff; // 0b11111111 PORTD=0xff;
      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=0b11000011; //разрешаем прерывание int0 и int1 - кнопка
   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)
    {      
      //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];

    }
}


2 Engineer_Keen
Нажимал в протеусе и на плате, но все работало с прошлой допотопной версией программы.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 15:51:29 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 234
Зарегистрирован: Пт янв 29, 2010 10:27:40
Сообщений: 3851
Откуда: Москва
Рейтинг сообщения: 0
service47 писал(а):
Нажимал в протеусе и на плате, но все работало с прошлой допотопной версией программы.

Работать оно может, но если записать в DDR и PORT "1", а потом закоротить этот пин на землю, то верхний ключ сгорит (или PORT в "0", а кнопкой соединить с +5В - нижний сдохнет), этот пин больше не сможет работать как выход, только как вход, если повезет. Нельзя соединять напрямую с питанием пины, сконфигурированные как выходы (DDR=1).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Помогите опросить кнопку
СообщениеДобавлено: Ср дек 11, 2013 19:42:33 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 74
Зарегистрирован: Пн июн 18, 2012 12:01:04
Сообщений: 650
Откуда: Челябинская область, Копейск
Рейтинг сообщения: 0
Код:
      DDRD=0x00; //0b00001100 DDRD=0x0C;
      PORTD=0xff; // 0b11111111 PORTD=0xff;
   EICRA  =  (1<<ISC11) | (0<<ISC10) | (1<<ISC01) | (0<<ISC00);   // настройка срабатывания прерываний The falling edge of INT1 generates an interrupt request
   EIMSK=0b00000011; //разрешаем прерывание int0 и int1 - кнопка
   sei(); //Глобальное разрешение прерываний

Этого вполне достаточно, чтобы понять что произошло с кнопками в момент срабатывания прерываний, дальше остается только отфильтровать ложные срабатывания, все остальное относительно кнопок просто мусор.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 321 ]     ... , , , 7, , , ...  

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


Кто сейчас на форуме

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


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

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


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y