Страница 1 из 1

управление кнопками вкл\выкл на МК.

Добавлено: Сб дек 05, 2009 02:24:11
Rv
Всем добрый вечер!
Уважаемые форумчане помоготе написать програмку для любого бюджетного МК (PIC или AVR).
Это управление кнопками вкл\выкл с помощью микроконтроллера с разными функциями управления
выходного сигнала.МК необходим для уменьшения габаритов и навесных элементов.

Добавлено: Сб дек 05, 2009 10:48:39
AI_Disable
То есть нужно, чтоб на выходе была единица, пока удерживаешь S1, а после замыкания S2, единица должна удерживаться до следующего нажимания на кнопку? При этом нужна задержка t между нажатием кнопки и появлением единицы на выходе?
Если я всё правильно понял, то тут и МК не нужен. Можно обойтись стандартной логикой. Но если вы уж так хотите, то можно тиньку13 поставить иль ещё осьминога какого-нибудь код будет наподобе:

Код: Выделить всё

del, см. ниже

Добавлено: Вс дек 06, 2009 01:26:26
Rv
AI_Disable,спасибо,что откликнулись на просьбу.Я забыл указать,что кнопкам S1 и S2 должны соответствовать свои выходы раздельно.

Добавлено: Вс дек 06, 2009 10:48:52
Meteor
Если не секрет, почему на Вашем рисунке, происходит срабатвание от разных фронтов - включение по переднему, а выключение по заднему? Это необходимость или нет? От этого зависит сама прога. Легче что-то одно обрабатывать.

Добавлено: Вс дек 06, 2009 12:05:28
AI_Disable
Rv, код исправил, для разных выходов, с учётом фронтов и спадов, порты поправил под ваш рисунок:

Код: Выделить всё

char flag;
int main()
{
while(1) 
{ 
if(bit_is_set(PINB,0)) //Опрос S1
{
if(bit_is_clear(flag,0)) //больше не ждать t, пока не отпустят S1
{
_delay_ms(t); //задержка t 
PORTB|=(1<<3); 
flag|=(1<<0); 
} 
}
else 
{ 
if(bit_is_set(flag,0)) //больше не ждать t, пока не нажмут S1
{
_delay_ms(t); //задержка t 
PORTB&=~(1<<3); 
flag&=~(1<<0); 
} 
}
if(bit_is_set(PINB,1)) //Опрос S2 
{
if(bit_is_clear(flag,1)) //больше не ждать t, пока не отпустят S2
{ 
if(bit_is_set(PINB,4)) while(bit_is_set(PINB,1));
_delay_ms(t); //задержка t 
PORTB^=(1<<4); 
flag|=(1<<1); 
} 
}
else flag&=~(1<<1); 
}
}
И, да, подтяните на схеме reset МК к VCC через резистор 10кОм. Ещё надо бы добавить защиту от дребезга...

Добавлено: Пн дек 07, 2009 02:34:45
Rv
AI_Disable,спасибо за код.Буду разбираться,инет глючит нет выхода.О результате отпишусь.

Добавлено: Вт дек 08, 2009 00:07:32
Rv
AI_Disable,пробую компилировать Ваш код,выдаёт 4 ошибки.Подскажите,что не так.Я в CodeV.работаю первый раз.Да в программировании разбираюсь слабо.

Добавлено: Ср дек 09, 2009 19:54:58
AI_Disable
Код писал под WinAVR. Ниже поправил под кодвижион. Я уже давно не пользуюсь им, поэтому мог допустить ошибки...

Код: Выделить всё

bit flag; 
bit flag2;
void main(void) 
{ 
while(1) 
{ 
if(PINB%2) //Опрос S1 
{ 
if(flag==0) //больше не ждать t, пока не отпустят S1 
{ 
_delay_ms(t); //задержка t 
PORTB|=(1<<3); 
flag=1; 
} 
} 
else 
{ 
if(flag) //больше не ждать t, пока не нажмут S1 
{ 
_delay_ms(t); //задержка t 
PORTB&=~(1<<3); 
flag=0; 
} 
} 
if((PINB/2)%2) //Опрос S2 
{ 
if(flag2==0) //больше не ждать t, пока не отпустят S2 
{ 
if((PINB/16)%2) while((PINB/2)%2); 
_delay_ms(t); //задержка t 
PORTB^=(1<<4); 
flag2=1; 
} 
} 
else flag2=0; 
} 
}

Добавлено: Ср дек 09, 2009 20:07:45
AI_Disable
Хех, вверху в коде тоже была ошибочка, по крайней мере, одна, исправил.

Добавлено: Сб дек 12, 2009 00:20:05
Rv
Собрал устройство в железе и Proteus 7.6 SP0. AI_Disable,спасибо за исправления кода.
Вот что получилось.
1.при включении питания порт PB4 установлен в "1",когда должен "0".
2.порт PB3 верно,в нуле.
3.при включении S1(многократно),на выходе PB4 ничего не происходит.
4.при включении S2 алгоритм работы соответствует задаче.
И вот после того,как вкл/выкл S2,кнопка S1 начинает работать в нужном режиме,
Ещё надо настроить порты.PB3,PB4 на выход.PB0,PB1 на вход с подтяжкой резисторов.
AI_Disable,на Вас вся надежда.

Добавлено: Сб дек 12, 2009 10:51:20
AI_Disable
Не обратил внимания, что кнопки повешены на GND, а не на VCC.
Вот:

Код: Выделить всё

bit flag; 
bit flag2; 
void main(void) 
{ 
DDRB|=(1<<3); //Настройка портов
DDRB|=(1<<4); 
// PORTB|=(1<<0);     //раскомментируйте, если лень вешать резисторы подтяжки на кнопки
// PORTB|=(1<<1);
while(1) 
{ 
if(PINB%2==0) //Опрос S1 
{ 
if(flag==0) //больше не ждать t, пока не отпустят S1 
{ 
delay_ms(50); //задержка t 
PORTB|=(1<<3); 
flag=1; 
} 
} 
else 
{ 
if(flag) //больше не ждать t, пока не нажмут S1 
{ 
delay_ms(50); //задержка t 
PORTB&=~(1<<3); 
flag=0; 
} 
}  
if((PINB/2)%2==0) //Опрос S2 
{ 
if(flag2==0) //больше не ждать t, пока не отпустят S2 
{ 
delay_ms(50); //задержка t 
PORTB^=(1<<4); 
flag2=1; 
} 
} 
else flag2=0; 
} 
}
Проверил в протеусе с вашей схемой, вроде всё работает.

Добавлено: Сб дек 12, 2009 15:00:09
Rv
AI_Disable,всё заработало как требовалось,СПАСИБО за работу!

Добавлено: Сб дек 12, 2009 15:26:14
AI_Disable
PORTB|=(0<<3);
PORTB|=(0<<4);
1-состояние порта,<< 1номер порта
PORTB|=(0<<2);
Не совсем так. Первая с лева цифра - это не состояние порта.
Выражение PORTB|=(0<<2); ничего не делает. Для записи в бит регистра порта нуля, не трогая другие биты нужно делать так:
PORTB&=~(1<<номер_бита); Код вижион имеет такую фитчу:
PORTB.4=1; это тоже самое, что и PORTB|=(1<<4);
,а PORTB.4=0; это тоже самое, что и PORTB&=~(1<<4);

Добавлено: Сб дек 12, 2009 17:30:34
Rv
Исправил.

Добавлено: Вс дек 13, 2009 11:48:59
AI_Disable
Теперь я вообще не понимаю, что вы хотите. Вам нужно чтоб S1 "действовала" на D3, также как S2 на D2?

Код: Выделить всё

void main(void) 
{ 
DDRB|=(1<<3); //Настройка портов 
DDRB|=(1<<4);
DDRB|=(1<<2); 

PORTB|=(1<<0);     //раскомментируйте, если лень вешать резисторы подтяжки на кнопки
PORTB|=(1<<1);
PORTB&=~(1<<2);	//В регистрах портов, после включения, всегда нули.  Эти три строчки бесполезны.
PORTB&=~(1<<3);
PORTB&=~(1<<4);
                
while(1) 
{ 
if(PINB%2==0) //Опрос S1 
{ 
if(flag==0) //больше не ждать t, пока не отпустят S1 
{ 
delay_ms(50); //задержка t 
PORTB|=(1<<3); 
flag=1; 
} 
} 
else 
{ 
if(flag) //больше не ждать t, пока не нажмут S1 
{ 
delay_ms(50); //задержка t 
PORTB&=~(1<<3); 
flag=0;
delay_ms(50); //задержка t 
PORTB^=(1<<2); 
flag2=1; 				 //Зачем тут трогать флаг, отнасящийся ко второй кнопке?
} 
}  
if((PINB/2)%2==0) //Опрос S2 
{ 
if(flag2==0) //больше не ждать t, пока не отпустят S2 
{ 
delay_ms(50); //задержка t 
PORTB^=(1<<4); 
flag2=1; 
} 
} 
else flag2=0; 			//Темболее он сразуже сбросится в этом месте
} 
}

Добавлено: Вс дек 13, 2009 14:40:46
Rv
Замечания учёл,но чисто визуально разницы не увидел.А c PB2 просто эксперементировал,мало-ли понадобится такое же управление портом
как и от S2.В данном случае порт PB2 управляется после окончания процесса PB3.Можно сделать одновременно при нажатии S1,но у меня не получилось.