Gdzie jest blad ?? A moze go nie ma !?



Masz problem? Zapytaj na forum elektroda.pl

Poprzedni Następny
Wiadomość
Spis treści
From: "Bushi" <pxe_at_nospam_poczta.onet.pl>
Subject: Gdzie jest blad ?? A moze go nie ma !?
Date: Sat, 11 Jun 2005 10:35:24 +0200


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 !!