Mam taki ma³y problem. realizuje projekt na swoich studiach, który polega na realizacji lokalizatora opartego na przetwornikach ultradzwiekowych. Uklad uz zbudowalem, program pod ATMeg'e8 napisalem i wgralem. Caly projekt polega na tym ze nadajnik umieszczony w jakims dowolnym miejscu sceny nadeje sygnal (nadawany jest sygnal rownu, przynajmniej teoretycznie 40kHz; nad nadajnikiem umieszczony jest storzek zrobiony z metalu ktory rozprasza fale dzwiêkow±), zostaje wyzerowany TIMER1. "S³ysz±ce" go odbiorniki (atmega 8 ma tylko 1 komparatro wiec uzylem multipleksera 4051BE zeby przelanczac poszczegolne sonarki) odbiraja sygnal i w tym momenci zostaje zczytany czas jaki uplynal od momentu nadania fali i przekazany do wyslania za pomoca rs232. Wszystko chodzi, ale jest maly problem zwiazany z tym ze przesylane czasy wogole maja sie nijka do tego jak ustawiony jest nadajnik - wychodzi na to ze nadajnik (za kazdym razem, niezaleznie od tego gdzie jest ustawiony nadajnik) jest w tej samej odlegolosci od wszystkich odbiornikow. Jesli ktos tylko mogl by mi pomoc to bardzo chetnie z pomocy skorzystam !!. Do postu przesylam kod programu ktory napisalem (sory ze taki dlogi ale najlepiej bedzie jak wkleje wszystko zeby pozniej nie bylo niepotrzebnych pytan :] ).
#include <avr/io.h>
#include <avr/timer.h>
#include <avr/interrupt.h>
//#include <inttypes.h>
#include "biblioteka.h" #include "funkcje.c"
/* Mikroprocesory ATMega8 maja fabrycznie wylaczone przerwania */ /*--------------------------------------------------------------------------
-*/ // Projekt wykonany przez studentow IV ARR: // Tchórz Marek - autor i pomyslodawca oprogramowania mikroprocesora; // Korys Bart³omiej - zwany "zwichnieta raczka",zlutowal uk³ad tak jak tylko // potrafil; /*--------------------------------------------------------------------------
-*/ /* Funkcja generujaca fale sinusoidalna o danej czestotliwosci */ void sinus_40_khz(void) { sbi(DDRC,PC0);sbi(PORTC,PC0); sbi(DDRC,PC1);cbi(PORTC,PC1); // teraz czekamy po³owê okresu sinosoidy asm volatile ( "WDR"::); asm volatile ( "WDR"::); asm volatile ( "WDR"::); asm volatile ( "WDR"::);
cbi(PORTC,PC0); sbi(PORTC,PC1); // teraz czekamy nieco krócej jak okres po³owy sinusoidy bo procesor potrzebuje // nieco czasu na powrót z tej procedury i ponowne do niej wej¶cie - dopiero // wtedy rozpocznie kolejn± sinusoidê asm volatile ( "WDR"::); asm volatile ( "WDR"::); }
/*--------------------------------------------------------------------------
-*/ /* Funkcja pozwalajaca na zliczenie czasu jaki uplynie od nadania dzwieku przez nadajnik ultradzwiekowy do odebrania tego dzwieku przez odbiornik
*/ unsigned int czas_po_nadaniu(int ktory_odbior) { unsigned int echo = 0; // zmienna odpowiedzialna za czas rowny dojsciu fali // do obiornika switch(ktory_odbior) { case 0: sbi(DDRD,PD5);cbi(PORTD,PD5);//przelaczenie w multiplekserze na wejcie 0 sbi(DDRD,PD4);cbi(PORTD,PD4); break; case 1: sbi(DDRD,PD5);cbi(PORTD,PD5);//przelaczenie w multiplekserze na wejcie 1 sbi(DDRD,PD4);sbi(PORTD,PD4); break; case 2: sbi(DDRD,PD5);sbi(PORTD,PD5);//przelaczenie w multiplekserze na wejcie 2 sbi(DDRD,PD4);cbi(PORTD,PD4); break; case 3: sbi(DDRD,PD5);sbi(PORTD,PD5);//przelaczenie w multiplekserze na wejcie 3 sbi(DDRD,PD4);sbi(PORTD,PD4); break; }
outp((1<<TOV1),TIFR); // Jesli flaga TOV1(przepelnienie timera) jest ustawiona // na 1 to wyzeruj- to tak dla pwnosci ale pewenie niepotrzene TCNT1 = 0; // Wyzerowanie stanu timer'a 16-bitowego
// Wysy³anie paczki ultrad¼wiêków o czestotliwosci 40kHZ 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();
// po wys³aniu paczki ultrad¼wiêków wyt³umiamy drgania przetwornika (nadajnika) // zwieraj±c je do masy cbi(PORTD,PD0); // zwarcie jednego nozki cbi(PORTD,PD1); // zwarcie drugiej nozki delay(8);
sbi(DDRD,PD6); cbi(PORTD,PD6); //rozladowujemy pojemno¶æ przetwornika wej¶ciowego poprzez //zwarcie do masy delay(8);
cbi(DDRD,PD6); // ustawiamy jako wej¶cie pin do ktorgo podpieta jest jedna z // nozek odbiornika ultradzwiekowego. do { echo = TCNT1;// dopoki nie przyjdzie echo zmiennej przypisuje wartosc // 16-bit timera } while(bit_is_clear(ACSR,ACO)); // jesli w rejestrze ACSR //w miejscu ACO pojawi sie 1, to znaczy ze echo doszlo do odbiornika
return (echo); // zwracam jako wynik czas jaki uplynal od nadania dzwieku // do odebrania }
/*--------------------------------------------------------------------------
-*/ // GLOWNY KOD PROGRAMU /*--------------------------------------------------------------------------
-*/ int main (void) { Rs_Init(); // inicjalizacja wysylania danych RS232 wraz z paramtrami wysylania
unsigned int czas_0,czas_1,czas_2,czas_3;
sbi(DDRD,PD7); // ustawiam port D, pin 7 jako wyjsciowy cbi(PORTD,PD7);// zwieramy nieodwracaj±ce wej¶cie komparatora do masy podajac stan "0"
outp(0, TCCR1A); // ustawienie TCCR1A na 0 - nie wiem dlaczego ale tak bylo w dokumentacji outp(1, TCCR1B); // ustawienie preskalera na wartosc 1 czyli bez skalowania
for (;;) // nieskonczenie trwajaca petla { czas_0 = 0; czas_1 = 0; czas_2 = 0; czas_3 = 0; sbi(DDRD,PD2); // ustawiamy pin drugi portu D jako pin wyjsciowy sbi(PORTD,PD2); // ustawiamy pin na stan wysoki delay(5); // dajemy 5 mikrosekund na prze³adowanie cbi(DDRD,PD2); // teraz prze³±czamy piny w tryb pracy jako wej¶cia
loop_until_bit_is_clear(PIND,klawisz_s1_pin);// nie rob nic dopoki klawisz // nie zostanie wcisniety; delayms(200); czas_0 = czas_po_nadaniu(0); delayms(200); czas_1 = czas_po_nadaniu(1); delayms(200); czas_2 = czas_po_nadaniu(2); delayms(200); czas_3 = czas_po_nadaniu(3); delayms(100);
while ( !(UCSRA & (1<<UDRE)) ); // czeka na pusty bufor transmisji UDR = czas_0; // wysyla dane while ( !(UCSRA & (1<<UDRE)) ); // czeka na pusty bufor transmisji UDR = czas_1; // wysyla dane while ( !(UCSRA & (1<<UDRE)) ); // czeka na pusty bufor transmisji UDR = czas_2; // wysyla dane while ( !(UCSRA & (1<<UDRE)) ); // czeka na pusty bufor transmisji UDR = czas_3; // wysyla dane
} // to narazie tyle, jeszcze przesylanie do twojego programu (i pozbywszy sie kilku) problemow // sprzetowych jakie znowu napotkalem !!! powinno zadzialac.Makefila nie masz co kapowac // bo to tylko kapuja orly i wogole to jest czarna magia. jak cos to widzimy sie jutro !! //Pozdro i sory ze tak pozno chociaz i tak pwenie siedziales nad protokolami !!
return(0); }
A i jeszcze pytanie: czy flage AOC w rejestrze ACSR trzeba zerowac samemu czy robi sie to samocznnie (wiem ze wszystko jest w dokumentacji ale ja nie za dobrze spiku po polskiemu a co dopiero po nagielskiemu :) )?? Za wszelko pomoc dziekuje - pozdrawiam Bushi !!