Печать
Категория: PIC
Просмотров: 7711

В прошлой статье мы рассмотрели простейшую программу для МК. Сейчас же усложним задачу: Усовершенствуем программу для МК, а, следовательно, и схему, так что бы выполнялись два условия:
->Возможность отключать бегущий огонь, и включать «дежурный» светодиод.
->Добавим возможность регулировки скорости «бега» бегущего огня.

Задача поставлена – приступим к решению.
Первым делом изменим схему, включив в нее две кнопки: одна с фиксатором, вторая без. Одним контактом кнопки включены через резистор на «+», тем самым формируя на RA0 и RA1 логическую единицу. При нажатии на выключатель SW1 (SW2), RA0 (RA1) замыкается на «землю» - теперь есть логический ноль.
Займемся кодом. В конце статьи есть полный исходник на С. Сейчас же разберем полученную свистопляску символов.
Начнем с команды Delay_ms() – пауза в мс (задаются в скобках). При выполнении данной команды, МК как будто «замирает» на время паузы, тем самым не дает возможности наблюдать за портами ввода RA0 и RA1 – не сможем видеть нажат ли SW1 или SW2. Заменим данную команду циклом и вынесем его в отдельную функцию, которую можно будет вызывать при необходимости в любом месте программы:
/*------------------------------------------- Функция паузы ---------------------------------------------*/
void pause()                                                                                                                
{
     int i;                                                            // Вводим целое i для счета пробега по циклу
     for (i=0;i<=t;i++)                                        // цикл будет выполнятся пока i<t t-время паузы
         {
         Delay_ms(1);                                            //Пауза в 1 мс
         if (knopka1 == 1 || knopka2 == 0 ) break; //Проверка переключателей
         }                                                              //если кнопки нажимались, пауза прерывается
}
/*--------------------------------------- Конец функции паузы -----------------------------------------*/











Далее запишем сам процесс «бегущего огня» тоже в виде функции, заменяя Delay_ms() написанной функцией pause().
/*----------------------------------------- Функция бегущего огня -------------------------------------*/
void begogon ()
{
 while(knopka1==0 && knopka2 == 1 )// Цикл будет выполятя пока SW1 вкл и
                                   // SW2 отпущена
         PORTB.F4=1;         //Устанавливаем на выводе RB4 1 - LED1 загорается
         pause();                //Пауза
         PORTB.F4=0;         //Устанавливаем на выводе RB4 0 - LED1 гаснет
         PORTB.F5=1;         //Устанавливаем на выводе RB4 1 - LED2 загорается
         pause();                //Пауза
         PORTB.F5=0;         //Устанавливаем на выводе RB4 0 - LED2 гаснет
         PORTB.F6=1;         //Устанавливаем на выводе RB4 1 - LED3 загорается
         pause();                //Пауза
         PORTB.F6=0;         //Устанавливаем на выводе RB4 0 - LED3 гаснет
         PORTB.F7=1;         //Устанавливаем на выводе RB4 1 - LED4 загорается
         pause();                //Пауза
         PORTB.F7=0;         //Устанавливаем на выводе RB4 0 - LED4 гаснет
         }
}
/*--------------------------------------- Конец функции бегущего огня --------------------------------*/

















Данные функции можно вызвать при необходимости в процессе исполнения программы.
C кнопкой SW1 все понятно:
/*------------------------------- Обработка кнопки SW1 ------------------------------*/

if (knopka1==0) begogon();           // Если SW1 вкл, то будет бегущий огонь
else PORTB.F4=1;                          // Иначе (если SW1 не вкл) - дежурный LED

/*------------------------------- Конец обработки кнопки SW1* ---------------------*/






В начале исполнения первой функции программы main(), переменной t присваивается максимальное значение паузы maxtime. Таким образом t = 510 мс (выбрано наугад). Если кнопка SW2 нажата, то отнимаем от текущего значения t величину в 60 мс (так же подобрана и может изменятся, как нужно). Pначение уже t =450 мс и т.д.
Выражение if (t<30) t=maxtime; необходимо, для контроля времени паузы t. Если оно будет меньше 30 мс (так же можно изменить на нужное), то переменной t присваивается значение maxtime.
Так как МК достаточно быстрый и может обработать состояние кнопки несколько раз, пока мы ее единожды нажали, значит, что операция разности может быть произведена несколько раз за одно нажатие. Что бы этого не допустить, вводится команда паузы Delay_ms(100) между последующими обработками SW2.

Ну и на последок как это работает.
Симуляция в Proteus Professional

Так же любые вопросы можно обсудить на форуме.

Авторизоваться, чтобы комментировать
wade ответил в теме #495 1 год 4 мес. назад
Итак.
Прошу прощения, что долго не отвечал - проходил начальный курс по программированию.
Статью номер 6 читал, так все понятно и есть пошаговая инструкция. Но в 8ой статье не все было понятно. Сейчас вроде немного разобрался. Программу собрал, все работает. Если можете, оставьте комментарии, что думаете, что можно исправить\переделать.
Оставлю ссылку на github, чтоб не засорять форум.
github.com/e-Wade/Running_leds_v2/blob/master/mcppi
alex аватар
alex ответил в теме #494 1 год 5 мес. назад
статью 6 читал? там весь код программы расписан, даже видео есть пошаговое.
wade ответил в теме #493 1 год 5 мес. назад
Тот же, что и в примерах. PIC16F84A
alex аватар
alex ответил в теме #492 1 год 5 мес. назад
PORTA - это регистр - обращение к самому контроллеру. knopka1 - это только для нашего понимания.
порту контроллера нельзя присвоить кнопку1
можно заменить одно другим командой #define, например,
#define knopka1 PORTA.F0;
Другими словами, когда компилятор будет собирать прошивку, вместо knopka1 он везде проставит PORTA.F0.

Данная замена делается только для нашего удобства. Замена прописывается в самом верху.
Кроме того в твоем коде неправильно настроен контроллер. Давай начнем с самого начала. Какой контроллер используешь?
wade ответил в теме #491 1 год 5 мес. назад
начну сначала. что делать с "knopka1" и "knopka2"?
их нужно присвоить к PORTA.F0 и PORTA.F1 соответственно?
PORTA.F0 = knopka1;
PORTA.F1 = knopka2;
вот так? или наоборот
knopka1=PORTA.F0;
knopka2=PORTA.F1;
Так как весь код у меня не работает, то я начал разбирать по частям. Остановился на том, что просто не могу взаимодествовать с кнопками: никак не реагируют на нажатия. Поэтому решил сначала разобраться с дежурным светодиодом, чтобы он загорался\гас по нажатию, но не выходит
int knopka1,knopka2;
void main()
{
TRISB=0;
PORTB=0;
TRISA.F1=1;
TRISA.F0=1;
knopka1=PORTA.F0;
knopka2=PORTA.F1;
if (knopka1 == 0)PORTB.F5=1;
else PORTB.F4=1;
}
alex аватар
alex ответил в теме #490 1 год 5 мес. назад
Что именно не получается? Выложи свой код, глянем на ошибки.
П. С. Код из статьи возможно достану через пару дней.
wade ответил в теме #488 1 год 5 мес. назад
кто нибуль может помочь с полным кодом программы? не получается сделать самостоятельно, а ссылка на полный код видимо пропала.