Страница 1 из 1
управление кнопками вкл\выкл на МК.
Добавлено: Сб дек 05, 2009 02:24:11
Rv
Всем добрый вечер!
Уважаемые форумчане помоготе написать програмку для любого бюджетного МК (PIC или AVR).
Это управление кнопками вкл\выкл с помощью микроконтроллера с разными функциями управления
выходного сигнала.МК необходим для уменьшения габаритов и навесных элементов.
Добавлено: Сб дек 05, 2009 10:48:39
AI_Disable
То есть нужно, чтоб на выходе была единица, пока удерживаешь S1, а после замыкания S2, единица должна удерживаться до следующего нажимания на кнопку? При этом нужна задержка t между нажатием кнопки и появлением единицы на выходе?
Если я всё правильно понял, то тут и МК не нужен. Можно обойтись стандартной логикой. Но если вы уж так хотите, то можно тиньку13 поставить иль ещё осьминога какого-нибудь код будет наподобе:
Добавлено: Вс дек 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,но у меня не получилось.