// Макросы
#define HIGH_P(port, num) ( port |= (1 ‹‹ num) ) // 1. Высокий уровень
#define LOW_P(port, num) ( port &= ~(1 ‹‹ num) ) // 0. Низкий уровень
#define OUT_P(port, num) ( port |= (1 ‹‹ num) ) // Выход
#define IN_P(port, num) ( port &= ~(1 ‹‹ num) ) // Вход
#define SCAN_P(port, num) ( port & (1 ‹‹ num) ) // Поступает ли сигнал на порт
// Датчик растояния
//=============================
#define HC_Trig_PORT PORTE
#define HC_Trig_DDR DDRE
#define HC_Trig_PIN PINE
#define HC_Trig_PINn 7
//=============================
// частота МК
#define F_CPU 16000000UL
// Тик на 1мкс
#define quant_t2_prescaler (1 ‹‹ CS20) // Предделитель
#define quant_t2_start TCNT2 = 0xF0; TCCR2 |= quant_t2_prescaler // Запуск
#define quant_t2_stop TCNT2 = 0xF0; TCCR2 &= ~(quant_t2_prescaler) // Остановка
//==============
#include ‹avr/io.h›
#include ‹avr/interrupt.h›
#include ‹avr/delay.h›
// Отслеживаем дистанцию
char high_HC_int = 0; // Изначально на ножке нет сигнала. Значит false
unsigned int HC_time_us = 0; // Считаем время
float HC_dist = 0; // Дистанция
// Прерывание INT6 по смене напряжения
ISR(INT6_vect) {
high_HC_int = ~high_HC_int;
}
// Таймер 2
ISR(TIMER2_OVF_vect) {
TCNT2 = 0xF0;
HC_time_us++;
}
// Отслеживаем дистанцию
char HC_time(void) {
unsigned int loopCnt = 0;
// Сбрасываем
HC_time_us = 0;
high_HC_int = 0;
// Подаем импульс на вход trig дальномера
HIGH_P(HC_Trig_PORT, HC_Trig_PINn);
// Равный 10 микросекундам
_delay_us(10);
// Отключаем
LOW_P(HC_Trig_PORT, HC_Trig_PINn);
// Ждем, пока придет high сигнал
while(!high_HC_int) {
if(loopCnt++ == 20000) { // Время истекло
return 0;
}
}
// Начинаем считать
quant_t2_start;
while(high_HC_int) {
if(HC_time_us › 3000) {
break;
}
}
quant_t2_stop;
return 1;
}
int main(void) {
/*
PE.4 - Светодиод 1
PE.5 - Светодиод 2
PE.6 - Ножка датчика расстояния Echo (INT6)
PE.7 - Ножка датчика расстояния Trig
*/
// Настройка портов вывода-вывода
//==========================
DDRE = (1 ‹‹ DDE7) | (0 ‹‹ DDE6) | (1 ‹‹ DDE5) | (1 ‹‹ DDE4) | (0 ‹‹ DDE3) | (0 ‹‹ DDE2) | (0 ‹‹ DDE1) | (0 ‹‹ DDE0);
//==========================
// Таймеры
//==========================
// Таймер 2
TCCR2 = (0 ‹‹ WGM20) | (0 ‹‹ COM21) | (0 ‹‹ COM20) | (0 ‹‹ WGM21) | (0 ‹‹ CS22) | (0 ‹‹ CS21) | quant_t2_prescaler;
TCNT2 = 0xF0;
OCR2 = 0x00;
quant_t2_stop;
// Прерывания Таймеров/Счетчикков
TIMSK = (0 ‹‹ OCIE2) | (1 ‹‹ TOIE2) | (0 ‹‹ TICIE1) | (0 ‹‹ OCIE1A) | (0 ‹‹ OCIE1B) | (0 ‹‹ TOIE1) | (0 ‹‹ OCIE0) | (0 ‹‹ TOIE0);
//==========================
// Прерывания
//==========================
EICRA = (0 ‹‹ ISC31) | (0 ‹‹ ISC30) | (0 ‹‹ ISC21) | (0 ‹‹ ISC20) | (0 ‹‹ ISC11) | (0 ‹‹ ISC10) | (0 ‹‹ ISC01) | (0 ‹‹ ISC00);
EICRB = (0 ‹‹ ISC71) | (0 ‹‹ ISC70) | (0 ‹‹ ISC61) | (1 ‹‹ ISC60) | (0 ‹‹ ISC51) | (0 ‹‹ ISC50) | (0 ‹‹ ISC41) | (0 ‹‹ ISC40);
EIMSK = (0 ‹‹ INT7) | (1 ‹‹ INT6) | (0 ‹‹ INT5) | (0 ‹‹ INT4) | (0 ‹‹ INT3) | (0 ‹‹ INT2) | (0 ‹‹ INT1) | (0 ‹‹ INT0);
EIFR = (0 ‹‹ INTF7) | (1 ‹‹ INTF6) | (0 ‹‹ INTF5) | (0 ‹‹ INTF4) | (0 ‹‹ INTF3) | (0 ‹‹ INTF2) | (0 ‹‹ INTF1) | (0 ‹‹ INTF0);
//==========================
sei();
while(1) {
if(HC_time()) {
HC_dist = (float)HC_time_us / 58.00;
if(HC_dist ‹ 10) {
HIGH_P(PORTE, 5);
} else {
LOW_P(PORTE, 5);
}
}
_delay_ms(50);
}
} |