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

[C] czujnik koloru AVR atmega8 program Prośba

avo3 07 Lis 2010 20:17 3699 21
  • #1 8715241
    avo3
    Poziom 11  
    Witam. Projektuję czujnik koloru na kontrolerze Atmega8.
    Mam już schemat oraz program w języku C, ale jestem początkujący w programowaniu i dlatego proszę o sprawdzenie programu lub ewentualne porady. Program starałem się napisać jak najprościej nie jestem pewien końcówki tego programu związanego z porównywaniem zmiennych i wystawianiem stanu wysokiego na poszczególne wyjścia w zależności od rozpoznanego koloru. Z góry bardzo dziękuję.
    [C] czujnik koloru AVR atmega8 program Prośba
    Czujnik ma rozpoznawać trzy kolory przedmiotów (klocków) czerwony, zielony, niebieski.Po położeniu przedmiotu na przycisku Z1 (patrz schemat) rozpoczyna się procedura oświetlania przedmiotu. Jeśli przycisk Z1 nie jest wciśnięty powinna mrugać dioda bezczynności. Najpierw oświetlany jest światłem czerwonym (dioda LED) światło odbija się od przedmiotu i trafia do fotorezystora. Fotorezystor podłączony jest do przetwornika ADC ukontrolera. Wartość pomiaru jest zapisywana w zmiennych. Ten sam schemat pomiaru powtarza się dla 2 pozostałych kolorów. Po oświetleniu klocka trzema różnymi barwami światła jeden z pomiarów będzie po porównaniu największy. Np. po oświetleniu czerwonego klocka czerwonym światłem fotorezystor „odbierze” większą ilość światła niż po oświetleniu go innym kolorem. Wtedy wysterowane jest odpowiednie wyjście w stan wysoki inne dla każdego z kolorów.
    
    #include <avr/io.h>
    #include <until/delay.h>
    
    unsigned int r, g, b, max;                  //zmienne
    unsigned char i;
    
    int main()
    {
     TCCR0 |= ((1 << CS00) | (1 << CS02));       //Ustawia timer0 z preskalerem Fcpu/1024
     DDRB=0;                                     //linie portu B wejściowe
     PORTB=0x01;                                 //stan wysoki na lini PB0
     DDRD=0x7F;                                  //linie PD0 PD1 PD2 PD3 PD4 PD5 PD6 wyjściowe
     PORTD=0x7F;                                 //stan wysoki na liniach PD0 PD1 PD2
     ADMUX=0;                                    //wybierz kanał 0 przetwornika ADC
     ADCSR = _BV(ADEN)|_BV(ADSC)|_BV(ADFR)|_BV(ADIE)|_BV(ADPS1)|_BV(ADPS1)|_BV(ADPS0);
                                                 //włączenie przetwornika
                                                 //rozpocznij konwersję
                                                 //tryb samobieżny
                                                 //uruchom generowanie przerwań
                                                 //częstotilwość taktowania F_ADC=F_CPU/64 przy F_CPU=8MHz : F_ADC=125 kHz
     while(1)
     {
      for(i=1;i<=3;i++)                          //trzy fazy czerwona, zielona, niebieska
      {
       if(!PINB & 0x01)) i = 0;                 //jeśli na PB0 stan niski
       switch(i)
       {
         case 1:
         PORTD &= ~(_BV(PD0));                   //stan niski na PB0 dioda czerwona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         r=ADCW;                                 //wpisz wartość z przetwornika do zmiennej r (r -czerwona)
         PORTD |=_BV(PD0);                       //stan wysoki na Pb0 dioda czerwona zgaszona
         break;
    
         case 2:
         PORTD &= ~(_BV(PD1));                   //stan niski na PB1 dioda zielona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         g=ADCW;                                 //wpisz wartość z przetwornika do zmiennej g (g -zielona)
         PORTD |=_BV(PD1);                       //stan wysoki na Pb1 dioda zielona zgaszona
         break;
    
         case 3:
         PORTD &= ~(_BV(PD2));                   //stan niski na PB1 dioda niebieska zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         b=ADCW;                                 //wpisz wartość z przetwornika do zmiennej b (b -niebieska)
         PORTD |=_BV(PD2);                       //stan wysoki na Pb1 dioda niebieska zgaszona
         break;
    
         default;                                //gdy PB0 stan niski
         PORTD &= ~(_BV(PD3);                    //stan niski na PD3 dioda bezczynności zaświecona
         _delay_ms(1000);
         PORTD |=_BV(PD3);                       //stan wysoki na PD3 dioda bezczynności zgaszona
         _dealy_ms(1000);
       }
      }
     } 
     
      if(r>g)                 //jeśli r jest wieksze od g to                               
      {
       max=r;                //wartość w zmiennej r jest przypisana do zmiennej max
      }
      if(max=r)               //jeśli max=r 
      {
       PORTD &= ~(_BV(PD4);  //to zmień stan PD4 na wysoki
      }
      else
      { 
       max=g;                //jeśli r nie jest wieksze od g to max=g 
      } 
      if(max=g)               //jesli max=g
      {
       PORTD &= ~(_BV(PD5);  //to Zmien stan PD5 na wysoki
      }
      if(b>max)               //jeśli b jest wieksza od max to
      {
       max=b;                //wartość w zmiennej b jest przypisana do zmiennej max
      }
      if(max=b)               //jesli max=b
      {
       PORTD &= ~(_BV(PD6);  //to zmien stan PD6 na wysoki
      }
     return 0;
    }
    
  • Pomocny post
    #2 8715293
    sulfur
    Poziom 24  
    Zlikwidować pętlę for i instrukcję switch. Zapoznać się z różnicą pomiędzy operatorami = i ==.
  • #3 8715462
    tmf
    VIP Zasłużony dla elektroda
    Pomysł ciekawy, ale widzę pewien problem - zakładasz, że przedmiot odbija światło tylko o jednym kolorze. A co jeśli np. przedmiot ma kolor zielony, a nie powstający jako czysta barwa, tylko ze zmieszania żółtego i niebieskiego? Wtedy będziesz miał wysoki sygnał w kanale niebieskim i stosunkowo wysoki w czerwonym. To samo dotyczy oczywiście innych mieszanek. Różne farby mają czasami dosyć złożone widmo - warto więc sprawdzić na spektrofotometrze farby, których używasz.
  • #4 8715496
    avo3
    Poziom 11  
    Cytat:

    Pomysł ciekawy, ale widzę pewien problem - zakładasz, że przedmiot odbija światło tylko o jednym kolorze. A co jeśli np. przedmiot ma kolor zielony, a nie powstający jako czysta barwa, tylko ze zmieszania żółtego i niebieskiego? Wtedy będziesz miał wysoki sygnał w kanale niebieskim i stosunkowo wysoki w czerwonym. To samo dotyczy oczywiście innych mieszanek. Różne farby mają czasami dosyć złożone widmo - warto więc sprawdzić na spektrofotometrze farby, których używasz.

    Tak zgadzam się że to rozwiązanie może posiadać takie wady jednak buduję go z ciekawości na razie utknąłem przy programie do ukontrolera.
    Czy tak powinien wyglądać ten program po zmianach wykasowanie for i switch zmiany w = i ==
    
    #include <avr/io.h>
    #include <until/delay.h>
    
    unsigned int r, g, b, max;                  //zmienne
    unsigned char i;
    
    int main()
    {
     TCCR0 |= ((1 << CS00) | (1 << CS02));       //Ustawia timer0 z preskalerem Fcpu/1024
     DDRB=0;                                     //linie portu B wejściowe
     PORTB=0x01;                                 //stan wysoki na lini PB0
     DDRD=0x7F;                                  //linie PD0 PD1 PD2 PD3 PD4 PD5 PD6 wyjściowe
     PORTD=0x7F;                                 //stan wysoki na liniach PD0 PD1 PD2
     ADMUX=0;                                    //wybierz kanał 0 przetwornika ADC
     ADCSR = _BV(ADEN)|_BV(ADSC)|_BV(ADFR)|_BV(ADIE)|_BV(ADPS1)|_BV(ADPS1)|_BV(ADPS0);
                                                 //włączenie przetwornika
                                                 //rozpocznij konwersję
                                                 //tryb samobieżny
                                                 //uruchom generowanie przerwań
                                                 //częstotilwość taktowania F_ADC=F_CPU/64 przy F_CPU=8MHz : F_ADC=125 kHz
     while(1)
     {
         PORTD &= ~(_BV(PD0));                   //stan niski na PB0 dioda czerwona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         r=ADCW;                                 //wpisz wartość z przetwornika do zmiennej r (r -czerwona)
         PORTD |=_BV(PD0);                       //stan wysoki na Pb0 dioda czerwona zgaszona
         break;
    
       
         PORTD &= ~(_BV(PD1));                   //stan niski na PB1 dioda zielona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         g=ADCW;                                 //wpisz wartość z przetwornika do zmiennej g (g -zielona)
         PORTD |=_BV(PD1);                       //stan wysoki na Pb1 dioda zielona zgaszona
         break;
    
        
         PORTD &= ~(_BV(PD2));                   //stan niski na PB1 dioda niebieska zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         b=ADCW;                                 //wpisz wartość z przetwornika do zmiennej b (b -niebieska)
         PORTD |=_BV(PD2);                       //stan wysoki na Pb1 dioda niebieska zgaszona
         break;
    
       
        if(bit_is_clear(PINB, 0))                //jeśli na PB0 stan niski
    	 {
         PORTD &= ~(_BV(PD3);                    //stan niski na PD3 dioda bezczynności zaświecona
         _delay_ms(1000);
         PORTD |=_BV(PD3);                       //stan wysoki na PD3 dioda bezczynności zgaszona
         _dealy_ms(1000);
    	 }
     }
     
      if(r>g)                 //jeśli r jest wieksze od g to                               
      {
       max=r;                //wartość w zmiennej r jest przypisana do zmiennej max
      }
      if(max==r)               //jeśli max=r
      {
       PORTD &= ~(_BV(PD4);  //to zmień stan PD4 na wysoki
      }
      else
      {
       max=g;                //jeśli r nie jest wieksze od g to max=g
      }
      if(max==g)               //jesli max=g
      {
       PORTD &= ~(_BV(PD5);  //to Zmien stan PD5 na wysoki
      }
      if(b>max)               //jeśli b jest wieksza od max to
      {
       max=b;                //wartość w zmiennej b jest przypisana do zmiennej max
      }
      if(max==b)               //jesli max=b
      {
       PORTD &= ~(_BV(PD6);  //to zmien stan PD6 na wysoki
      }
     return 0;
    } 
  • Pomocny post
    #5 8715599
    sulfur
    Poziom 24  
    Pętla główna while powinna kończyć się przed "return 0". Teraz kończy się za wcześnie. Usunąć break pozostałe po switch (3 sztuki w pętli while).
  • #6 8715733
    avo3
    Poziom 11  
    Zmieniłem zakończenie pętli while usunąłem break oraz 'unsigned char i' nie będzie już potrzebny


    #include <avr/io.h>
    #include <until/delay.h>
    
    unsigned int r, g, b, max;                  //zmienne
    
    int main()
    {
     TCCR0 |= ((1 << CS00) | (1 << CS02));       //Ustawia timer0 z preskalerem Fcpu/1024
     DDRB=0;                                     //linie portu B wejściowe
     PORTB=0x01;                                 //stan wysoki na lini PB0
     DDRD=0x7F;                                  //linie PD0 PD1 PD2 PD3 PD4 PD5 PD6 wyjściowe
     PORTD=0x7F;                                 //stan wysoki na liniach PD0 PD1 PD2
     ADMUX=0;                                    //wybierz kanał 0 przetwornika ADC
     ADCSR = _BV(ADEN)|_BV(ADSC)|_BV(ADFR)|_BV(ADIE)|_BV(ADPS1)|_BV(ADPS1)|_BV(ADPS0);
                                                 //włączenie przetwornika
                                                 //rozpocznij konwersję
                                                 //tryb samobieżny
                                                 //uruchom generowanie przerwań
                                                 //częstotilwość taktowania F_ADC=F_CPU/64 przy F_CPU=8MHz : F_ADC=125 kHz
     while(1)
     {
         PORTD &= ~(_BV(PD0));                   //stan niski na PB0 dioda czerwona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         r=ADCW;                                 //wpisz wartość z przetwornika do zmiennej r (r -czerwona)
         PORTD |=_BV(PD0);                       //stan wysoki na Pb0 dioda czerwona zgaszona
      
    
       
         PORTD &= ~(_BV(PD1));                   //stan niski na PB1 dioda zielona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         g=ADCW;                                 //wpisz wartość z przetwornika do zmiennej g (g -zielona)
         PORTD |=_BV(PD1);                       //stan wysoki na Pb1 dioda zielona zgaszona
       
    
       
         PORTD &= ~(_BV(PD2));                   //stan niski na PB1 dioda niebieska zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         b=ADCW;                                 //wpisz wartość z przetwornika do zmiennej b (b -niebieska)
         PORTD |=_BV(PD2);                       //stan wysoki na Pb1 dioda niebieska zgaszona
       
       
        if(bit_is_clear(PINB, 0))                //jeśli na PB0 stan niski
        {
         PORTD &= ~(_BV(PD3);                    //stan niski na PD3 dioda bezczynności zaświecona
         _delay_ms(1000);
         PORTD |=_BV(PD3);                       //stan wysoki na PD3 dioda bezczynności zgaszona
         _dealy_ms(1000);
        }
     
     
      if(r>g)                 //jeśli r jest wieksze od g to                               
      {
       max=r;                //wartość w zmiennej r jest przypisana do zmiennej max
      }
      if(max==r)               //jeśli max=r
      {
       PORTD &= ~(_BV(PD4);  //to zmień stan PD4 na wysoki
      }
      else
      {
       max=g;                //jeśli r nie jest wieksze od g to max=g
      }
      if(max==g)               //jesli max=g
      {
       PORTD &= ~(_BV(PD5);  //to Zmien stan PD5 na wysoki
      }
      if(b>max)               //jeśli b jest wieksza od max to
      {
       max=b;                //wartość w zmiennej b jest przypisana do zmiennej max
      }
      if(max==b)               //jesli max=b
      {
       PORTD &= ~(_BV(PD6);  //to zmien stan PD6 na wysoki
      }
      return 0;
     }
    }
    
    
  • #7 8716001
    rpal
    Poziom 27  
    tmf napisał:
    Pomysł ciekawy, ale widzę pewien problem - zakładasz, że przedmiot odbija światło tylko o jednym kolorze. A co jeśli np. przedmiot ma kolor zielony, a nie powstający jako czysta barwa, tylko ze zmieszania żółtego i niebieskiego? Wtedy będziesz miał wysoki sygnał w kanale niebieskim i stosunkowo wysoki w czerwonym. To samo dotyczy oczywiście innych mieszanek. Różne farby mają czasami dosyć złożone widmo - warto więc sprawdzić na spektrofotometrze farby, których używasz.

    a ja dodam jeszcze coś takiego jak czułość na określoną długość długośc fali. Proponuje koledze poczytać o światłomierzach fotograficznych dla fotografi kolorowej jest tam opisana zasada działania tego ustrojstwa i wyznaczania temperatury światła. O ile pamietam fotorezystory - para są oświetlane przez 2 filtry purpurowy i tzw pawi czyli niebiesko-zielony i przez odpowiednie porónanie napięc wyznacza jest barwa światła. Szczegółow nie pamietam. I pomyslał bym o korekcji odczytów z fotorezystora bo jeden i drugi napewno nie będą takie same.
  • Pomocny post
    #8 8716469
    Konto nie istnieje
    Konto nie istnieje  
  • #9 8717312
    avo3
    Poziom 11  
    if(r>g)                 //jeśli r jest wieksze od g to                               
      {
       max=r;                //wartość w zmiennej r jest przypisana do zmiennej max
      }
      if(max==r)               //jeśli max=r
      {
       PORTD &= ~(_BV(PD4);  //to zmień stan PD4 na wysoki
      }
      else
      {
       max=g;                //jeśli r nie jest wieksze od g to max=g
      }
      if(max==g)               //jesli max=g
      {
       PORTD &= ~(_BV(PD5);  //to Zmien stan PD5 na wysoki
      }
      if(b>max)               //jeśli b jest wieksza od max to
      {
       max=b;                //wartość w zmiennej b jest przypisana do zmiennej max
      }
      if(max==b)               //jesli max=b
      {
       PORTD &= ~(_BV(PD6);  //to zmien stan PD6 na wysoki
      } 

    Tak zgadzam się jest tutaj błąd tylko nie wiem w jaki sposób porównać ze sobą
    te trzy wartości zmiennych zebranych z ADC i w zależności czy największa to r czy g czy b wystawić stan wysoki na odpowiednim pinie PD4 bądź PD5 bądź PD6
  • Pomocny post
    #10 8717637
    Andrzej__S
    Poziom 28  
    Chciałbym jeszcze zauważyć, że teoretycznie mogą zdarzyć się sytuacje: r=b lub b=g lub r=g lub nawet wszystkie jednocześnie. Prawdopodobieństwo może niewielkie, ale program powinien chyba brać to pod uwagę?
  • Pomocny post
    #11 8718339
    sulfur
    Poziom 24  
    Proponuję:
    if (r >=g && r >= b)
        PORTD |= _BV(PD4)


    Analogicznie dla "g" i "b". Należy także gasić wszystkie diody przed sprawdzaniem warunków. Założyłem, że stan wysoki na porcie zapala diody. Jeśli zachodzą warunki podane przez kolegę Andrzej_S, to zapalają się te diody, które są równe pod warunkiem, że są to wartości największe.
  • #12 8718690
    avo3
    Poziom 11  
    Poprawiłem program według rady kolegi sulfur ustawiłem na początku stan niski na liniach PD4 PD5 i PD6. Po rozpoznaniu koloru przedmiotu jedno lub w szczególnym przypadku 2 wyjścia (PD4 PD5 PD6) zmieniają swój stan na wysoki w zależności od koloru.
    Znalazłem podobny projekt http://www.robotroom.com/ColorSensor.html ,ale bez kodu do uprocesora.

    Czy tak powinien wyglądać zmodyfikowany program?

    
    #include <avr/io.h>
    #include <until/delay.h>
    
    unsigned int r, g, b, max;                  //zmienne
    
    int main()
    {
     TCCR0 |= ((1 << CS00) | (1 << CS02));       //Ustawia timer0 z preskalerem Fcpu/1024
     DDRB=0;                                     //linie portu B wejściowe
     PORTB=0x01;                                 //stan wysoki na lini PB0
     DDRD=0xFF;                                  //linie PD0 PD1 PD2 PD3 PD4 PD5 PD6 wyjściowe
     PORTD=0x07;                                 //stan wysoki na liniach PD0 PD1 PD2 stan niski na pozostałych
     ADMUX=0;                                    //wybierz kanał 0 przetwornika ADC
     ADCSR = _BV(ADEN)|_BV(ADSC)|_BV(ADFR)|_BV(ADIE)|_BV(ADPS1)|_BV(ADPS1)|_BV(ADPS0);
                                                 //włączenie przetwornika
                                                 //rozpocznij konwersję
                                                 //tryb samobieżny
                                                 //uruchom generowanie przerwań
                                                 //częstotilwość taktowania F_ADC=F_CPU/64 przy F_CPU=8MHz : F_ADC=125 kHz
     while(1)
     {
         PORTD &= ~(_BV(PD0));                   //stan niski na PB0 dioda czerwona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         r=ADCW;                                 //wpisz wartość z przetwornika do zmiennej r (r -czerwona)
         PORTD |=_BV(PD0);                       //stan wysoki na Pb0 dioda czerwona zgaszona
      
    
       
         PORTD &= ~(_BV(PD1));                   //stan niski na PB1 dioda zielona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         g=ADCW;                                 //wpisz wartość z przetwornika do zmiennej g (g -zielona)
         PORTD |=_BV(PD1);                       //stan wysoki na Pb1 dioda zielona zgaszona
       
    
       
         PORTD &= ~(_BV(PD2));                   //stan niski na PB1 dioda niebieska zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         b=ADCW;                                 //wpisz wartość z przetwornika do zmiennej b (b -niebieska)
         PORTD |=_BV(PD2);                       //stan wysoki na Pb1 dioda niebieska zgaszona
       
       
        if(bit_is_clear(PINB, 0))                //jeśli na PB0 stan niski
        {
         PORTD &= ~(_BV(PD3);                    //stan niski na PD3 dioda bezczynności zaświecona
         _delay_ms(1000);
         PORTD |=_BV(PD3);                       //stan wysoki na PD3 dioda bezczynności zgaszona
         _dealy_ms(1000);
        }
     
      if(r >=g && r >=b)
       {
        PORTD |= _BV(PD4);
        _delay_ms(3000);
        PORTD &= ~(_BV(PD4));
       }
      if(g >=r && g >=b)
       {
        PORTD |= _BV(PD5);
        _delay_ms(3000);
        PORTD &= ~(_BV(PD5));
       }
      if(b >=r && b >=g)
       {
        PORTD |= _BV(PD6);
        _delay_ms(3000);
        PORTD &= ~(_BV(PD6));
       }
         
      return 0;
     }
    }
    
    
  • #13 8718954
    Konto nie istnieje
    Konto nie istnieje  
  • #14 8719039
    avo3
    Poziom 11  
    Dodałem resetowanie po delay 2 post powyżej ten czas wysterowania wyjścia w zupełności mi wystarczy chyba dobrze to zrobiłem?
    Co do tego przycisku to program ma być wykonywany jeśli przycisk jest nie naciśnięty w przypadku naciśnięcia dioda bezczynności mruga i układ oczekuje na położenie klocka i zbadanie jego barwy. Krańcówkę mogę podłączyć NC lub NO bez problemu.
  • Pomocny post
    #15 8719063
    sulfur
    Poziom 24  
    W takich okolicznościach przycisk na podstawie załączonego kodu nie działa prawidłowo. W ogóle, to pragnę zauważyć, że za daleko kolega zajechał z pętlą zamykającą while, dlatego w każdym przypadku program wykonuje się tylko raz, po uruchomieniu uC.
  • Pomocny post
    #16 8719191
    Konto nie istnieje
    Konto nie istnieje  
  • #17 8719306
    avo3
    Poziom 11  
    Czy tak ma być?

    #include <avr/io.h>
    #include <until/delay.h>
    
    unsigned int r, g, b, max;                  //zmienne
    
    int main()
    {
     TCCR0 |= ((1 << CS00) | (1 << CS02));       //Ustawia timer0 z preskalerem Fcpu/1024
     DDRB=0;                                     //linie portu B wejściowe
     PORTB=0x01;                                 //stan wysoki na lini PB0
     DDRD=0xFF;                                  //linie PD0 PD1 PD2 PD3 PD4 PD5 PD6 wyjściowe
     PORTD=0x07;                                 //stan wysoki na liniach PD0 PD1 PD2 stan niski na pozostałych
     ADMUX=0;                                    //wybierz kanał 0 przetwornika ADC
     ADCSR = _BV(ADEN)|_BV(ADSC)|_BV(ADFR)|_BV(ADIE)|_BV(ADPS1)|_BV(ADPS1)|_BV(ADPS0);
                                                 //włączenie przetwornika
                                                 //rozpocznij konwersję
                                                 //tryb samobieżny
                                                 //uruchom generowanie przerwań
                                                 //częstotilwość taktowania F_ADC=F_CPU/64 przy F_CPU=8MHz : F_ADC=125 kHz
     while(1)
     {
      if(bit_is_clear(PINB, 0))                //jeśli na PB0 stan niski
        {
         PORTD &= ~(_BV(PD3);                    //stan niski na PD3 dioda bezczynności zaświecona
         _delay_ms(1000);
         PORTD |=_BV(PD3);                       //stan wysoki na PD3 dioda bezczynności zgaszona
         _dealy_ms(1000);
        }
      else
       {
         PORTD &= ~(_BV(PD0));                   //stan niski na PB0 dioda czerwona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         r=ADCW;                                 //wpisz wartość z przetwornika do zmiennej r (r -czerwona)
         PORTD |=_BV(PD0);                       //stan wysoki na Pb0 dioda czerwona zgaszona
      
    
       
         PORTD &= ~(_BV(PD1));                   //stan niski na PB1 dioda zielona zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         g=ADCW;                                 //wpisz wartość z przetwornika do zmiennej g (g -zielona)
         PORTD |=_BV(PD1);                       //stan wysoki na Pb1 dioda zielona zgaszona
       
    
       
         PORTD &= ~(_BV(PD2));                   //stan niski na PB1 dioda niebieska zaswiecona
         _delay_ms(1000);
         int value = ((ADCH << 8) | (ADCL));     //czytaj wartość z przetwornika ADC
         b=ADCW;                                 //wpisz wartość z przetwornika do zmiennej b (b -niebieska)
         PORTD |=_BV(PD2);                       //stan wysoki na Pb1 dioda niebieska zgaszona
       
         PORTD &= ~(_BV(PD4));
         PORTD &= ~(_BV(PD5));
         PORTD &= ~(_BV(PD6));
     
         if(r >=g && r >=b)
         {
          PORTD |= _BV(PD4);
         }
         if(g >=r && g >=b)
         {
          PORTD |= _BV(PD5);
         }
         if(b >=r && b >=g)
         {
          PORTD |= _BV(PD6);
         }
       } 
     } 
      return 0;
     
    }
    
    
    
  • Pomocny post
    #18 8720222
    Konto nie istnieje
    Konto nie istnieje  
  • #19 8720938
    avo3
    Poziom 11  
    Czy tak dobrze wstawiłem void adc_init(void)
    #include <avr/io.h>
    #include <until/delay.h>
    
    unsigned int r, g, b, max;                  //zmienne
    
    int main()
    {
     DDRB=0;                                     //linie portu B wejściowe
     PORTB=0x01;                                 //stan wysoki na lini PB0
     DDRD=0xFF;                                  //linie PD0 PD1 PD2 PD3 PD4 PD5 PD6 wyjściowe
     PORTD=0x07;                                 //stan wysoki na liniach PD0 PD1 PD2 stan niski na pozostałych
     ADCSRA = (1 << ADEN);
     ADCSRA |=  (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2);
     ADMUX |= (1 << REFS0)  ;                  //Aref = vcc / kanał 0 domyślnie
    
     while(1)
     { 
      if(bit_is_clear(PINB, 0))                  //jeśli na PB0 stan niski
        {
         PORTD &= ~(_BV(PD3);                    //stan niski na PD3 dioda bezczynności zaświecona
         _delay_ms(1000);
         PORTD |=_BV(PD3);                       //stan wysoki na PD3 dioda bezczynności zgaszona
         _dealy_ms(1000);
        }
      else
       {
         PORTD &= ~(_BV(PD0));                   //stan niski na PB0 dioda czerwona zaswiecona
         ADCSRA |=(1 << ADSC) ;                  //start 
    	 while (ADCSRA & (1<< ADSC) );           //czekanie na wynik 
    	 r = ADCW                                 //czytaj wartość z przetwornika ADC 
         PORTD |=_BV(PD0);                       //stan wysoki na Pb0 dioda czerwona zgaszona
      
    
       
         PORTD &= ~(_BV(PD1));                   //stan niski na PB1 dioda zielona zaswiecona
         ADCSRA |=(1 << ADSC) ;                  //start 
    	 while (ADCSRA & (1<< ADSC) );           //czekanie na wynik 
    	 g = ADCW                                 //czytaj wartość z przetwornika ADC 
         PORTD |=_BV(PD1);                       //stan wysoki na Pb1 dioda zielona zgaszona
       
    
       
         PORTD &= ~(_BV(PD2));                   //stan niski na PB1 dioda niebieska zaswiecona
         ADCSRA |=(1 << ADSC) ;                  //start 
    	 while (ADCSRA & (1<< ADSC) );           //czekanie na wynik 
    	 b = ADCW                                 //czytaj wartość z przetwornika ADC 
         PORTD |=_BV(PD2);                       //stan wysoki na Pb1 dioda niebieska zgaszona
       
         PORTD &= ~(_BV(PD4));
         PORTD &= ~(_BV(PD5));
         PORTD &= ~(_BV(PD6));
     
         if(r >=g && r >=b)
         {
        PORTD |= _BV(PD4);
         }
         if(g >=r && g >=b)
         {
         PORTD |= _BV(PD5);
         }
         if(b >=r && b >=g)
         {
         PORTD |= _BV(PD6);
         }
       } 
     } 
      return 0;
     
    }
    
  • Pomocny post
    #20 8721002
    Konto nie istnieje
    Konto nie istnieje  
  • #21 8721033
    avo3
    Poziom 11  
    Dzięki czy program tak jak zmieniony powyżej powinien już działać poprawnie oczywiście teoretycznie ?
  • #22 8721056
    Konto nie istnieje
    Konto nie istnieje  
REKLAMA