Заголовок сообщения: Re: Мелкие вопросы по МК и ПЛИС.
Добавлено: Чт ноя 28, 2013 10:01:06
Прорезались зубы
Зарегистрирован: Вт мар 12, 2013 16:05:45 Сообщений: 219
Рейтинг сообщения:0
А каким образом можно реализовать отслеживание удержания 2-х кнопок в течении 2сек. вне обработчика прерывания? У меня они не реагируют на команду (PIND2 == 0) или единице, пробовал через: while(EIFR == 0b00000011) и те же задержки.
1. Кнопки не относятся к устройствам реального времени. 2. Кнопки анализируются циклическим ОПРОСОМ. 3. Цикл можно задавать прерыванием от таймера. 4. Циклический опрос одновременно защищает от дребезга, если интервал опроса больше времени дребезга. Далее думайте. Когда появятся СВОИ идеи - продолжим...
Зарегистрирован: Вт мар 12, 2013 16:05:45 Сообщений: 219
Рейтинг сообщения:0
Пункт 2 непонятен (что опрашивать: пин, флаг прерывания...), у меня кнопки через резистор 10кОм соединены с питанием, а другим выводом на землю и при замыкании кнопки на пине д.б. 0, пробую в программе, но код не работает.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Причем тут прерывания? Опрашивается КНОПКА. То есть ПИН. А опрашивается он с интервалом прерываний от таймера. Состояние обеих кнопок фиксируется в специальном регистре, который называется машиной состояний. Анализ машины состояний и есть путь для решения Вашей задачи.
Зарегистрирован: Вт мар 12, 2013 16:05:45 Сообщений: 219
Рейтинг сообщения:0
Если под машиной состояний имеется ввиду флаг прерываний, устанавливаемый в единицу, когда происходит прерывание регистр EIFR биты INTF0 и INTF1: опрос while(EIFR == 0b00000011) то тут получается трудно нажать идеально одновременно обе кнопки чтобы запустился алгоритм, видимо придется опрашивать от прерывания таймера эти биты.
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Цитата:
видимо придется опрашивать от прерывания таймера эти биты.
Не "видимо придётся", а так и нужно делать. Где то в районе 4-ой страницы я выкладывал пример обработки кнопок. А на предыдущей странице есть посты, где человек запустил длинные нажатия. Почитайте темку, не ленитесь...
Если под машиной состояний имеется ввиду флаг прерываний, устанавливаемый в единицу, когда происходит прерывание регистр EIFR биты INTF0 и INTF1: опрос while(EIFR == 0b00000011) то тут получается трудно нажать идеально одновременно обе кнопки чтобы запустился алгоритм, видимо придется опрашивать от прерывания таймера эти биты.
У Вас дислексия? Я РУССКИМ языком написал: ЗАБУДЬТЕ О ПРЕРЫВАНИЯХ ОТ КНОПОК.
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 а там уже другие ошибки выскакивают.
Заголовок сообщения: Кнопки не работают от 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
Зарегистрирован: Вт мар 12, 2013 16:05:45 Сообщений: 219
Рейтинг сообщения:0
Как раз наоборот пытаюсь сделать опрос кнопок по шаблону от Alex'a (все в архиве), а в обработчики прерывания полез чтобы в протеусе тестировать значение на портах при которых кнопка замкнута и т.д. т.к. в голове не укладывается как так может быть, что у кнопки может быть состояние отличное от логических нулей и единиц...
/******************************************************************/ 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];
DDRD=0x0C; //0b00001100 единичные биты это те две кнопки PIND2 и PIND3, поставил нули реакции нет (но еще повожусь с этими нулями, чтоб наверняка знать)...
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
service47 писал(а):
поставил нули реакции нет
Какой кошмар Прежде чем что-то делать, нужно хорошо понимать что ты делаешь. А с таким методом тыка можно дотыкаться до убийства портов МК (как минимум)...
Зарегистрирован: Вт мар 12, 2013 16:05:45 Сообщений: 219
Рейтинг сообщения:0
Вобщем так: 1. Таймер1В отключен и прерывание тоже по переполнению. Запуск ШИМ откл. 2. Включены прерывания INT0 и INT1 с условиями для проверки значений нажатой кнопки. 3. При старте программы прописаны условия if чтобы проверить состояние отжатой кнопки методом подбора значении (если совпадет, то на индикаторе будет цифра 8 ).
Кнопки соответственно уменьшают и увеличивают значение на индикаторе на 1. Как только значения проясняться или все сведется к лог.0 и 1, то будет включен модуль написанный Alex'ом, там уже другие заморочки.
/******************************************************************/ 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 Нажимал в протеусе и на плате, но все работало с прошлой допотопной версией программы.
Нажимал в протеусе и на плате, но все работало с прошлой допотопной версией программы.
Работать оно может, но если записать в DDR и PORT "1", а потом закоротить этот пин на землю, то верхний ключ сгорит (или PORT в "0", а кнопкой соединить с +5В - нижний сдохнет), этот пин больше не сможет работать как выход, только как вход, если повезет. Нельзя соединять напрямую с питанием пины, сконфигурированные как выходы (DDR=1).
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(); //Глобальное разрешение прерываний
Этого вполне достаточно, чтобы понять что произошло с кнопками в момент срабатывания прерываний, дальше остается только отфильтровать ложные срабатывания, все остальное относительно кнопок просто мусор.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения