Перше, що може заважати цьому – відсутність у складі мікросхеми вбудованого аналого-цифрового перетворювача Якщо у робота, де використовується мікроконтролер PIC16F887, вимірювач відстані працює в парі з АЦП, то що робити нам

Так, модуля АЦП немає, але є вбудовані компаратори, і є програмно керовану опорна напруга Якщо визначити це опорна напруга рівним 100 мВ, що відповідає відстані до поверхні, що відбиває більше 15 см, то при перевищенні напруги сигналу від фотоприймача, ми будемо «бити тривогу»

Як і колись, опишемо мета нашої наступної роботи:

1 Мікроконтролер PIC16F628A потрібно так налаштувати, щоб працював його вбудований компаратор, до одного з входів якого підключено опорна напруга від внутрішнього джерела, а до іншого входу буде підключений детектор

2 Мікроконтролер буде постійно випромінювати ІЧ-сигнал, але при напрузі на вході компаратора більше 100 мв, коли компаратор перемикається, повинен встановлюватися прапор – праворуч перешкоду

3 При запиті по USART від основного контролера, коли робот виявляє перешкоду перед собою, мікроконтролер PIC16F628A повинен відправити стан прапора: «0» – праворуч перешкоди немає, «1» – праворуч перешкоду

По суті, описавши вище, що ми маємо намір отримати в результаті, ми розбили задачу на підзадачі, і готові приступити до роботи, використовуючи як плану роботи наш опис

Що можна знайти в описі контролера про опорному напрузі і компараторах Пошукаємо

Модуль компараторів дозволяє використовувати внутрішнє джерело опорної напруги, описаний в розділі 110 Сигнал внутрішнього джерела опорного напруги підключається до висновків VIN + обох компараторів, коли біти конфігурації CM <2:0> = 010 (див малюнок 9-1)

Подивимося малюнок:

Рис 5313 Малюнок з довідки – схема включення компараторів

Звернемося до опису регістра, згаданого вище:

Рис 5314 Регістр CMCON мікроконтролера PIC16F628A Біт 7: C2OUT: Вихід компаратора 2

Якщо C2INV = 0

1 = C2 VIN+ > C2 VIN-

0 = C2 VIN+ < C2 VIN-

Якщо C2INV = 1

0 = C2 VIN+ > C2 VIN-

1 = C2 VIN+ < C2 VIN-

Біт 6: C1OUT: Вихід компаратора 1 Якщо C1INV=0

1 = C1 VIN+ > C1 VIN-

0 = C1 VIN+ < C1 VIN-

Якщо C1INV = 1

0 = C1 VIN+ > C1 VIN-

1 = C1 VIN+ < C1 VIN-

Біт 5: C2INV: Інверсний вихід компаратора 1 лютого = C2 інверсний вихід

0 = C2 НЕ інверсний вихід

Біт 4: C1INV: Інверсний вихід компаратора 1 січня = C1 інверсний вихід

0 = C1 не інверсний вихід

Біт 3: CIS: Підключення входів компараторів Якщо CM2:CM0 = 001

1 = C1 VIN-підключений до RA3 0 = C1 VIN-підключений до RA0 Якщо CM2:CM0 = 010

1 = C1 VIN-підключений до RA3 C2 VIN-підключений до RA2

0 = C1 VIN-підключений до RA0 C2 VIN-підключений до RA1

Біти 2-0: CM2: CM0: Режим роботи компараторів Дивіться малюнок вище

І на завершення заглянемо в розділ 11:

Налаштування джерела опорного напруги

Джерело опорного напруги може мати 16 різних рівнів напруги для кожного діапазону

Рівняння обчислення напруги:

Якщо VRR = 1: VREF = (VR <3:0> / 24) x VDD

Якщо VRR = 0: VREF = (VDD x ¼) + (VR <3:0> / 32) x VDD

Час установки напруги повинно визначатися по напрузі на висновку VREF

І ось опис регістра налаштування опорного напруги:

Рис 5315 Регістр VRCON

Біт 7: VREN: Включення джерела опорного напруги 1 = джерело опорного напруги включений

0 = джерело опорного напруги вимкнений і не споживає струму Біт 6: VROE: Включення виходу VREF

1 = вихід VREF підключений до RA2

0 = вихід VREF не підключений до RA2

Біт 5: VRR: Діапазон вихідної напруги VREF 1 = нижній діапазон

0 = верхній діапазон

Біт 4: Не використовується: читається як 0

Біти 3-0: VR3: VR0: Вибір вихідної напруги VREF 0 < = VR [3:0] <= 15 Якщо VRR = 1: VREF = (VR <3:0> / 24) x VDD

Якщо VRR = 0: VREF = (VDD x ¼) + (VR <3:0> / 32) x VDD

І ще одне зауваження з datasheet:

Відповідні біти в регістрі TRISA визначають підключати чи ні вихід компараторів до висновків RA3 і RA4/T0CKI (якщо CM <2:0> = 110 або 001)

Щоб написати цю частину програми, рушимо в зворотному напрямку Спочатку визначимо, як отримати опорна напруга порядку 100 мВ

Запишемо в регістр VRCON число 11100001 (0xE1) Запишемо в CMCON число 11000110 (0xC6) Що відповідає настройці кілька відрізняється від рекомендацій, але працює в програмі:

void main() { VRCON = 0xE1 CMCON = 0xC6 TRISA = 0xF7

while(1)

}

Рис 5316 Робота компаратора з опорною напругою

Порогова напруга, правда, не 100 мВ, але трохи більше 200 мВ (що випливає з можливостей вбудованого опорного напруги)

Поєднавши вихід компаратора з входом мікроконтролера, який ми можемо опитувати, ми отримаємо наступне розвиток програми:

void main() { VRCON = 0xE1 CMCON = 0xC6 TRISA = 0xF3

while(1)

{

if (PORTBF0 == 1) PORTAF2 = 1 else PORTAF2 = 0

}

}

Установка виведення RA2 в одиницю або скидання в нуль потрібні в якості перевірки:

Рис 5317 Проміжна перевірка

Тепер ми замінимо цю перевірочну операцію операцією управління прапором

char flag = 0 void main() {

VRCON = 0xE1 CMCON = 0xC6 TRISA = 0xF3

while(1)

{

if (PORTBF0 == 1) flag = 0

else flag = 1

}

}

І додамо в програму переривання по UART Завідують перериваннями регістр INTCON:

Рис 5318 Біти регістра INTCON

Біт 7: GIE: Глобальне дозвіл переривань

1 = дозволені всі немаскірованном переривання 0 = всі переривання заборонені

Біт 6: PEIE: Дозвіл переривань від периферійних модулів

1 = дозволені всі немаскірованном переривання периферійних модулів 0 = переривання від периферійних модулів заборонені

Біт 5: T0IE: Дозвіл переривання по переповнення TMR0 1 = переривання дозволено

0 = переривання заборонено

Біт 4: INTE: Дозвіл зовнішнього переривання INT 1 = переривання дозволено

0 = переривання заборонено

Біт 3: RBIE: Дозвіл переривання по зміні сигналу на входах RB7: RB4 PORTB 1 = переривання дозволено

0 = переривання заборонено

Біт 2: T0IF: Прапор переривання по переповнення TMR0

1 = сталося переповнення TMR0 (скидається програмно) 0 = переповнення TMR0 не було

Біт 1: INTF: Прапор зовнішнього переривання INT

1 *) = виконана умова зовнішнього переривання на виведенні RB0/INT 0 = зовнішнього переривання не було

Біт 0: RBIF: Прапор переривання по зміні рівня сигналу на входах RB4: RB7 PORTB 1 *) = зафіксована зміна рівня сигналу на одному з входів RB7: RB4

0 = не було зміни рівня сигналу на жодному з входів RB7: RB4

*) Скидається програмно І регістр PIE1:

Рис 5319 Біти регістра PIE1

Біт 7: EEIE: Дозвіл переривання по закінченню запису в EEPROM даних 1 = переривання дозволено

0 = переривання заборонено

Біт 6: CMIE: Дозвіл переривання від компараторов 1 = переривання дозволено

0 = переривання заборонено

Біт 5: RCIE: Дозвіл переривання від приймача USART 1 = переривання дозволено

0 = переривання заборонено

Біт 4: TXIE: Дозвіл переривання від передавача USART 1 = переривання дозволено

0 = переривання заборонено Біт 3: Чи не реалізований: читається як 0

Біт 2: CCP1IE: Дозвіл переривання від модуля CCP1 1 = переривання дозволено

0 = переривання заборонено

Біт 1: TMR2IE: Дозвіл переривання по переповнення TMR2 1 = переривання дозволено

0 = переривання заборонено

Біт 0: TMR1IE: Дозвіл переривання по переповнення TMR1 1 = переривання дозволено

0 = переривання заборонено

Допишемо дозволу переривання і програму обробки переривання

char flag = 0 char cmnd = 0

void interrupt() {

if (UART1_Data_Ready() == 1) { cmnd = UART1_Read()

}

if (flag == 1) UART1_Write(1) else UART1_Write(0)

INTCONPEIE = 1

}

void main() {

TRISA = 0xF3 INTCONGIE = 1

INTCONPEIE = 1

PIE1RCIE = 1 VRCON = 0xE1 CMCON = 0xC6 UART1_Init(4800)

Delay_ms(100) while(1)

{

if (PORTBF0 == 1) flag = 0

else flag = 1

}

}

Промоделюємо ситуацію за компютером:

Рис 5320 Моделювання роботи другого мікроконтролера

Я ніяк не визначав команду запиту до контролера, тому можна відправляти будь-який символ Але, якщо буде потрібно, скажімо, кілька команд, то для кожної можна визначити свій символ або набір символів Перший відгук після команди був виконаний при напрузі на виході детектора більш 200 мВ, друге, як показано на малюнку

Залишилося перевірити роботу двох мікроконтролерів, замінивши віртуальний термінал контролером PIC16F887 Я не буду писати для нього повну програму Зараз мені це не важливо Я напишу програму, в якій кожну секунду відправлятиметься команда, яка запитує стан прапора, що визначається датчиком другого мікроконтролера Ось ця програма:

void main() { UART1_Init(4800)

while (1) { UART1_Write(a) Delay_ms(1000)

}

}

Програму легко перевірити за компютером:

Рис 5321 Перевірка програми відправлення запиту

І прийшов час зєднати два мікроконтролера, щоб промоделювати їх спільну роботу

Рис 5322 Моделювання спільної роботи двох мікроконтролерів

Спочатку я хотів відрізати саморобний далекомір на платформу робота, але по деякому роздумів вирішив, що для мене це тільки додаткові механічні роботи, а вам буде цікавіше самостійно перевірити всі з реальним макетуванням

Звичайно, було б ще цікавіше постачити робота, скажімо, сервоприводом, на платформі якого зміцнити додатковий датчик, що дозволило б роботу «оглядати» околиці з великим успіхом

Ймовірно, фабричний датчик відстані працює краще, але саморобний, погодьтеся, дешевше Але й не це головне Головне, проводячи експерименти, ви краще зрозуміли, як працюють такі датчики, як можна самостійно поставити завдання і вирішити її, слідуючи плану, який ви самі написали, самі ж і виконали

Одне зауваження: якщо вас не влаштовує напругу в 200 мВ, то можна, використовуючи вбудоване опорна напруга і дільник з двох резисторів привести напруга до потрібного значення Спробуйте це зробити хоча б за компютером, ви краще зрозумієте, як працювати з вбудованими компараторами і джерелом опорного напруги

Два мікроконтролера, використані при експериментах, виконують кожен свою задачу У найпростішому випадку можна було здійснити всі, використовуючи один мікроконтролер Але не завжди переривання виконуваної мікроконтролером роботи, щоб виконати інше завдання, можливо У подібних ситуаціях другий мікроконтролер може взяти на себе виконання другого завдання Мікроконтролери, як ми це зробили вище, можна зєднати по UART, але в простих ситуаціях можна використовувати зєднання (у нашому випадку ми могли це зробити) висновків порту для обміну інформацією Наприклад, ми могли б поєднати вихід другого мікроконтролера з входом першого Стан виходу другого мікроконтролера відповідало б стану прапора (використаного в прикладі), а станом виходу перший контролер міг легко визначити все, що йому було б потрібно Варіантів, як зробити те чи інше, зазвичай буває достатньо багато Залишається тільки вибрати підходящий

Джерело: Гололобов ВН, – Самовчитель гри на паяльнику (Про електроніці для школярів і не тільки), – Москва 2012