Skocz do zawartości

ATMEGA8 Czujnik HC-SR04


w1941srobot

Pomocna odpowiedź

Witam piszę tutaj ponieważ już męczę się z tym od 6godz. i nic. Dodam, że przy okazji uczyłem się obsługi przerwań i timerów. Nie mogę sobie poradzić z obsługą czujnika HC-SR04. Już z kilkanaście razy zmieniam kod, próbuje tak i tak, swoje sposoby, czyjeś ale dalej dupa.

Chce wyświetlić odl. na porcie C w atmedze gdzie mam podpiętych 6 diod. Do portu B podłączyłem pin TRIG od HC-SR04 a ECHO do INT1.

TERAZ TAK:

Częstotliwość taktowania mikro kontrolera wynosi 8mhz.

Timer2 jest tak ustawiony (tak mi się wydaje, sam liczyłem więc może być błąd) żeby po 8 taktach wywołać przerwanie co da nam 1us.

Port INT1 ustawiłem na przerwanie wywołane zmianą stanu:

Reszta wyjaśni się w kodzie 🙁:

Dodam jeszcze tylko że diody losowo zmieniają stan co około sekundę (tak mi się wydaje). 🙁

#define F_CPU 8000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile char zbocze ;          // zero to stan początkowy
volatile int czas ;		//zmienna przechowuje czas  jednostka 1 us
volatile char odl;
int main()
{
DDRC=0xFF; //c jako wejscie
DDRB=0xFF; // jako wyjscie
DDRD=0x00; //jako wejscie

PORTC=0x00;
PORTB=0x00;

MCUCR|=(1<<ISC10); //przerwanie wywołane zmianą stanu

GICR|=(1<<INT1); //uruchomienie przerwan int1

TIMSK|=(1<<OCIE2); //przerwanie od timera po zrownaniu z OCR2

OCR2=8; 

czas=0;
zbocze=0;


sei();
while(1)
{


	//czas=0;

	_delay_ms(500);

	PORTB=0xFF;    //uaktywnienie SC-HC04
	_delay_us(15);
	PORTB=0x00;

	PORTC=odl; // Wyswietlenie czasu w 1 us.



}
}

SIGNAL(SIG_INTERRUPT1)
{

if(zbocze==0)
	{

		TCCR2=0b00001001; //WGM21 ON   bez preskalera, start timera
	        zbocze=1;
	}
else if(zbocze==1)
	{


			TCCR2=0b00001000; //WGM21 zatrzymanie timera

			odl=czas*340/100;
			czas=0;

			zbocze=0;

	}
}


SIGNAL(SIG_OUTPUT_COMPARE2)
{
++czas;

}

Z góry przepraszam za błędy ale jest 2:06 i już nie daje rady :/.

[ Dodano: 07-09-2013, 12:49 ]

Dokonałem zmian w kodzie i

teraz diody wyświetlają błędne informacje.:

#define F_CPU 8000000L 
#include <avr/io.h> 
#include <avr/interrupt.h> 
#include <util/delay.h> 

volatile char zbocze ;          // zero to stan początkowy 
volatile int czas ;        //zmienna przechowuje czas  jednostka 1 us 
volatile uint8_t odl; 
int main() 
{ 
DDRC=0xFF; //c jako wejscie 
DDRB=0xFF; // jako wyjscie 
DDRD=0x00; //jako wejscie 

PORTC=0x00; 
PORTB=0x00; 

MCUCR|=(1<<ISC10); //przerwanie wywołane zmianą stanu 

GICR|=(1<<INT1); //uruchomienie przerwan int1 

TIMSK|=(1<<OCIE2); //przerwanie od timera po zrownaniu z OCR2 

OCR2=8; 

czas=0; 
zbocze=0; 


sei(); 
while(1) 
{ 


       //czas=0; 

       _delay_ms(500); 

       PORTB=0xFF;    //uaktywnienie SC-HC04 
       _delay_us(15); 
       PORTB=0x00; 
       _delay_ms(1); // Sprawdzę czy z opóźnieniem 15ms będzie działać
       PORTC=odl; // Wyswietlenie czasu w 1 us. 



} 
} 

SIGNAL(SIG_INTERRUPT1) 
{ 

   if(zbocze==0) 
       { 

           TCCR2=0b00001001; //WGM21 ON   bez preskalera, start timera 
               zbocze=1; 
       } 
   else if(zbocze==1) 
       { 


               TCCR2=0b00001000; //WGM21 zatrzymanie timera 

               odl=((czas/58)*340)/2; 
               czas=0; 

               zbocze=0; 

       } 
} 


SIGNAL(SIG_OUTPUT_COMPARE2) 
{ 
   ++czas; 

}

[ Dodano: 07-09-2013, 16:50 ]

Ale monolog 😃 :D, ale wydaje

się, że atmega za szybko przypisuje wartość do PORTU C i trzeba zwiększyć wielkość opóźnienia z 1ms do około 15ms? Jak tylko przyjadę do domu to sprawdzę. Proszę o odpowiedzi 🙂.

[ Dodano: 07-09-2013, 22:20 ]

Dziękuje za pomoc 🤣 problem rozwiązałem 🙂. Napisze może przyda się innym 🙂:

#define F_CPU 8000000L 
#include <avr/io.h> 
#include <avr/interrupt.h> 
#include <util/delay.h> 

volatile char zbocze ;          // zero to stan początkowy 
volatile int czas ;        //zmienna przechowuje czas  jednostka 1 us 
volatile uint8_t odl; 
int main() 
{ 
DDRC=0xFF; //c jako wejscie 
DDRB=0xFF; // jako wyjscie 
DDRD=0x00; //jako wejscie 

PORTC=0x00; 
PORTB=0x00; 

MCUCR|=(1<<ISC10); //przerwanie wywołane zmianą stanu 

GICR|=(1<<INT1); //uruchomienie przerwan int1 

TIMSK|=(1<<OCIE2); //przerwanie od timera po zrownaniu z OCR2 

OCR2=8; // przerwanie co 1us

czas=0; 
zbocze=0; 


sei(); 
while(1) 
{ 


       //czas=0; 

       _delay_ms(1000); //pomiar co 1 sec.

       PORTB=0xFF;    //uaktywnienie SC-HC04 
       _delay_us(15); 
       PORTB=0x00; 
       _delay_ms(30); // opóźnienie max długość echa
       PORTC=odl; // Wyswietlenie czasu w 1 us. 



} 
} 

SIGNAL(SIG_INTERRUPT1) 
{ 

   if(zbocze==0) 
       { 

           TCCR2=0b00001001; //WGM21 ON   bez preskalera, start timera 
               zbocze=1; 
       } 
   else if(zbocze==1) 
       { 


               TCCR2=0b00001000; //WGM21 zatrzymanie timera 

               odl=czas/10; 
               czas=0; 

               zbocze=0; 

       } 
} 


SIGNAL(SIG_OUTPUT_COMPARE2) 
{ 
   ++czas; //zwiekszenie licznika

}
  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.