PIC Урок 4. Кнопка

 

 

 

Сегодня мы расширим свой кругозор по изучению работы портов микроконтроллера и изучим второе назначение порта — работу на вход. И для изучения работы на вход мы применим обычную тактовую кнопку.

Ну и давайте также как и в случаях с другими контроллерами в целях экономии времени на создание нового проекта в будущем, когда дело будет касаться одного и того же контроллера, попробуем проект для нашего сегодняшнего урока создать из проекта прошлого занятия.

Для этого мы в той же папке, где лежит папка с проектом BLINK01.X создадим ещё одну папку с именем таким, которое мы хотим присвоить новому проекту, в нашем случае будет BUTTON01.X.

И в эту папку из папки BLINK01.X мы перепишем папку nbproject и файлы Makefile и main.c.

Зайдём в папку nbproject в папке нового проекта и удалим там всё кроме файлов project.xml и configurations.xml.

Затем откроем файл project.xml и исправим в нём имя старого проекта на имя нового: в нашем случае BLINK01 на BUTTON01.

Всё!

Оказалось, что сгенерировать проект из старого легче чем в случае с AVR и STM.

А, ну заодно и файл проекта для протеуса тоже перепишем в новую папку, переименовав его тоже в свете требований имени нового проекта — в BUTTON01.X.pdsprj.

Запустим среду программирования MPLAB X IDE и просто откроем там наш новый проект из меню File -> Open Project либо с соответствующей кнопки тулбара.

Сделаем наш проект главным, чтобы из меню и тулбара всё управление шло именно к данному проекту, с помощью контекстного меню, вызвав его правой кнопкой мыши на имени проекта в дереве проектов по пункту Set as Main Project

 

 

Откроем файл main.c в новом проекте и попробуем проект собрать. Проект уже спокойно должен будет собраться, о чём будет свидетельствовать надпись в окне вывода информации, в котором также будет присутствовать и путь к файлу новой прошивки

 

 

Откроем теперь файл протеуса и исправим там в свойствах микроконтроллера путь к прошивке, так как он скорей всего остался к файлу старого проекта.

Запустим наш проект и проверим его работоспособность. Светодиоды должны будут поочерёдно зажигаться.

Теперь добавим кнопку, подключив её одним выводом к общему проводу, а другим к выводу RA2 контроллера

 

 

Также, чтобы в момент, когда кнопка не будет нажата, чтобы не получилось у нас неизвестное состояние у ножки порта, подтянем нашу ножку к выводу питания с помощью резистора, на 10 килоом, я думаю будет нормально

 

 

Вернёмся в наш проект в MPLAB и будем немного его совершенствовать. Думаю, нормально будет, если огни теперь при запуске сразу не побегут, а побегут они тогда, когда мы нажмём кнопку. Для этого мы сначала настроим ножку порта RA2 на вход соответствующим образом в функции main()

 

PORTA &= ~0x03;

TRISA |= 0x04; //Включим ножку RA2 на вход

 

Теперь над функцией main() давайте напишем функцию обнаружения нажатой кнопки, чтобы не загромождать функцию main

 

//--------------------------------------------

unsigned char CheckButton(void)

{

  unsigned char result=0;

  unsigned int butcount=0;

  while(!RA2)

  {

    if(butcount < 10000)

    {

      butcount++;

    }

    else

    {

      result = 1;

      break;

    }

  }

  return result;

}

//--------------------------------------------

 

Вот такая вот функция, которая кажется сложной только на первый взгляд, на самом деле она простая. Разберём всё по порядку сверху вниз.

Мы добавим две локальные беззнаковые целочисленные переменные, одну разрядностью в 8 бит, а другую в 16. Затем мы проверим наличие единицы в бите RA2, если такое имеет место, то попадём в тело цикла, в котором мы будем наращивать счётчик butcount в каждом прохождении по циклу при условии, что бит у нас будет оставаться в единице, то есть кнопка будет всё ещё нажата. Если мы в таком состоянии достигнем отметки в 10000, что будет соответствовать сколько-то милисекунд (подбирается на практике либо можно измерить с помощью инструмента отладки StopWatch, который мы испробовали на прошлом занятии), то мы уже не попадём в тело условия, что счётчик у нас меньше 10000, он же будет больше и мы тогда попадём в тело обратного (или противного) условия, где установим переменную результата в 1 и выйдем из цикла по команде break, а затем и из функции также с положительным результатом. А если мы так и не досчитаем до нашей цифры (которую вы можете для себя подобрать другую), то мы тогда и так выйдем из цикла while, и выйдем из функции, но уже с результатом 0, что будет свидетельствовать о том. что кнопка у нас не нажата. Таким образом мы не только отследим «нажатость» кнопки, но ещё и проведём борьбу с дребезгом, так как кнопки по качеству иногда отличаются.

 

 

Вернёмся в нашу функцию main() и в бесконечном цикле весь наш код бегущих светодиодов обернём в условие нажатия кнопки, что приведёт к тому, что данный код будет выполняться только в том условии, если мы нажмём кнопку. Соответственно, если мы её отпустим раньше, чем цикл бегущих огней дойдёт до окончания, то он все равно благополучно закончится, так как мы не будем отслеживать нажатие кнопки после каждой задержки. Может было бы эффективнее после отжатия кнопки оперативно прекращать цикл, но это внесёт определённые задержки в программу. Вот когда мы будем работать с таймерами, там это уже сделать будет хоть и не проще, но зато более безболезненно для программы.

Ну так вот он наш код бесконечного цикла

 

while(1)

{

  if(CheckButton())

  {

    PORTAbits.RA1 = 0;

    PORTBbits.RB0 = 1;

    __delay_ms(100);

    PORTBbits.RB0 = 0;

    PORTBbits.RB1 = 1;

    __delay_ms(100);

    PORTBbits.RB1 = 0;

    PORTBbits.RB2 = 1;

    __delay_ms(100);

    PORTBbits.RB2 = 0;

    PORTBbits.RB3 = 1;

    __delay_ms(100);

    PORTBbits.RB3 = 0;

    PORTBbits.RB4 = 1;

    __delay_ms(100);

    PORTBbits.RB4 = 0;

    PORTBbits.RB5 = 1;

    __delay_ms(100);

    PORTBbits.RB5 = 0;

    PORTBbits.RB6 = 1;

    __delay_ms(100);

    PORTBbits.RB6 = 0;

    PORTBbits.RB7 = 1;

    __delay_ms(100);

    PORTBbits.RB7 = 0;

    PORTAbits.RA0 = 1;

    __delay_ms(100);

    PORTAbits.RA0 = 0;

    PORTAbits.RA1 = 1;

    __delay_ms(100);

  }

}

 

Напомню, что то, что изменилось в коде, я выделяю. Невыделенное — это неизменённое и показываю я это с той целью, чтобы вы поняли, куда именно писать новый код.

Только это ещё не всё. Когда мы отожмём кнопку, наш цикл дойдёт до конца, но у нас не потухнет светодиод, подключенный к ножке порта RA1. Это непорядок. Давайте её потушим

 

    PORTAbits.RA1 = 1;

    __delay_ms(100);

    PORTAbits.RA1 = 0;

  }

}

return;

 

А вначале нашего цикла мы её уже тушить не будем. Если это будет самое первое прохождение по циклу, то у нас и так в данный момент ничего не светится, так как все ножки, к которым подключены наши светодиоды, находятся в нулях. Поэтому мы удалим данную строку из кода

 

if(CheckButton())

{

  PORTAbits.RA1 = 0;

  PORTBbits.RB0 = 1;

 

Ну что ж. Соберём наш код, зайдём в протеус и попробуем запустить его.

Соответственно, мы увидим, что светодиоды наши больше не зажигаются.

А чтобы они зажглись нажмём кратковременно на кнопку (но не слишком кратковременно, чтобы выждать наш период борьбы с дребезгом).

Светодиоды начнут попеременно светиться

 

 

Теперь подключим настоящую кнопку к нашей схеме прошлого урока, также не забываем и о резисторе

 

 

Подключим программатор, запустим программу PICkit 2, откроем нашу новую прошивку и зальём её в контроллер.

А вот и результат

 

 

Таким образом, цель нашего занятия достигнута. Мы научились работать с ножками портов, настроенными на вход. Также мы уже использовали добавление новой функции, один из методов борьбы с дребезгом контактов и, что немаловажно, научились делать проект из одного из предыдущих, не создавая его заново и не добавляя тот же код. Пока нам это мало что принесло и экономии во времени немного, но когда будут большие проекты, то вы, соответственно, увидите преимущество данного метода.

Спасибо всем за внимание!

 

Предыдущий урок Программирование МК PIC Следующий урок

 

Исходный код

 

 

Приобрести программатор PICKit3 (неоригинальный) можно здесь PICKit3

Приобрести программатор PICKit3 (оригинальный) можно здесь PICKit3

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

PIC Кнопка

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*