Уважаемые форумчане, подскажите какой вариант из предложенных наиболее удобный! И желательно бы хотелось услышать как плюсы так и минуса каждой схемы подключения!
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
1) +проще обработка с точки зрения программы +можно обрабатывать любую комбинацию одновременно нажатых кнопок -нужно много ног для подключения -для аппаратного антидребезга нужны RC-цепочки для каждой кнопки 2) +всего одна нога контроллера -немного сложнее обработка кнопок -нажатие более одной кнопки может обработаться как нажатие другой кнопки
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Все правильно сделано, считывается состояние, сейчас собрал проект если кнопка нажата-моргает портом B в протеусе. Если не нажата - не моргает. Возможно просто вы не видите этого в реале так как потому что нет задержки перед выключением порта Попробуйте так проверить, так просто копируется состояние ноги RA2 в порт B Спойлер
Код:
LIST P=PIC16F628A __CONFIG H'3F69'
STATUS EQU H'03' TRISA EQU H'05' PORTA EQU H'05' TRISB EQU H'06' PORTB EQU H'06'
org 0 ; начало программы ; подготовительные моменты bsf STATUS,5 ; переход в Банк 1 movlw b'00011111' movwf TRISA clrf TRISB bcf STATUS,5 ; переход назад в Банк 0 clrf PORTB ; очистка порта ; отслеживание нажатия кнопки m1: btfsc PORTA,2 ; бит-проверка ножки RA2 goto m2 clrf PORTB goto m1 m2 movlw .255 movwf PORTB goto m1 end ; конец программы
Протеуса у меня нет. Попробовал ваш вариант в МК . Глуха как в танке ,а в моем варианте горят все порты В сразу как подашь питания. Может надо ка кто по другому биты конфигурации выставить ?
День добрый, пытаюсь организовать опрос двух кнопок, взял пример из этого сообщения
Аlex писал(а):
Ну чтож, коли пошла такая пьянка, подкину и я своих дровишек в костёрчик ) Раз тут собрались одни АВРщики , пришлось поставить CV и черкнуть на нём примерчик обработки кнопок. CV взял из-за генератора кода, т.к. не хочется лезть в даташит на совершенно незнакомые мне МК. В общем, за им генерируемый код меня не пинать . Остальное, что касается моей писанины - обсуждаем, критикуем, закидываем помидорами, .... В архиве проект + файл всеми любимого протеуса:
Вложение:
butt.rar
Программа хорошо комментирована, так что, думаю, вопросов не возникнет. Если кому будет интересно, могу добавить обработку длинного нажатия.
и переделал под себя, но вот какая загвоздка, все работает если я организовываю опрос либо кнопки 1 либо кнопки 2, но когда пытаюсь сделать так что бы работал опрос 2х кнопок, то почему то программа реагирует только на нажатие кнопки 1, подскажите в чем может быть проблема, что надо исправить что бы была реакция на нажатие обоих кнопок. Код моей программы ниже. Спойлер
#define PORT_BUTT_2 PIND // Порт кнопки №2 #define PIN_BUTT_2 3 // Номер бита порта кнопки №2 //_____ unsigned char str=0b10000000, maska_str; unsigned int stolb=0b0111111111111111, maska_stolb; //_____ typedef struct{ unsigned cur: 1; // Текущее состояние unsigned prev: 1; // Предыдущее состояние unsigned down: 1; // Была нажата unsigned up: 1; // Была отжата }tButt1; volatile tButt1 mButt_1 = {0,!ACT_BUTT_LEV_1,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 для нашей кнопки и иним её. //_____
interrupt [TIM1_OVF] void timer1_ovf_isr(void){ 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_1) && (mButt_1.prev!=ACT_BUTT_LEV_1)) // Если текущее значение - "нажата" и предыдущее - "не нажата" mButt_1.down = 1; // Устанавливаем флаг down if((mButt_1.cur!=ACT_BUTT_LEV_1) && (mButt_1.prev==ACT_BUTT_LEV_1)) // Если текущее значение - "не нажата" и предыдущее - "нажата" mButt_1.up = 1; // Устанавливаем флаг up mButt_1.prev=mButt_1.cur; // Сохраняем текущее значение. Оно для следующего входа будет предыдущим
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; } } /******************************************************************/ //Сдвиг по стобцам void sdvig_stolb (void) { maska_stolb=0x8000;
do { // начало цикла if(stolb & maska_stolb) // если в результате умножения маски и числа получилось ненулевое значение { DATA_STOLB=1; // выводим в порт 1 #asm("nop"); CLK_STOLB=1; #asm("nop"); CLK_STOLB=0; #asm("nop"); } else { DATA_STOLB=0; // иначе 0 #asm("nop"); CLK_STOLB=1; #asm("nop"); CLK_STOLB=0; #asm("nop"); } maska_stolb>>=1; // сдвигаем маску вправо на 1 разряд } while(maska_stolb!=0x000); // цикл выполняется, пока не выдадим 16 разрядов и //значение маски станет 0x0000 LATCH_STOLB=1; // Импульс на Latch clock #asm("nop"); LATCH_STOLB=0; }
//Сдвиг по строкам void sdvig_str (void) { maska_str=0x80;
do { // начало цикла if(str & maska_str) // если в результате умножения маски и числа получилось ненулевое значение { DATA_STR=1; // выводим в порт 1 #asm("nop"); CLK_STR=1; #asm("nop"); CLK_STR=0; #asm("nop"); } else { DATA_STR=0; // иначе 0 #asm("nop"); CLK_STR=1; #asm("nop"); CLK_STR=0; #asm("nop"); } maska_str>>=1; // сдвигаем маску вправо на 1 разряд } while(maska_str!=0x00); // цикл выполняется, пока не выдадим 16 разрядов и //значение маски станет 0x0000 LATCH_STR=1; // Импульс на Latch clock #asm("nop"); LATCH_STR=0; } //инициализация МК void inMK(void) { // Port A initialization PORTA=0x00; DDRA=0x0E; // Port B initialization PORTB=0x00; DDRB=0x00; // Port C initialization PORTC=0x00; DDRC=0x70; // Port D initialization PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization TCCR0=0x00; TCNT0=0x00; OCR0=0x00; // Timer/Counter 1 initialization TCCR1A=0x00; TCCR1B=0x01; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // INT2: Off MCUCR=0x00; MCUCSR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x04; // USART initialization // USART disabled UCSRB=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // ADC initialization // ADC disabled ADCSRA=0x00; // SPI initialization // SPI disabled SPCR=0x00; // TWI initialization // TWI disabled TWCR=0x00; } //основная программа void main(void) { inMK(); #asm("sei") while (1) { if(mButt_2.up){ // Если кнопка была нажата -> отжата mButt_2.up=0; // Сбрасываем флаг str=(str >> 1) | (str << 7); // Двигаем диод по строкам } if(mButt_1.up){ // Если кнопка была нажата -> отжата mButt_1.up=0; // Сбрасываем флаг stolb=(stolb >> 1) | (stolb << 15); // Двигаем диод по столбцам }
sdvig_stolb(); sdvig_str();
//buttob_stolb(); //buttob_str();
} }
_________________ Не бейте за глупости, я только учусь)
Пытаюсь сделать обработку длительного нажатия кнопки. Делаю вот так вот
Код:
interrupt [TIM1_OVF] void timer1_ovf_isr(void){ 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) && timer<10) // Если текущее значение - "нажата" и предыдущее - "не нажата" mButt_1.down = 1; // Устанавливаем флаг down if((mButt_1.cur!=ACT_BUTT_LEV) && (mButt_1.prev==ACT_BUTT_LEV)&& timer<10) // Если текущее значение - "не нажата" и предыдущее - "нажата" mButt_1.up = 1; // Устанавливаем флаг up if((mButt_1.cur==ACT_BUTT_LEV) && (mButt_1.prev==ACT_BUTT_LEV)){ timer++; if(timer>10) mButt_1.but_long = 1; }
mButt_1.prev=mButt_1.cur; // Сохраняем текущее значение. Оно для следующего входа будет предыдущим } //----------// }
но тут получается что при нескольких коротких нажатий переменная timer доходит до 10 и устанавливается флаг как этого избежать ? И вообще в правильную сторону копаю?
Заголовок сообщения: Re: Мелкие вопросы по МК и ПЛИС.
Добавлено: Чт ноя 28, 2013 09:44:18
Прорезались зубы
Зарегистрирован: Вт мар 12, 2013 16:05:45 Сообщений: 219
Рейтинг сообщения:0
Почему не работает код в обработчике прерывания, отслеживающий одновременное нажатие двух кнопок и удержание их в течении 2 сек., код одинаков для обоих обработчиков INT0 и INT1:
Код:
ISR(INT1_vect) { _delay_ms(300); char i = 0; while((PIND2 == 1) && (PIND3 == 1)) { _delay_ms(100); i++; if (i >= 20) { FLAG |= COUNTDOWN; break; } } }
Пробовал, вписывать вместо единицы ноль, но результата нет: while((PIND2 == 0) && (PIND3 == 0)) Думаю, что дело в подтягивающих резисторах МК, так ли это?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения