Prezentuję poniżej kod źródłowy sonaru (nie uwzględniam tu plików biblioteki Procyon AVRlib).
Plik sonar.c:
//#############################
//
// Sonar ultradźwiekowy
//
//#############################
#include <avr/io.h>
#include "deprecated.h"
#include "sonar.h"
#include "znaki.h"
#include <avr/interrupt.h>
#include <util/delay.h>
#include "i2c.h"
#define wait 0xffff
int distance=0;
int idx; //zmienna uzyta w petli w funkcji wynik
unsigned int TicksNo[42] = {10,20,50,85,120,150,170, //3...30cm
220,240,280,315,335,375, //35...60cm
400,440,460,500,530,560, //65...90cm
600,630,660,690,720,760, //95...120cm
790,820,850,885,910,945, //125...150cm
970,1010,1050,1080,1115, //155...175cm
1150,1180,1210,1240,1270, //180...200cm
1300}; //troche ponad 2m
unsigned short DisplayChars0[42] = {0,0,1,1,2,2,3,3, //03...35cm
4,4,5,5,6,6,7,7, //40...75cm
8,8,9,9,0,0,1,1, //80...115cm
2,2,3,3,4,4,5,5, //120...155cm
6,6,7,7,8,8,9,9, //160...195cm
0,10}; //200...troche ponad 200
unsigned char DisplayChars1[42] = {3,5,0,5,0,5,0,5, //03...35cm
0,5,0,5,0,5,0,5, //40...75cm
0,5,0,5,0,5,0,5, //80...115cm
0,5,0,5,0,5,0,5, //120...155cm
0,5,0,5,0,5,0,5, //160...195cm
0,10}; //200...troche ponad 200
unsigned char digits[11] = {
((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDF)),
((1<<LEDB)|(1<<LEDC)),
((1<<LEDA)|(1<<LEDB)|(1<<LEDD)|(1<<LEDE)|(1<<LEDG)),
((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDG)),
((1<<LEDB)|(1<<LEDC)|(1<<LEDF)|(1<<LEDG)),
((1<<LEDA)|(1<<LEDC)|(1<<LEDD)|(1<<LEDF)|(1<<LEDG)),
((1<<LEDA)|(1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG)),
((1<<LEDA)|(1<<LEDB)|(1<<LEDC)),
((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG)),
((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDF)|(1<<LEDG)),
(1<<LEDG) //kreska pozioma
};
unsigned char DisplayedChar[2];
unsigned char Com[2] = {~(1<<COM1),~(1<<COM2)};
//
//############################################################
//
//-------------------------
//
// procedura wysyłania paczki ultradźwięków
//
//-------------------------
int sygnal(void)
{
int echos=0; // zmienna do bliczenia powrotu ultradźwięków
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
// teraz trzeba wytłumić drgania przetwornika zwierając go do masy
cbi(ultrasonic_pinA_port,ultrasonic_pinA_pin);
cbi(ultrasonic_pinB_port,ultrasonic_pinB_pin);
delay(8);
// przetwornik wejściowy też zwieramy do masy w celu wytłumienia
sbi(DDRD,PD6);
cbi(PORTD,PD6);
delay(8);
cbi(DDRD,PD6); // no i można go włączyć
for(echos=0;echos<2500;echos++) // i czekać na odbite dźwięki
{
if(bit_is_set(ACSR,ACO)) // jeżeli bit ACO rejestru ACSR ustawiony
{
break; // to przerwij
}
}
return echos; // zwróć wartość zmiennej
}
//-------------------------
//
// procedura sygnału 40kHz
//
//-------------------------
void sinus_40_khz(void)
{
sbi(ultrasonic_pinA_DDR,ultrasonic_pinA_pin);sbi(ultrasonic_pinA_port,ultrasonic_pinA_pin);
sbi(ultrasonic_pinB_DDR,ultrasonic_pinB_pin);cbi(ultrasonic_pinB_port,ultrasonic_pinB_pin);
asm volatile("WDR"::); //watchdog reset, czyli nic nie rób.
asm volatile("WDR"::);
asm volatile("WDR"::);
asm volatile("WDR"::);
cbi(ultrasonic_pinA_port,ultrasonic_pinA_pin);
sbi(ultrasonic_pinB_port,ultrasonic_pinB_pin);
asm volatile("WDR"::);
asm volatile("WDR"::);
}
//-----------------------------------------------------
//
// procedura wyswietlajaca wynik na wyswietlaczach LED
//
//-----------------------------------------------------
void result(void)
{
idx = 0;
while(distance > TicksNo[idx])
idx++;
if(idx>41) //wieksza odleglosc niz 2m z hakiem
{
DisplayedChar[0]=0;
DisplayedChar[1]=0;
_delay_loop_2(wait);
}
else //w mierzonym zakresie
{
DisplayedChar[0]=digits[DisplayChars0[idx]];
DisplayedChar[1]=digits[DisplayChars1[idx]];
if(idx>19 && idx<40) //miedzy 1m a 2m
DisplayedChar[0] = DisplayedChar[0] | mdp; //dodaj kropke
if(idx==40) // 2m
DisplayedChar[1] = DisplayedChar[1] | mdp; //dodaj kropke
_delay_loop_2(wait);
}
}
//-----------------------------------------------------
//
// MAIN
//
//-----------------------------------------------------
int main(void)
{
//inicjalizacja i2c - na razie nie uzywana...
i2cInit();
i2cSetBitrate(10);
sbi(DDRD,PD7);
cbi(PORTD,PD7);
LEDDDR=0xff;
COMDDR=((1<<COM1)|(1<<COM2));
TCCR0 = 1<<CS01|1<<CS00;//preskaler 64//
TIMSK = 1<<TOIE0;
sei();
for(;;)
{
distance = sygnal();
result();
}
return(0);
}
//-----------------------------------------------------
//
// PRZERWANIE
//
//-----------------------------------------------------
SIGNAL(SIG_OVERFLOW0)
{
static int ActiveDisplay = 0;
TCNT0=128;
COMPORT &= ~(1<<COM1 | 1<<COM2); ///zerowanie wyswietlacza
LEDPORT = DisplayedChar[ActiveDisplay]; ///wysylanie znaku
COMPORT |= (Com[ActiveDisplay]); ///wlaczenie wyswietlacza
++ActiveDisplay; /// wlaczanie kolejnego wyswietlacza
if(ActiveDisplay > 1)
{
ActiveDisplay = 0;
}
}
Plik sonar.h:
//najpierw pin do którego podłączamy pierwszy kabelek
#define speaker_pinA_port PORTC
#define speaker_pinA_pin PC4
#define speaker_pinA_DDR DDRC
//pin kabelka 2
#define speaker_pinB_port PORTC
#define speaker_pinB_pin PC5
#define speaker_pinB_DDR DDRC
// definicja ultradzwiekowego nadajnika
#define ultrasonic_pinA_port PORTD
#define ultrasonic_pinA_pin PD0
#define ultrasonic_pinA_DDR DDRD
//drugi pin
#define ultrasonic_pinB_port PORTD
#define ultrasonic_pinB_pin PD1
#define ultrasonic_pinB_DDR DDRD
//diody//
#define LED4_ON sbi(DDRD,PD5);sbi(PORTD,PD5);
#define LED4_OFF sbi(DDRD,PD5);cbi(PORTD,PD5);
#define LED3_ON sbi(DDRD,PD4);sbi(PORTD,PD4);
#define LED3_OFF sbi(DDRD,PD4);cbi(PORTD,PD4);
#define LED2_ON sbi(DDRD,PD3);sbi(PORTD,PD3);
#define LED2_OFF sbi(DDRD,PD3);cbi(PORTD,PD3);
#define LED1_ON sbi(DDRD,PD2);sbi(PORTD,PD2);
#define LED1_OFF sbi(DDRD,PD2);cbi(PORTD,PD2);
// Procedury opóźnień czasowych
#define CYCLES_PER_US ((1000000+500000)/1000000)
void delay(unsigned int us)
{
unsigned int delay_loops;
register unsigned int i;
delay_loops=((us+3)/5*CYCLES_PER_US)*10;
for(i=0;i<delay_loops;i++){};
}
void delayms(unsigned int ms)
{
unsigned int i;
for(i=0;i<ms;i++)
{
delay(999);
asm volatile("WDR"::);
}
}
//prototypy funkcji i procedur
void delay(unsigned int us);
void delayms(unsigned int ms);
int sygnal(void);
void sinus_40_khz(void);
Plik znaki.h:
/////////////////////////////////////////////////////
////////Definicje polączenia wyświetlaczy 7 segm/////
////////i definicje znaków wyswietlanych/////////////
////////ZDEFINIOWANE ZNAKI://////////////////////////
///0-9; a,b,c,d,e,f,h,i,j,l,n,o,p,r,u////////////////
/////////////////////////////////////////////////////
///definicje klawiszy///
#define SWPORT PORTC
#define SWDDR DDRC
#define SWPIN PINC
#define SW1 2
#define SW2 3
////definicje podłączonych segmentów/////
#define LEDPORT PORTB
#define LEDDDR DDRB
#define LEDA 2
#define LEDB 1
#define LEDC 7
#define LEDD 0
#define LEDE 5
#define LEDF 3
#define LEDG 4
#define LED_DP 6
////definicje podłączonych wspólnych anod////
#define COMPORT PORTC
#define COMDDR DDRC
#define COM1 0
#define COM2 1
////definicje znaków wyświetlanych na wyświetlaczu////
#define mnul 0;//kasowanie wyswietlacza//
#define m0 ((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDF));
#define m1 ((1<<LEDB)|(1<<LEDC));
#define m2 ((1<<LEDA)|(1<<LEDB)|(1<<LEDD)|(1<<LEDE)|(1<<LEDG));
#define m3 ((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDG));
#define m4 ((1<<LEDB)|(1<<LEDC)|(1<<LEDF)|(1<<LEDG));
#define m5 ((1<<LEDA)|(1<<LEDC)|(1<<LEDD)|(1<<LEDF)|(1<<LEDG));
#define m6 ((1<<LEDA)|(1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG));
#define m7 ((1<<LEDA)|(1<<LEDB)|(1<<LEDC));
#define m8 ((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG));
#define m9 ((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDF)|(1<<LEDG));
#define mdip (1<<LEDG); // myslnik//
#define mdp (1<<LED_DP); //kropka//
#define mA ((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG));
#define mB ((1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG));
#define mC ((1<<LEDD)|(1<<LEDE)|(1<<LEDG));
#define mD ((1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDG));
#define mE ((1<<LEDA)|(1<<LEDD)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG));
#define mF ((1<<LEDA)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG));
#define mH ((1<<LEDC)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG));
#define mI ((1<<LEDE)|(1<<LEDF));
#define mJ ((1<<LEDA)|(1<<LEDB)|(1<<LEDC)|(1<<LEDD)|(1<<LEDE));
#define mL ((1<<LEDD)|(1<<LEDE)|(1<<LEDF));
#define mN ((1<<LEDC)|(1<<LEDE)|(1<<LEDG));
#define mO ((1<<LEDC)|(1<<LEDD)|(1<<LEDE)|(1<<LEDG));
#define mP ((1<<LEDA)|(1<<LEDB)|(1<<LEDE)|(1<<LEDF)|(1<<LEDG));
#define mR ((1<<LEDE)|(1<<LEDG));
#define mU ((1<<LEDC)|(1<<LEDD)|(1<<LEDE));