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

[AVR][ATtiny25][ADC] odczyt z 2 kanalow

m_misek 31 Gru 2010 02:16 1646 4
REKLAMA
  • #1 8937836
    m_misek
    Poziom 11  
    Witam
    Mam ja sobie taki oto kod :
    #include <avr/interrupt.h>
    #include <avr/io.h>
    
    #define XX 10
    
    int pomiar=0;
    int ilosc_pomiarow=XX;
    int temp;
    
    int main(void)
    {
    	//PORTS
    	DDRB = (1<<PB0 )| (1<< PB1 );
    	//ADC
    	ADMUX=2;
    	ADCSRA= ( 1<<ADPS0)|(1<<ADPS1) | ( 1<< ADPS2);//ADC clock = F_CPU/128
    	ADCSRA|= (1<<ADSC)|( 1<<ADEN) | ( 1<<ADIE);//ADC enable + IRQ enable
    	//TIMER 
    	TCCR0B = ( 1<< CS02) |( 0<< CS01) | ( 0<< CS00);
    	TIMSK = ( 1<< TOIE0) | ( 1<<OCIE0A) | ( 1<< OCIE0B);
    	sei();
    	while(1);
    
    
    
    
    }
    ISR(TIM0_COMPA_vect)
    {
    	PORTB &= ( 0<<PB0);
    }
    ISR(TIM0_COMPB_vect)
    {
    	PORTB &= ( 0<<PB1);
    }
    ISR (TIM0_OVF_vect)
    {
    	PORTB |= ( 1<<PB0 ) | ( 1<<PB1);
    }
    
    ISR(ADC_vect)
    {
    	pomiar+=ADC;
    	if(--ilosc_pomiarow==0)
    		{
    		switch (ADMUX)
    			{ 
    			case 1: 
    				OCR0B=pomiar/XX/4;
    				ADMUX =2;
    				break;
    			case 2:
    				temp = pomiar/XX;
    				if (temp <250) OCR0A=15;
    					else
    				 if (temp >350) OCR0A=5;
    				 	else OCR0A=10;
    				ADMUX =3;
    				break;
    			case 3:
    				//OCR0B=pomiar/XX/4;
    				ADMUX =1;
    				break;
    			default :
    				 break;
    			}
    		ilosc_pomiarow=XX;
    		pomiar=0;
    		}
    	ADCSRA |= (1<<ADSC);
    }
    
    

    Pod PB0 podłączone serwo. Kanał 1 ADC to akcelerometr, kanał drugi to potencjometr, 3 chwilowo nie wykorzystywany.
    Jak widać... ma się odbywać 10 krotny pomiar z każdego z kanałów po czym jakaś tam zmiana na wyjściu ( nieważne jaka ). Wszystko działa dobrze dopóki mam w kodzie wykreśloną linie :
    OCR0B=pomiar/XX/4;

    Jeśli ją wpisze, serwo zaczyna wariować, ( tak działa dobrze ) wykonuje jakieś dziwne ruchy jednakże można nim jeszcze jako tako sterować no ale włączenie potencjometru wprowadza zakłócenia do niego. Przy czym przy niektórych ( skrajnych ) ustawieniach potencjometru nie da się już w ogóle sterować serwem.
    Pomiędzy pinami wyjściowymi brak zwarć, wejściowymi też.
    Zapewne jest gdzieś błąd podczas zmieniania kanałów ADC bądź przy Timerze ale nie potrafię go zlokalizować, więc liczę na jakaś podpowiedź.
    F_cpu = 2 MHz, VCC=5V ( zasilanie z USB)
  • REKLAMA
  • REKLAMA
  • #3 8939449
    m_misek
    Poziom 11  
    wszystko liczone jest w przerwaniu.
    Na poczatku sumowanie 10 pomiarow a potem w switchu jest linijka :
    OCR0B=pomiar/XX/4;
    czyli to co namierzone przez liczbe pomiarow i potem przez 4 jeszcze.
  • REKLAMA
  • #4 8939562
    LordBlick
    VIP Zasłużony dla elektroda
    A atrybut volatile dla "ilosc_pomiarow" gdzie ? Skąd pewność, że suma wszystkich pomiarów nie przepełnia wartości tej zmiennej ?
  • #5 8939639
    m_misek
    Poziom 11  
    wartosc "ilosc_pomiarow" to ledwie 10, a zmienna ta to int wiec chyba sie jednak miesci. Zmienna ta jest jedynie dekrementowana po czym znowu ustawiane jest 10. nie mam mowy o przepelnieniu.
    natomiast "pomiar" w ktorym jest suma wszystkich pomiarow to tez int i w niej jest maksymalnie 10*1024 czyli ilsoc pomiarow razy maksymalna wartosc dla przetwornika. wiec zmiescie sie nawet w signed int.
REKLAMA