Изменим схему следующим образом
добавим две тактовые кнопки BT1 и BT2.
Теперь переключимся на конфигурацию выводов, для этого сделаем двойной клик в окне Ресурсы проекта на Pin Module.
В окне Pin Module настроим RB6 и RB7
Настроим на вход убрав птички в колонке выход, подключим к этим входам подтягивающие резисторы, теперь на входе будет высокий уровень, при замыкании кнопки, уровень будет становиться низким. Обрабатывать прерывания мы будем через прерывания, чтобы не загружать процессор контролем состояния на этих входах.
В итоге у нас должен быть такой вид
Тискаем кнопочку сгенрировать
А теперь посмотрим как изменилась конфигурация входов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
void PIN_MANAGER_Initialize(void) { /** LATx registers */ LATA = 0x00; LATB = 0x00; LATC = 0x00; /** TRISx registers */ TRISA = 0x08; TRISB = 0xC0; TRISC = 0x00; /** ANSELx registers */ ANSELC = 0x00; ANSELB = 0x00; ANSELA = 0x00; /** WPUx registers */ WPUB = 0xC0; WPUA = 0x08; OPTION_REGbits.nWPUEN = 0; /** APFCONx registers */ APFCON = 0x00; /** IOCx registers */ // interrupt on change for group IOCBF - flag IOCBFbits.IOCBF6 = 0; IOCBFbits.IOCBF7 = 0; // interrupt on change for group IOCBN - negative IOCBNbits.IOCBN6 = 1; IOCBNbits.IOCBN7 = 1; // interrupt on change for group IOCBP - positive IOCBPbits.IOCBP6 = 0; IOCBPbits.IOCBP7 = 0; // register default IOC callback functions at runtime; use these methods to register a custom function IOCBF6_SetInterruptHandler(IOCBF6_DefaultInterruptHandler); IOCBF7_SetInterruptHandler(IOCBF7_DefaultInterruptHandler); // Enable IOCI interrupt INTCONbits.IOCIE = 1; } |
Что изменилось?
Два вывода настроены на вход
1 2 3 4 5 |
TRISx registers */ TRISA = 0x08; TRISB = 0xC0; TRISC = 0x00; |
Подключили к этим входах подтягивающие резисторы
1 2 3 4 5 |
WPUx registers */ WPUB = 0xC0; WPUA = 0x08; OPTION_REGbits.nWPUEN = 0; |
Выполнена настройка полярности формирования прерываний
1 2 3 4 5 6 7 8 9 |
// interrupt on change for group IOCBF - flag IOCBFbits.IOCBF6 = 0; IOCBFbits.IOCBF7 = 0; // interrupt on change for group IOCBN - negative IOCBNbits.IOCBN6 = 1; IOCBNbits.IOCBN7 = 1; // interrupt on change for group IOCBP - positive IOCBPbits.IOCBP6 = 0; IOCBPbits.IOCBP7 = 0; |
Регистрация функций прерываний и разрешение прерываний от портов по изменению состояния
1 2 3 4 5 6 |
// register default IOC callback functions at runtime; use these methods to register a custom function IOCBF6_SetInterruptHandler(IOCBF6_DefaultInterruptHandler); IOCBF7_SetInterruptHandler(IOCBF7_DefaultInterruptHandler); // Enable IOCI interrupt INTCONbits.IOCIE = 1; |
Изменилась также функция менеджера прерываний
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void interrupt INTERRUPT_InterruptManager (void) { // interrupt handler if(INTCONbits.TMR0IE == 1 && INTCONbits.TMR0IF == 1) { TMR0_ISR(); } else if(INTCONbits.IOCIE == 1 && INTCONbits.IOCIF == 1) { PIN_MANAGER_IOC(); } else { //Unhandled Interrupt } } |
В ней появилось секция обработки прерываний от изменения состояний на входах
1 2 3 4 5 |
else if(INTCONbits.IOCIE == 1 && INTCONbits.IOCIF == 1) { PIN_MANAGER_IOC(); } else |
Для индикации работы прерываний по входам будем использовать те же светодиоды, для этого закомментируем их функцию в прерываниях от таймера
1 2 3 4 5 6 7 8 9 10 11 |
void TMR0_CallBack(void) { // Add your custom callback code here // LD1=!LD1; // LD2=!LD2; if(TMR0_InterruptHandler) { TMR0_InterruptHandler(); } } |
и добавим их в функции IOCBF6_ISR и IOCBF7_ISR
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/** IOCBF6 Interrupt Service Routine */ void IOCBF6_ISR(void) { // Add custom IOCBF6 code LD1=!LD1; // Call the interrupt handler for the callback registered at runtime if(IOCBF6_InterruptHandler) { IOCBF6_InterruptHandler(); } IOCBFbits.IOCBF6 = 0; } /** IOCBF7 Interrupt Service Routine */ void IOCBF7_ISR(void) { // Add custom IOCBF7 code LD2=!LD2; // Call the interrupt handler for the callback registered at runtime if(IOCBF7_InterruptHandler) { IOCBF7_InterruptHandler(); } IOCBFbits.IOCBF7 = 0; } |
Теперь прошьем ПИК.
УПС!!! получили ошибки как видно эта версия МСС еще не совсем корректно работает, но это не проблема, просто МСС “забыл добавить новые функции в описание, в шапку. Это нас не должно останавливать, поэтому сделаем это за него. Добавим строки в файл pin_manager.h.
1 2 3 4 5 6 |
void IOCBF6_SetInterruptHandler(void* InterruptHandler); void IOCBF7_SetInterruptHandler(void* InterruptHandler); void IOCBF6_ISR(void); void IOCBF7_ISR(void); void IOCBF6_DefaultInterruptHandler(void); void IOCBF7_DefaultInterruptHandler(void); |
Теперь все завелось!!! И работает! Но как? Мы настроили, что при нажатию на кнопку состояние светодиода должно быть изменено на противоположное, все так и работает, но иногда почему-то происходит сбой.
Светодиод сразу выключается или помаргивает и все. это связано с нашим банальным дребезгом механических контактов.
Любой механический контакт, как бы он не был совершенен, в процессе замыкании, создает в своем начале дребезг, тоже самое происходит и при размыкании, это дребезг даже нашим “тихоходным контроллером” может быть обработан многократно, что при определенной ситуации даст нам нежелательный результат.
Как с этим дребезгом бороться, известно давно, что в тактовых кнопках длительность дребезга не более 10 мс. Локи проста при появлении прерывания, надо подождать 10 мс проверить уровень на входе и если он низкий выполнить функцию, если нет, то это будем расценивать как помеху. И все.
Как это будет выглядеть на практике изменим рабочий код прерывания для входа RB7
1 2 3 4 5 6 7 8 9 10 11 12 |
void IOCBF7_ISR(void) { // Add custom IOCBF7 code __delay_ms(10); if(!RB7)LD2=!LD2; // Call the interrupt handler for the callback registered at runtime if(IOCBF7_InterruptHandler) { IOCBF7_InterruptHandler(); } IOCBFbits.IOCBF7 = 0; } |
Что сделали? Добавили задержку а потом проверку реально низкого уровня на входе. Но надо не забыть добавить в заголовочный файл pin_manager.h вставку #include “mcc.h” в файле mcc.h описывается тактовая рабочая частота которая необходима для функции задержки.
Часть текста файла pin_manager.h с изменениями
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. */ #ifndef PIN_MANAGER_H #define PIN_MANAGER_H #include "mcc.h" #define INPUT 1 #define OUTPUT 0 #define HIGH 1 #define LOW 0 #define ANALOG 1 #define DIGITAL 0 |
Теперь проверим как будет работать кнопки на “модернизированном” входе и без. Кнопка подключенная ко входу RB7 работает четко переключая светодиод, а кнопка подключенная к входу RB6 со сбоями. Это типа ощутите разницу!
Теперь выполним модернизацию и входа RB6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** IOCBF6 Interrupt Service Routine */ void IOCBF6_ISR(void) { // Add custom IOCBF6 code __delay_ms(10); if(!RB6)LD1=!LD1; // Call the interrupt handler for the callback registered at runtime if(IOCBF6_InterruptHandler) { IOCBF6_InterruptHandler(); } IOCBFbits.IOCBF6 = 0; } |
Перепрошьем ПИК и о чудо, можно сказать жизнь удалась!!! Все работает без единого сбоя.
Очень важно получить от механических устройств правильно сформированный импульс, все стародавние варианты, с подключением конденсаторов для микроконтроллеров не катят, все должно обрабатываться программно. И актуально когда нужно получить счетный вход!
Проект по теме

Проект с использованием MCC часть 06 261.19 KB 65 downloads
Изменим схему следующим образом добавим две...Теперь мы можем управлять светодиодами, а можем ли мы управлять их яркостью? Это рассмотрим в следующей главе…
Это может быть интересно
Audio-bluetooth modules BK8000L (noname)
Еще один вариант, так сказать недоразумения Audio-bluetooth modules BK8000L (noname). Его отличительной маркировкой служат два отверстия в плате и надпись R2. Отличают его от модулей на чипе BK8000L, что у …Регулятор влажности
Регулятор ILLISSI-CH-1000 предназначен для контроля и регулировки относительной влажности в диапазоне от 0 до 100%. Регулятор позволяет работать как в режиме осушения, так и увлажнения. Для измерения возможно использовать аналоговые …CAN – Controller Area Network
Controller Area Network (CAN) первоначально был создан немецким поставщиком автомобильных систем Робертом Бош в середины 1980-х для автомобильной промышленности как метод для обеспечения возможности надежной последовательной связи. Целью было сделать автомобили более надежными, безопасными и …Акриловый корпус для платы ch-4000
Плата ch-4000 подходит для монтажа в корпуса на дин рейку, но для домашней автоматики необходимо что-то другое, поэтому был разработан корпус из акрила который позволит создавать настольные и настенные устройства. Корпус состоит из …Ultrasonic Level Meters – ULM –53L
Измерение расстояния при помощи ультра звукового датчика ULM–53L–10. Диапазон измерения от 0,5 м до 10 м, полностью пластмассовый излучатель PVDF, механическое соединение фланцем из полиэтилена HDPE (исполнение “N”) Характеристики Диапазон измерения …Счетчики посетителей
Вас сосчитали!? или счетчики посетителей. Для чего нужны счетчики посетителей? Какие они бывают? ТОРГОВЛЯ. Подсчитайте, сколько ваш магазин посещает человек за день. Кок много человек приходит утром, какое количество вечером. …Гаджеты для домашней автоматики – Датчик приближения
Управление светодиодным освещением – Датчик приближения. Данный гаджет предназначен для управления внутренним освещением мебели. Датчик позволяет определить закрытие или открытие дверцы или ящика и при этом включать или выключать освещение. …I2C MODULE – PIC18F25K42 Device ID Revision = A001
I2C MODULE Обход ошибок в версии I2C MODULE – PIC18F25K42 Device ID Revision = A001 В Серии K42 применен совершенно новый модуль шины I2C, который позволяет поддерживать все режимы этой …NS108-5050-16bit от Newstar
Кто уже использует в своих проектах адресуемые светодиоды хорошо знакомы с такими как WS2812 и им подобные. Эти светодиоды для управления используют однопроводную шину. Из-за этого пропускная способность такой шины …MCC PIC24 – модуль OUTPUT COMPARE – в режиме генератора звуковых сигналов
При проектировании простых устройств автоматики, часто необходимо иметь механизм звукового оповещения. Самый верхний уровень, это формирование голосовых сообщений, но об этом, как то по позже… В самом примитивном варианте можно …