logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Czy ten program jest poprawny

Ligi 22 Paź 2009 19:24 2576 6
  • #1 7161961
    Ligi
    Poziom 11  
    Witam mam mały problemik, napisałem program w C++ a znaczy dopisałem troszke do juz istniejącego i nie wiem czy jest od poprawny. Nie jestem dobry w tym języku a niestety musę w nim napisać program.

    Zasada działania programu:

    1. Wysyłamy pierwszą paczkę ultradźwięków => int sygnal(void)
    2. Odbieramy pierwszą paczkę ultradźwięków => void sinus_40_khz(void)
    3. Wysyłamy drugą paczkę ultradźwięków => int sygnal_1(void)
    4. Odbieramy drugą paczkę ultradźwięków => void sin_40_khz(void)
    5. Porównujemy odebrana pierwszy sygnał z odebranym drugim
    6. Jeżeli pierwszy sygnał jest większy od drugiego tzn. że auto się zbliżyło do nas
    I teraz badamy w którym z trzech podzakresów auto się znajduje.
    Jeżeli w najbliższym to zapalamy diodę nr 1(czerwona-nie wolno wyprzedzać i uruchamiamy brzęzek)
    Jeżeli w środkowym to zapalamy diodę nr 2(żółta- trzeba uważać) Jeżeli w najdalszym to zapalamy diodę nr 3(zielona- bezpieczna odległość)



    To co pogrubione to ja dodawałem tak aby program działał według powyższego schematu
    Na ukos to jest jakieś przerwanie do wyświetlaczy, ja takich nie mam więc chyba to mi nie potrzebne?

    //sonar ultradźwiękowy
    #include <avr/io.h>
    #include "deprecated.h"
    #include "sonar_luki.h"
    #include <avr/interrupt.h>
    #include <util/delay.h>

    #define wait 0xffff
    int odleglosc=0;
    int odleglosc_1=0
    unsigned int zoom[6] = {10,20,50,85,120,200};
    unsigned char Com[2] = {~(1<<COM1),~(1<<COM2)};


    int sygnal(void) // procedura wysyłania paczki ultradźwięków
    {
    int echo=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(echo=0;echo<300;echo++) // i czekać na odbite dźwięki
    {
    if(bit_is_set(ACSR,ACO)) // jeżeli bit ACO rejestru ACSR ustawiony
    {
    break; // to przerwij
    }
    }
    return echo; // zwróć wartość zmiennej
    }

    void sinus_40_khz(void) // procedura sygnału 40kHz
    {
    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":: );
    }

    int sygnal_1(void) // procedura wysyłania paczki ultradźwięków
    {
    int echo=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(echo=0;echo<300;echo++) // i czekać na odbite dźwięki
    {
    if(bit_is_set(ACSR,ACO)) // jeżeli bit ACO rejestru ACSR ustawiony
    {
    break; // to przerwij
    }
    }
    return echo; // zwróć wartość zmiennej
    }

    void sin_40_khz(void) // procedura sygnału 40kHz
    {
    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":: );
    }


    void Wynik(void)
    {

    if(odleglosc>odleglos_1)
    {

    if(odleglosc_1<zoom[2])
    {
    LED1_ON;
    beep(20,100);
    _delay_loop_2(wait);
    LED1_OFF;
    }
    else
    if(odleglosc<zoom[4])
    {
    LED2_ON;
    _delay_loop_2(wait);
    LED2_OFF;
    }
    else
    if(odleglosc<zoom[5])
    {
    LED3_ON;
    _delay_loop_2(wait);
    LED3_OFF;
    }
    else
    {
    LED1_OFF;LED2_OFF;LED3_OFF;
    _delay_loop_2(wait);
    }
    }
    else
    if(odleglosc<odleglosc_1)
    {
    LED3_ON;
    _delay_loop_2(wait);
    LED3_OFF;
    }

    }


    int main(void)
    {

    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(;; )
    {
    odleglosc=sygnal();
    odległość_1=sygnal_1() //odległość druga ta z która porównujemy sygnal
    Wynik();
    }
    return(0);
    }



    //przerwanie
    SIGNAL(SIG_OVERFLOW0)
    {
    static int AktWyswietlacz = 0;
    TCNT0=128;
    COMPORT &= ~(1<<COM1 | 1<<COM2); ///zerowanie wyswietlacza
    LEDPORT = ZnakWyswietlacza[AktWyswietlacz]; ///wysylanie znaku
    COMPORT |= (Com[AktWyswietlacz]); ///wlaczenie wyswietlacza
    ++AktWyswietlacz; /// wlaczanie kolejnego wyswietlacza
    if(AktWyswietlacz>1)
    {
    AktWyswietlacz = 0;

    }

    }






    A to jest sonar_luki.h w którym definiuje dane:

    //najpierw pin do którego podłączamy pierwszy kabelek
    #define speaker_pinA_port PORTC
    #define speaker_pinA_pin PC2
    #define speaker_pinA_DDR DDRC
    //pin kabelka 2
    #define speaker_pinA_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 LED3_ON sbi(DDRD,PC2);sbi(PORTD,PC2);
    #define LED3_OFF sbi(DDRD,PC2);cbi(PORTD,PC2);

    #define LED2_ON sbi(DDRD,PC3);sbi(PORTD,PC3);
    #define LED2_OFF sbi(DDRD,PC3);cbi(PORTD,PC3);

    #define LED1_ON sbi(DDRD,PC4);sbi(PORTD,PC4);
    #define LED1_OFF sbi(DDRD,PC4);cbi(PORTD,PC4);

    // 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);
    int sygnal_1(void);
    void sinus_40_khz(void);
    void sin_40_khz(void);
    void beep(unsigned int freq,unsigned int duration);
  • #2 7162862
    janbernat
    Poziom 38  
    A skompilowałeś ten program?
    To trochę wygląda na ATMega8 - ale nie jestem pewien.
    Ale sygnały z mikrofonu (niesłusznie opisane przez Ciebie jako nadajnik) wchodzą na RXD i TXD.
    A ten odbiornik (mikrofon) wcale nie wchodzi na PD.6 i PD.7 -więc jak komparator zobaczy przerwanie.
    Ale paru ciekawych spraw się z Twojego postu dowiedziałem.
  • #3 7162948
    tmf
    VIP Zasłużony dla elektroda
    Po czym wnioskujesz, ze to program napisany w C++?
    Uzywasz jakiejs prehistorycznej wersji Win-AVR, WDR jako opoznienie to raczej kiepski pomysl, nic nie rob ma mnemonik "NOP". Twoja funkcja wcale nie generuje 40kHz, calosc jest pokrecona jak swinski ogonek, jak myslisz po co funkcje moga przyjmowac parametry inne niz void?
    Twoje procedury opoznien sa OKDR, bo zadnych opoznien nie generuja (hint: optymalizacja), chyba, ze kompilujesz to z -O0.
    Mam nadzieje, ze odbiornik piezo masz podlaczony przez jakis op-amp, bo inaczej sprawdzanie stanu portu to spory optymizm z twojej strony.
    Najlepiej skasuj to co splodziles, poczytaj o timerach i napisz to jeszcze raz.
  • #4 7163173
    Ligi
    Poziom 11  
    Ten program jest dla Atmega8, pisałem go na podstawie programu z:
    http://www.patron.ehost.pl/patron/artykuly/vinavr/AVR_tutorial.htm
    Mówiłem że się nie znam na programowaniu a niestety musze taki program napisać.
    Może macie jakieś materiały z w których krok po kroku jest opisane, bo widzę że to co znalazłem okazało się złe i przestarzałe.
  • #5 7163292
    tmf
    VIP Zasłużony dla elektroda
    No, to jest tutorial do kompilatora sprzed 5 lat! Juz sam blad w naziwe (vinavr) powinien dac do myslenia :)
    Od tego czasu AVR-libc zmienilo sie bardzo i nawet tego programu nie uda ci sie skompilowac nowsza wersja. Jesli znasz angielski to opis do AVR-libc masz w WinAVR. Pokaz schemat wg ktorego budujesz to urzadzenie, bo jesli jest podobny do tego programu to zle to wrozy. Wkleilem ci schemat takiego urzadzenia z mojej stronki - dziala i moge za to reczyc, chociaz jako sonar do samochodu nie odwazylbym sie tego wykorzystac - przetwornik piezo nie ma takiego zasiegu, no i wiazka ma co najmniej 30 stopni, czyli po paru metrach odbija sie od wszystkiego tylko nie od samochodu, ktory przeciez jest jakies 100-200m przed toba.
    Jak pisalem, ten program skasuj, bo sie do niczego nie nadaje. Zacznij od generacji sygnalu 40kHz za pomoca timera i pomiaru czasu powrotu echa tez za pomoca timera.
    Czy ten program jest poprawny
  • #6 7163548
    Ligi
    Poziom 11  
    Wiem że czujniki piezo nie posiadają zasięgu do 100m, ja naszczęście maksymalnie potrzebuje osiągnąć 10m ale jak będzie 6m to też będzie dobrze. schemat postaram się wrzucić jutro bo nie mam go na kompie tylko na kartce i właśnie sciąga się program do rysowania. Mogę Ci tak na szybko powiedzieć jak jest podłączony.

    Procek to Atmega8 z niego z portu PD0 i PD1 wychodzą sygnały na układ max232 który wzmacnia napięcie na przetworniku. Odbiornik wchodzi na wzmacniacz nieodwracający, ten na filtr butterwortha II rzędu a z niego na wejścia analogowe uP PD6 i PD7. Buzzer jest podłączony pod PC5 i PC1 a diody pod PC4, PC3, PC2
REKLAMA