Skocz do zawartości

Czujnik HC-SR04 - pomocy w obsłudze


czarny8322

Pomocna odpowiedź

Witam,

Potrzebuję pomocy w obsłudze czujnika ultradźwiękowego HC-SR04. Potrzebuję programu w języku C, przykładu lub cokolwiek, abym mógł dalej z tym wystartować. Bede wdzięczny za jakąkolwiek pomoc. Szukałem na necie ale znalazłem przykłady jedynie dla arduino.

__________

Komentarz dodany przez: Treker

_allegro

Link do komentarza
Share on other sites

mój kod obsługujący 3 takie czujniki (są komentarze więc chyba wszystko jasne powinno być):

//F-cja inicjująca przerwania zawnętrzne i timer2
void InitInterrupt(void)					
{
//PRZERWANIA ZEWNĘTRZNE

DDRD = 0xf8;							//PD0-PD2 - wejscie (Echo); PD3-PD5 - wyjścia(Trig)

EICRA = 0x3f;							//Przerwanie zostanie wywołane zboczem narastająym
										//na wejściach INT0, INT1, INT2

//TIMER2
TCNT2 = 0x00;							//Zerowanie rejestru TCNT2 (Rejestr jednostki zegara)

TCCR2 = (1<<WGM01)|(1<<CS00);			//Ustawia timer2 w tryb CTC bez preskalera
										//Czestotliwość 16Mhz/1=16MHz

OCR2 = 0x10;							//Górna wartość licznika wynosi 16
										//Przerwania będą następować co 1us

SREG = 0x80;
}


//F-cja przerwania od Timera2
ISR(TIMER2_COMP_vect)						
{
licznik++;
}

//F-cja przerwania zewnętrznego INT0
ISR(INT0_vect)	
{
if(flaga==0)
{
	TIMSK = (1<<OCIE2);				//włącza Timer2 w trybie dopasowania (START)

	ClrBit(EIMSK, INT0);

	EICRA = 0x00;						//Przerwanie zostanie wywołane zboczem opadającym
	EICRA = (1<<ISC01);				//na wejściu INT0

	SetBit(EIMSK, INT0);

	flaga=1;
}

else if(flaga==1)
{
	TIMSK &=~(1<<OCIE2);				//zatrzymuje Timer2 (STOP)

	ClrBit(EIMSK, INT0);

	EICRA = 0x00;						//Przerwanie zostanie wywołane zboczem rosnącym
	EICRA = (1<<ISC01)|(1<<ISC00);		//na wejściu INT0

	SetBit(EIMSK, INT0);

	odl0=licznik;						//Zapisuje wartość licznika do zmiennej "odl"
	odl0/=20;							//oraz skaluje go

	licznik=0;							//Zerowanie licznika
	flaga=0;

}
}

//F-cja przerwania zewnętrznego INT1
ISR(INT1_vect)	
{
if(flaga==0)
{
	TIMSK = (1<<OCIE2);				//włącza Timer2 w trybie dopasowania (START)

	ClrBit(EIMSK, INT1);

	EICRA = 0x00;						//Przerwanie zostanie wywołane zboczem opadającym
	EICRA = (1<<ISC11);				//na wejściu INT1

	SetBit(EIMSK, INT1);

	flaga=1;
}

else if(flaga==1)
{
	TIMSK &=~(1<<OCIE2);				//zatrzymuje Timer2 (STOP)

	ClrBit(EIMSK, INT1);

	EICRA = 0x00;						//Przerwanie zostanie wywołane zboczem rosnącym
	EICRA = (1<<ISC11)|(1<<ISC10);		//na wejściu INT1

	SetBit(EIMSK, INT1);

	odl1=licznik;						//Zapisuje wartość licznika do zmiennej "odl"
	odl1/=20;							//oraz skaluje go

	licznik=0;							//Zerowanie licznika
	flaga=0;

}
}

//F-cja przerwania zewnętrznego INT2
ISR(INT2_vect)	
{
if(flaga==0)
{
	TIMSK = (1<<OCIE2);				//włącza Timer2 w trybie dopasowania (START)

	ClrBit(EIMSK, INT2);

	EICRA = 0x00;						//Przerwanie zostanie wywołane zboczem opadającym
	EICRA = (1<<ISC21);				//na wejściu INT2

	SetBit(EIMSK, INT2);

	flaga=1;
}

else if(flaga==1)
{
	TIMSK &=~(1<<OCIE2);				//zatrzymuje Timer2 (STOP)

	ClrBit(EIMSK, INT2);

	EICRA = 0x00;						//Przerwanie zostanie wywołane zboczem rosnącym
	EICRA = (1<<ISC21)|(1<<ISC20);		//na wejściu INT2

	SetBit(EIMSK, INT2);

	odl2=licznik;						//Zapisuje wartość licznika do zmiennej "odl"
	odl2/=20;							//oraz skaluje go

	licznik=0;							//Zerowanie licznika
	flaga=0;
}
}


double l_pomiar(void)			
{
SetBit(EIMSK, INT0);


SetBit(PORTD, 3);
_delay_us(15);
ClrBit(PORTD, 3);

_delay_ms(8);

ClrBit(EIMSK, INT0);	
return odl0;
}

double p_pomiar(void)			
{
SetBit(EIMSK, INT2);


SetBit(PORTD, 5);
_delay_us(15);
ClrBit(PORTD, 5);

_delay_ms(8);

ClrBit(EIMSK, INT2);	
return odl2;
}

double s_pomiar(void)			
{
SetBit(EIMSK, INT1);


SetBit(PORTD, 4);
_delay_us(15);
ClrBit(PORTD, 4);

_delay_ms(8);

ClrBit(EIMSK, INT1);	
return odl1;
}
  • Lubię! 1
Link do komentarza
Share on other sites

Używam atmega16 i chciałbym obsłużyć jeden czujnik podpięty do int0 i niestety jako "świerzak" nie mogę sobie jeszcze poradzić😋

W kodzie od kolegi wyżej zamieściłem komentarze odnośnie których proszę o jakieś sugestie:


//F-cja inicjująca przerwania zawnętrzne i timer2
void InitInterrupt(void)                   
{
//PRZERWANIA ZEWNĘTRZNE

    DDRD = 0x04;                            //PD2 - wejscie (Echo)

    MCUCR = (1<<ISC01) | (1<<ISC00);                            //Przerwanie zostanie wywołane zboczem narastająym
                                            //na wejściach INT0, INT1, INT2

//TIMER2
    TCNT2 = 0x00;                            //Zerowanie rejestru TCNT2 (Rejestr jednostki zegara)

    TCCR2 = (1<<WGM01)|(1<<CS21);            //Ustawia timer2 w tryb CTC bez preskalera
                                            //Czestotliwość 16Mhz/1=16MHz

//////Tu mam pierwszy problem, ponieważ program będzie chodził z wewnętrznym oscylatorem 8Mhz wiec ustawiłem bit w rejestrze TCCR2 na (1<<CS21) wg noty"clkT2S / 8 (preskaler)" --czy zrobiłem prawidłowo?//////



    OCR2 = 0x10;                            //Górna wartość licznika wynosi 16
                                            //Przerwania będą następować co 1us //


/////Tutaj w OCR2 też chyba powinienem zmienić wartość skoro wprowadziłem zmiany w rejestrze TCCR2 z którym to jak się domyślam OCR2 ma być porównywany, jednak nie wiem jak to wyliczyć, czy powinienem zmienić wartość "0x10"??/////


    SREG = 0x80;  ////po chłopsku jednym zdaniem proszę o wytłumaczenie mi do czego służy SREG i dlaczego przypisana jest mu akurat taka wartość 0x80? w nocie nie mogę się połapać////
}


//F-cja przerwania od Timera2


ISR(TIMER2_COMP_vect)                       
{
    licznik++;             ////domyślam się że muszę na początku zadeklarować zmienna licznik? ///
}


//F-cja przerwania zewnętrznego INT0



ISR(INT0_vect)   
{
    if(flaga==0)           ////flaga -- także muszę zadeklarować tą zmienna?///
    {
        TIMSK = (1<<OCIE2);                //włącza Timer2 w trybie dopasowania (START)



        ClrBit(MCUCR, INT0);       


////jeśli możesz to napisz mi kolego sokolsok, skąd wziąłes te funkcje: ClrBit i SetBit --- stworzyłęś je sam czy są dostępne w jakiejś bibliotece? ////




        EICRA = 0x00;                        //Przerwanie zostanie wywołane zboczem opadającym


//////EICRA ---- korzystam z atmegi 16 i tutaj też wyskakuje mi błąd ale domyślam się że poprostu u mnie ten rejestr się jakoś inaczej nazywa, czy wiecie jak?////


        EICRA = (1<<ISC01);                //na wejściu INT0

        SetBit(MCUCR, INT0);

        flaga=1;
    }

    else if(flaga==1)
    {
        TIMSK &=~(1<<OCIE2);                //zatrzymuje Timer2 (STOP)

        ClrBit(MCUCR, INT0);

        EICRA = 0x00;                        //Przerwanie zostanie wywołane zboczem rosnącym
        EICRA = (1<<ISC01)|(1<<ISC00);        //na wejściu INT0

        SetBit(MCUCR, INT0);

        odl0=licznik;                        //Zapisuje wartość licznika do zmiennej "odl"
        odl0/=20;                            //oraz skaluje go

        licznik=0;                            //Zerowanie licznika
        flaga=0;

    }
}



double l_pomiar(void)           
{
    SetBit(MCUCR, INT0);


    SetBit(PORTD, 3);
    _delay_us(15);
    ClrBit(PORTD, 3);

    _delay_ms(8);

    ClrBit(MCUCR, INT0);   
    return odl0;
}

int main(void)
{
   while(1)
   {
       //TODO:: Please write your application code
   }
}

Proszę o ogólne wytłumaczenie działania czujnika?

Czy dobrze myślę że atmega liczy czas w jakim fala została wysłana przez czujnik, odbita od przeszkody a następnie powróciła?

Link do komentarza
Share on other sites

Nie tak działa czujnik. Na wejście TRIG podajesz impuls o szerokości co najmniej 10us, co inicjuje wykonanie pomiaru. Następnie nadajnik hc-sr04 wysyła 8 impulsów, które są odbierane przez (oczywiście) odbiornik czujnika. Na wyjściu ECHO otrzymujesz impuls który jest proporcjonalny do wykrytej odległości. I to właśnie czas trwania tego impulsu musisz zmierzyć. (to tak w skrócie)

TCCR2 = (1<<WGM01)|(1<<CS21);          //Ustawia timer2 w tryb CTC bez preskalera
                                            //Czestotliwość 16Mhz/1=16MHz

//////Tu mam pierwszy problem, ponieważ program będzie chodził z wewnętrznym oscylatorem 8Mhz wiec ustawiłem bit w rejestrze TCCR2 na (1<<CS21) wg noty"clkT2S / 8 (preskaler)" --czy zrobiłem prawidłowo?//////

.........


    OCR2 = 0x10;                            //Górna wartość licznika wynosi 16
                                            //Przerwania będą następować co 1us //

/////Tutaj w OCR2 też chyba powinienem zmienić wartość skoro wprowadziłem zmiany w rejestrze TCCR2 z którym to jak się domyślam OCR2 ma być porównywany, jednak nie wiem jak to wyliczyć, czy powinienem zmienić wartość "0x10"??/////

Pierwszy rejestr jak sam zauważyłeś służy do ustawienie preskalera (jak i również trybu działania) licznika czyli jeśli używasz 8 MHz i użyjesz preskalera 8 to licznik będzie miał "pojemność" 1MHz. (8MHz/8=1MHz). Rejestrze OCRn jest rejestrem porównania. Gdy aktualna wartość licznika (rejestr TCNTn) zrówna się z wartością w OCRn nastąpi przerwanie od przepełnienia.

Czyli w przypadku Twojego kwarcu możesz ustawić preskaler na 1 i górną wartość na 8, lub preskaler na 8 i górną wartość na 1 - w obu przypadkach przerwanie będzie wywoływało się co 1us. Wszystkie kombinacje preskalerów i kwarców możesz sobie zobaczyć w moim pliku exelowym, który zrobiłem jak ja się tym bawiłem (załącznik).

SREG = 0x80;  ////po chłopsku jednym zdaniem proszę o wytłumaczenie mi do czego służy SREG i dlaczego przypisana jest mu akurat taka wartość 0x80? w nocie nie mogę się połapać//// 

8 bit (I) tego rejestru gdy jest ustawiony globalnie zezwala na wszystkie przerwania. Możesz zamiennie używać sei(); A czemu 80? 80 szesnastkowo to 10000000 binarnie, a mi zależało żeby ustawić wyłącznie ten jeden bit.

ISR(TIMER2_COMP_vect)                       
{
    licznik++;             ////domyślam się że muszę na początku zadeklarować zmienna licznik? ///
}

Tak, dobrze się domyślasz. (tą "flage" poniżej też)

////jeśli możesz to napisz mi kolego sokolsok, skąd wziąłes te funkcje: ClrBit i SetBit --- stworzyłęś je sam czy są dostępne w jakiejś bibliotece? ////

Są to makra ustawiające bądź zerujące dany bit:

#define SetBit(reg, bit) ((reg) |= (0x01 << (bit)))			// Ustawienie danego bitu w rejestrze
#define ClrBit(reg, bit) ((reg) &= ~(0x01 << (bit)))		// Wyzerowanie danego bitu w rejestrze
//////EICRA ---- korzystam z atmegi 16 i tutaj też wyskakuje mi błąd ale domyślam się że poprostu u mnie ten rejestr się jakoś inaczej nazywa, czy wiecie jak?//// 

U Ciebie ten rejestr nazywa się MCUCR.

Ps. To wszystko co to napisałem jest w dokumentacji, jesli chodzi o ATmege 16 masz nawet dokumentacje po polsku. tu Wystarczy trochę poszukać🙂

preskaler.xls

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Podpowie mi ktoś co takiego robie żle?

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

#define SetBit(reg, bit) ((reg) |= (0x01 << (bit)))         // Ustawienie danego bitu w rejestrze 
#define ClrBit(reg, bit) ((reg) &= ~(0x01 << (bit)))        // Wyzerowanie danego bitu w rejestrze


//F-cja inicjująca przerwania zawnętrzne i timer2 
 void InitInterrupt(void)                    
 { 
 //PRZERWANIA ZEWNĘTRZNE 

     DDRD = 0x04;                            //PD2 - wejscie (Echo) 

     MCUCR = (1<<ISC01) | (1<<ISC00);        //Przerwanie zostanie wywołane zboczem narastająym 
                                             //na wejściach INT0, INT1, INT2 
 //TIMER2 
     TCNT2 = 0x00;                           //Zerowanie rejestru TCNT2 (Rejestr jednostki zegara) 

     TCCR2 = (1<<WGM21)|(1<<CS20);           //Ustawia timer2 w tryb CTC bez preskalera 
                                             //Czestotliwość 16Mhz/1=16MHz 

     OCR2 = 0x08;                            //Górna wartość licznika wynosi 16 
                                             //Przerwania będą następować co 1us // 
     sei();                                         
     //SREG = 0x80; 
} 


 double l_pomiar(void)            
 { 
     SetBit(MCUCR, INT0); 
     SetBit(PORTD, 3); 
     _delay_us(15); 
     ClrBit(PORTD, 3); 
     _delay_ms(8); 
     ClrBit(MCUCR, INT0);    
     return odl0; 
 } 

int main(void) 
{ 
int licznik, odl0, flaga;

while(1) 
    { 
	InitInterrupt();
	l_pomiar();
 } 
}

SIGNAL(TIMER2_COMP_vect)                        
 {
  licznik++;              
 } 


 //F-cja przerwania zewnętrznego INT0 



 SIGNAL(INT0_vect)    
 { 
  if(flaga==0)            
     { 
         TIMSK = (1<<OCIE2);                //włącza Timer2 w trybie dopasowania (START) 
         ClrBit(MCUCR, INT0);        
         MCUCR = 0x00;                        //Przerwanie zostanie wywołane zboczem opadającym 
         MCUCR = (1<<ISC01);                //na wejściu INT0 
         SetBit(MCUCR, INT0); 
         flaga=1; 
     } 

     else if(flaga==1) 
     { 
	  TIMSK &=~(1<<OCIE2);                //zatrzymuje Timer2 (STOP) 

         ClrBit(MCUCR, INT0); 

         MCUCR = 0x00;                        //Przerwanie zostanie wywołane zboczem rosnącym 
         MCUCR = (1<<ISC01)|(1<<ISC00);        //na wejściu INT0 

         SetBit(MCUCR, INT0); 

         odl0=licznik;                        //Zapisuje wartość licznika do zmiennej "odl" 
         odl0/=20;                            //oraz skaluje go 

         licznik=0;                            //Zerowanie licznika 
         flaga=0; 

     } 

nie mogę tego skompilować

Link do komentarza
Share on other sites

Poprawiłem zmienne, program się skompilował jednak w terminalu zamiast odległości atmega wysyła mi jedynie liczby 128

a to kod:

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

#define SetBit(reg, bit) ((reg) |= (0x01 << (bit)))         // Ustawienie danego bitu w rejestrze 
#define ClrBit(reg, bit) ((reg) &= ~(0x01 << (bit)))        // Wyzerowanie danego bitu w rejestrze 
int licznik, odl0, flaga;

#define RS_BAUD 9600
#define RS_UBRR F_CPU / 16 / RS_BAUD - 1

void start(uint16_t ubrr)
{
// Ustawienie prędkości transmisji
UBRRH = (uint8_t)(ubrr >> 8);
UBRRL = (uint8_t)ubrr;

// Włączenie nadajnika i odbiornika
UCSRB = (1 << RXEN) | (1 << TXEN);

// Ustawienie formatu ramki:
// 8 bitów danych, 1 bit stopu, brak parzystości
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
}
void nadaj(uint8_t data)
{
// Oczekiwanie na zakończenie nadawania
while (!(UCSRA & (1 << UDRE)));

// Wysłanie danych
UDR = data;
}
uint8_t uart_ischar()
{
// Czy w buforze są dane?
return (UCSRA & (1 << RXC));
}
uint8_t uart_getc()
{
// Czy w buforze są dane?
while(!uart_ischar());

// Dane z bufora
return UDR;
} 





//F-cja inicjująca przerwania zawnętrzne i timer2 
  void InitInterrupt(void)                    
  { 
  //PRZERWANIA ZEWNĘTRZNE 

      DDRD = 0xFF;                            //PD2 - wejscie (Echo) 

      MCUCR = (1<<ISC01) | (1<<ISC00);        //Przerwanie zostanie wywołane zboczem narastająym 
                                              //na wejściach INT0, INT1, INT2 
  //TIMER2 
      TCNT2 = 0x00;                           //Zerowanie rejestru TCNT2 (Rejestr jednostki zegara) 

      TCCR2 = (1<<WGM21)|(1<<CS20);           //Ustawia timer2 w tryb CTC bez preskalera 
                                              //Czestotliwość 16Mhz/1=16MHz 

      OCR2 = 0x01;                            //Górna wartość licznika wynosi 16 
                                              //Przerwania będą następować co 1us // 
      //sei();                                          
      SREG = 0x80; 
} 


  double l_pomiar(void)            
  { 
      SetBit(MCUCR, INT0); 
      SetBit(PORTD, 3); 
      _delay_us(20); 
      ClrBit(PORTD, 3); 
      _delay_ms(8); 
      ClrBit(MCUCR, INT0);    
      return odl0; 
  } 

 int main(void) 
 { 
   DDRD=0xFF;
    while(1) 
     { 
	 start(RS_UBRR);
        InitInterrupt(); 
	 l_pomiar();
        nadaj(odl0); 
    } 
 } 

SIGNAL(TIMER2_COMP_vect)                        
  { 
      licznik++;              
  } 


  //F-cja przerwania zewnętrznego INT0 



  SIGNAL(INT0_vect)    
  { 
      if(flaga==0)            
      { 
          TIMSK = (1<<OCIE2);                //włącza Timer2 w trybie dopasowania (START) 
          ClrBit(MCUCR, INT0);        
          MCUCR = 0x00;                      //Przerwanie zostanie wywołane zboczem opadającym 
          MCUCR = (1<<ISC01);                //na wejściu INT0 
          SetBit(MCUCR, INT0); 
          flaga=1; 
      } 

      else if(flaga==1) 
      { 
          TIMSK &=~(1<<OCIE2);                //zatrzymuje Timer2 (STOP) 

          ClrBit(MCUCR, INT0); 

          MCUCR = 0x00;                        //Przerwanie zostanie wywołane zboczem rosnącym 
          MCUCR = (1<<ISC01)|(1<<ISC00);        //na wejściu INT0 

          SetBit(MCUCR, INT0); 

          odl0=licznik;                        //Zapisuje wartość licznika do zmiennej "odl" 
          odl0/=20;                            //oraz skaluje go 

          licznik=0;                            //Zerowanie licznika 
          flaga=0; 

      }
   }	      
Link do komentarza
Share on other sites

Witam, wzmagam się z uruchomieniem czujnika ultradźwiękowego HC-SR04 na ATMEGA 328p. Czujnik bardzo dobrze współpracuje z Arduino, aczkolwiek zależy mi na obsłudze tego czujnika w czystym C i środowisku Eclipse. Potrzebuję odczytać odległość w cm, która będzie warunkiem do poruszania się robota.

Pozdrawiam

Link do komentarza
Share on other sites

No, nieźle odkopałeś temat. Jeśli kody Kolegów przedstawione powyżej Ci nie wystarczają, może warto założyć własny temat i zacząć od początku? Na dzień dobry przejrzyj dane katalogowe tego czujnika:

http://www.micropik.com/PDF/HCSR04.pdf

i napisz konkretnie czego nie rozumiesz. Idea sprowadza się do pomiaru długości impulsu więc nie jest to jakaś technologia rakietowa - przy niewielkiej pomocy powinieneś sam to szybko obmyślić i napisać kawałek kodu.

Link do komentarza
Share on other sites

Próbuję dopasować kod kolegi do swojego układu na Atmega328p. Aczkolwiek nie chcę mi to działać. Poniżej zamieszczam kod.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#define LED_PIN (1<<PB5)
#define LED_ON PORTB &= ~LED_PIN
#define LED_OFF PORTB |= LED_PIN
#define LED_TOG PORTB ^= LED_PIN

#define SetBit(reg, bit) ((reg) |= (0x01 << (bit)))            // Ustawienie danego bitu w rejestrze
#define ClrBit(reg, bit) ((reg) &= ~(0x01 << (bit)))        // Wyzerowanie danego bitu w rejestrze

int licznik, odl0, flaga;

//F-cja inicjująca przerwania zawnętrzne i timer2
void InitInterrupt(void)
{
//PRZERWANIA ZEWNĘTRZNE
   DDRD |= (1<<PD2);                            //PD2- wejście echo
   EICRA = 0x3d;                            //Przerwanie zostanie wywołane zboczem narastająym
                                                    //na wejściu INT0 - NIE WIEM CO TUTAJ  MAM USTAWIĆ
//TIMER2
   TCNT2 = 0x00;                            //Zerowanie rejestru TCNT2 (Rejestr jednostki zegara)
   TCCR2B = (1<<WGM22)|(1<<CS20);            //Ustawia timer2 w tryb CTC bez preskalera
                                           //Czestotliwość 16Mhz/1=16MHz
   OCR2B = 0x10;                            //Górna wartość licznika wynosi 16
                                           //Przerwania będą następować co 1us
}

//F-cja przerwania od Timera2
ISR(TIMER2_COMPB_vect)
{
   licznik++;
}

//F-cja przerwania zewnętrznego INT0
ISR(INT0_vect)
{
   if(flaga==0)
   {
       TIMSK2 = (1<<OCIE2B);                //włącza Timer2 w trybie dopasowania (START)

       ClrBit(EIMSK, INT0);

       EICRA = 0x00;                        //Przerwanie zostanie wywołane zboczem opadającym
       EICRA = (1<<ISC01);                //na wejściu INT0

       SetBit(EIMSK, INT0);

       flaga=1;
   }

   else if(flaga==1)
   {
       TIMSK2 &=~(1<<OCIE2B);                //zatrzymuje Timer2 (STOP)

       ClrBit(EIMSK, INT0);

       EICRA = 0x00;                        //Przerwanie zostanie wywołane zboczem rosnącym
       EICRA = (1<<ISC11)|(1<<ISC10);        //na wejściu INT0

       SetBit(EIMSK, INT0);

       odl0=licznik;                        //Zapisuje wartość licznika do zmiennej "odl"
       odl0/=20;                            //oraz skaluje go

       licznik=0;                            //Zerowanie licznika
       flaga=0;

   }
}

double pomiar(void)
{
   SetBit(EIMSK, INT0);

   SetBit(PORTD, 6);
   _delay_us(15);
   ClrBit(PORTD, 6);

   _delay_ms(8);

   ClrBit(EIMSK, INT0);
   return odl0;
}

int main(void)
{

DDRB |= LED_PIN;

sei(); //włączenie globalnych przerwań

InitInterrupt();

while(1)
{
	pomiar();
	if(odl0>0){LED_ON;}


}

}

Proszę o pomoc! :)
Link do komentarza
Share on other sites

Czyli jednak zrzynanie i pójście na łatwiznę. Oczekujesz, że ktoś będzie przeglądał Twój kod nie znając reszty projektu i wskaże Ci palcem błąd? Może kolega który go napisał? Bo jeśli on też go ściągnął to mam dla Ciebie przykrą wiadomość: będziesz musiał przysiąść i sam zrozumieć to, co nam tu wysłałeś. Spróbuj opisać co działa, co nie, jakie są objawy, jak wygląda układ i jakie są warunki pomiaru - wysil się, przynajmniej tyle.

Czy zostawiając samochód w warsztacie mówisz zwykle: "Aczkolwiek nie chcę mi to działać" i odchodzisz? Chyba jednak nie, prawda?

Link do komentarza
Share on other sites

"marek1707" <- jak to mówią nie ma cwaniaka nad Warszawiaka. Mimo, że mi nie pomogłeś i tak dzięki, za Twoje komentarze. 😉 Już sobie poradziłem i uznaje temat za otwarty. Gdyby miał ktoś problem z tym czujnikiem służę pomocą. Pozdrawiam

Link do komentarza
Share on other sites

Trudno pomagać komuś, kto nie szanuje swoich rozmówców wtykając im nie swój kod z propozycją "to teraz wy się pomęczcie a ja poczekam" ale dzięki za uznanie. Nigdy nie myślałem, że miejsce zamieszkania jakoś wyróżnia choć pewnie niektórym robi to różnicę. Nawet jeśli ja nie zasługuję na kilka słów wyjaśnienia to może innym Kolegom nie sprawisz zawodu i napiszesz co było problemem? Gdybyś jeszcze w skrócie opisał jak sobie poradziłeś z obciążeniem procesora przerwaniami co 1 mikrosekundę 🤯 to byłbym wdzięczny.

Rozumiem, że otwarty temat sugeruje dalszą dyskusję nad pomiarem długości impulsów, tak?

Link do komentarza
Share on other sites

Witam,a ja mam pytanie odnośnie tego czujnika,czy np.ktoś z forum posiada sterownik serw polulu ? pytanie jest takie czy do tego kontrolera da się podłączyć czujnik ultradźwiękowy HC-SR04 ? czy trzeba do niego osobny uC stosować? dodam że robot sterowany laptopem jeśli miało by to coś pomóc .

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.