В ихідний код програми мікроконтролера
Керуюча
програма була написана мовою
С
у програмному середовищі Atmel Studio 6.
Далі
показано вихідний код програми
мікроконтролера
Main.c:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> //!!!
#include <stdio.h>
#include "LCD.h" // бібліотека для роботи із LCD дисплеєм
#include "hc_sr04.h" // бібліотека для роботи із акустичним датчиком
#define MODE_SPEEDMETER 1
#define MODE_DISTANCE_METER 0
unsigned char mode_ = 0;
// обробка натискання кнопки зміни режиму
ISR (INT1_vect)
{
if ( mode_ == MODE_SPEEDMETER )
{
mode_ = MODE_DISTANCE_METER;
}
else
{
mode_ = MODE_SPEEDMETER;
}
}
// виведення чисел типу float на дисплей
void float_to_string ( float a , char *mass) // ( float_число , рядок_у_який_повертаємо )
{
int res_integer = 0; // ціла частина числа
int res_drob = 0; // дробова частина числа
res_integer = (int)(a);
a = a - (float)res_integer;
a = a*100;
res_drob = (int)a;
if ( res_drob < 0)
{
res_drob = -res_drob;
};
if ( a < 0 && -1 < res_integer && res_integer < 1 )
sprintf( mass , "speed:-%d.%d m/s" , res_integer , res_drob );
else
sprintf( mass , "speed:%d.%d m/s" , res_integer , res_drob );
}
//ініціалізація
переривання
void init_interp_button (void)
{
MCUCR |=(1<<ISC11); //по будь-якому фронту
GICR |= (1<<INT1); //на INT1
}
int main(void)
{
DDRB |= (1<<0);
PORTB |= (1<<0);
LCDinit();
HC_SRC4_Init();
init_interp();
init_interp_button();
sei();
char personal_string[10];
LCDclear();
int distance_start = 0;
int distance_end = 0;
unsigned int time = 0;
volatile float result = 0;
while(1)
{
if ( mode_ == MODE_DISTANCE_METER)
{
_delay_ms(500);
sprintf (personal_string , "distance = %dcm " , (int)HC_SRC4_Get_CM());
LCDstring( personal_string , 0 , 0);
}
else
{
_delay_ms(250);
distance_start = (int)HC_SRC4_Get_CM();
_delay_ms(150);
distance_end = (int)HC_SRC4_Get_CM();
result = distance_end - distance_start;
if ( result == 0)
{
asm("nop");
LCDclear();
sprintf (personal_string , "speed: 0 m/s ");
}
else
{
result = result / 5;
float_to_string( result , personal_string );
LCDclear();
};
};
}
}
h
c_sr04.h:
//ніжка Echo
#define Echo_PORT PORTD
#define Echo_DDR DDRD
#define Echo_PIN PIND
#define Echo_N 2
//ніжка Trig
#define Trig_PORT PORTD
#define Trig_DDR DDRD
#define Trig_PIN PIND
#define Trig_N 1
//ініціалізація ніжок для роботи із датчиком
void HC_SRC4_Init (void)
{
//Налаштування ніжок
Trig_DDR |= 1<<Trig_N;
Trig_PORT &= ~(1<<Trig_N);
Echo_DDR &= ~(1<<Echo_N);
Echo_PORT &= ~(1<<Echo_N);
}
// строб імпульс
void HC_SRC4_Send_strob (void) {
Trig_PORT |= 1<<Trig_N; // ЛОГ 1
_delay_us(11);
Trig_PORT &= ~(1<<Trig_N); // ЛОГ 0
}
//ініціалізація переривання для роботи із датчиком
void init_interp (void)
{
MCUCR |=(1<<ISC00); //По будь-якому фронту
GICR |= (1<<INT0); // на INT0
}
#define Start 1
#define Stop 0
//функція запуску і зупинки таймера
unsigned int timer_Start_Stop (char flag)
{
unsigned int rez; // збереження кількості тактів
unsigned short int buff[2];
if (flag)
{
TCNT1H = 0;
TCNT1L = 0;
TCCR1B |=(1<<CS11); //запуск таймера із діленням 8
}
else
{
TCCR1B &= ~(1<<CS11); //Зупинка таймера
buff[0] = TCNT1L;
buff[1] = TCNT1H;
rez = buff[1];
rez <<= 8;
rez |= buff[0];
return rez;
}
return 0;
}
//такти таймера у відстань
unsigned int HC_SRC4_Convert_CM (unsigned int N_t)
{
unsigned long int C ;
if (N_t > 2900)
{
return (unsigned int) 0;
};
C = N_t * 8; //час імпульса = кількість тактів таймера * 8
C /= 58; // відстань у сантиметрах
return (unsigned int) C;
}
unsigned int N_takt=0;
//переривання обробки довжини імпульсу
ISR (INT0_vect)
{
if (Echo_PIN & (1<<Echo_N)) //зростаючий фронт
timer_Start_Stop (Start);
else //спадаючий фронт
N_takt = timer_Start_Stop (Stop); }
// функція визначає і повертає відстань
unsigned int HC_SRC4_Get_CM (void)
{
HC_SRC4_Send_strob();
_delay_ms(25);
return HC_SRC4_Convert_CM (N_takt); //повернення значення у СМ
}
