AtMega88 - Zapnuti/vypnuti Ad prevodniku.

Zdravim. O vikendu jsem vam tu polozil jednu otazecku s delicem a bavili jsme se take o akcelerometru a ad prevodnicich. Ted mam ale na vas dotaz.

Jak zakazat ad prevodnik. Taky by se mi mel spustit prevod az po splneni podminky, ale me se proste ISR (adc_vect) vykona, ikdyz podminka neni splnena - if (bit_is_clear(PIND,2)) -

Inicializaci prevodniku mam v mainu pred smyckou while(1).

nemuze byt nejaka chyba s prekladacem, optimalizace atd?

Taky by me zajimalo jak ad prevodnik vypnout, zadne nulovani ADENu nefunguje

Diky

jeste sem pridavam kod aby jste tam videli ty podminky vsecky. No a proste hned jak prijmu dato 30h tak akcelerometr snima (vykonava se ISR pro ADC) a to ikdyz mam na pind 2 sdelanou propojku. ktera propojuje na GND

[code]void checkC2C()
{
if (bit_is_clear(PIND,4))//jeli spojen okruh, je nula na pin 4
{
c2c=0x88; //a zapise 88h do c2c, ktere odesle jak pretece citac
//LED_ON();
}
}

void checkC1O()
{
if (bit_is_set(PIND,3))//jeli otevren okruh, je nula na pin 3
{
c1o=0x34; //a zapise 34h do c1o, ktere odesle jak pretece citac
//LED_OFF();
}
}

void checkACM()
{
ADCSRA|=0b01000000; //logicky soucet pro registr k spusteni prevodu. Po dokonceni prevodu vyvola vector preruseni
prevod=1; //uvedeni prevodu do jedna, aby se pak neopakovalo volani funkce a tim by se stale zacinal prevod
sei() ; //povoli vsechna preruseni
}

int main(void)
{
unsigned int data,i,j;
portInit(); //inicializace portu
rfInit(); //inicializace transceiveru
ADCSRA=0b10001100; //zapnuti ad prevodniku, povoleni preruseni po dokonceni prevodu a nastaveni rychlosti prevodu
ADMUX |= (1<<REFS0) | (1<<REFS1);
FIFOReset();
while(1)
{
if (otocit==0)
{
FIFOReset();
while((data = rfRecv() ) != 0) //jeli NEnulovy prijem, skoc dovnitr a vykonej
{
if (data==0x30) // 30h posila pager pro navazani spojeni
{
otocit=1; // a tim se otevre odesilani dat kde odesle 31h jako odpoved ACK, spojeni ok
prevod=0;
}

			if (data==0x32) // 32h posila pager pro vzdalene vypnuti posilani dat
			{
				cli(); // zakaze vsechny preruseni, tim padem i od casovace a prestane posilat data
				LED_OFF();
				otocit=0; // po ukonceni zustan v rezimu prijmace a toc se tady {muzes prijmout 30h nebo 32h}
				c1o=0;	//vynulovani stavu senzoru
				c2c=0;  //vynulovani stavu senzoru
				acm=0;
				//bat=0;
				kanal=0; //kanal do nuly, aby zacinal pak s nultym kanalem - X
				mereni=0; //znuluje mereni abych pak mohl met vychozi jinou polohu
				prevod=1; //k nenastartovani prevodu
			}	
		}
	}

	FIFOReset();

	if (otocit==1)
	{
		writeCmd(0x8239); //stan se VYSILACEM
		
		//_delay_ms(2000); //pauza pred vysilanim, nechapu proc, ale dulezita, bez ni to neslo
		
		for(i=0;i<1000;i++) // prasacke, ale musim i tu nejak kontrolovat vstupy, cili misto delay 2000
			for(j=0;j<200;j++) //bylo trista, snazit se dat co nejnize
			{
				if (bit_is_clear(PIND,0))
					checkC1O(); //testuje otevreni dratu porad, kazdou vterinu odesle data na pager
				if (bit_is_clear(PIND,1))
					checkC2C(); //testuje spojeni dratu porad, kazdou vterinu odesle data na pager
				
			}
			
		writeCmd(0x0000);
		cli(); //zakazani vsech preruseni {ani citac neprerusi}
	
		rfSend(0xAA); // PREAMBLE
		rfSend(0xAA);
		rfSend(0xAA);
		rfSend(0x2D); // SYNC
		rfSend(0xD4);
		rfSend(0x31); // dato o spojeni, tzv ACK
		rfSend(c2c); //dato o spojeni okruhu
		rfSend(c1o); //dato o rozspojeni okruhu
		rfSend(bat); //dato o vybijejici se baterii
		rfSend(acm); //dato o pohnuti acm
		rfSend(0xAA); // PREAMBLE
		rfSend(0xAA);
		rfSend(0xAA);
		
		otocit=0;
		c1o=0;	//vynulovani stavu senzoru
		c2c=0;  //vynulovani stavu senzoru
		acm=0;
		bat=0;
		writeCmd(0x8299); //stan se PRIJIMACEM

		sei(); //povoleni vsech preruseni {pro povoleni casovace} 
	
		if (citac==0) // zapnuti casovace
		{
			TCCR1B |= (1<<CS10);//|(1<<CS11); //nastaveni preddelicky na 64. Zakladni cas je cca 4,2s 
			TIMSK1 |= (1<<TOIE1); //pro vector preteceni v ISR
			citac=1; //aby neinicializoval casovac pokazdem odeslani dat
		}
	}

	if (bit_is_clear(PIND,0))
		checkC1O(); //testuje otevreni dratu porad, kazdou vterinu odesle data na pager
	
	if (bit_is_clear(PIND,1))
		checkC2C(); //testuje spojeni dratu porad, kazdou vterinu odesle data na pager

	if (bit_is_clear(PIND,2)) // Propojka pro ACM nasazena
	{
		if (prevod==0)
		checkACM(); //testuje akcelerometr, zda se pohl
	}
	if (bit_is_set(PIND,2)) // Propojka pro ACM sundana
	{
		LED_OFF(); //konrolni led zhasni
		cli(); //zakaz preruseni - zvazit zdali by nestacilo nastavenim prislusneho registru vypnout AD.
		kanal=0; //kanal do nuly, aby zacinal pak s nultym kanalem - X
		mereni=0; //znuluje mereni abych pak mohl met vychozi jinou polohu
		prevod=1; //nastartovani prevodu
	}
}
return 0;

}

ISR( TIMER1_OVF_vect ) //pri preteceni casovace se zavola tento vector preruseni a vykona se
{
//preteceli casovac, a bude v c1o NEBO v c2c 34h nebo 88h, tak nastav otocit do 1
//a tim se odeslou data
if (c1o==0x34 || c2c==0x88 || acm==0x53 || bat==0xB1 || bat==0xB2 || bat==0xBE)
otocit=1;
}

ISR( ADC_vect )
{

int d_hranice,h_hranice;

int	aktualni=ADCW; //zde se nahraje hodnota prevodu-aktualni
		
if (kanal==0 && mereni==0)     //vykonace se jen na zacatku, je to ulozeni vychozi
	predchozi_ADCW_x=aktualni; //hodnoty X se kterou se pak porovnavat bude

if (kanal==0 && mereni==1)	//az v druhem kole, kdy mereni je jedna, 
{							//mereni se nastavi na jedna az po prepnuti zase na nulty kanal
	h_hranice=predchozi_ADCW_x+CITLIVOST;
	d_hranice=predchozi_ADCW_x-CITLIVOST;
	
	if (d_hranice<aktualni && aktualni<h_hranice)
		{LED_ON();}
		else{
		 	LED_OFF();
			acm=0x53;
			}
}


if (kanal==1 && mereni==0) 	   //vykonace se jen na zacatku, je to ulozeni vychozi 
	predchozi_ADCW_y=aktualni; //hodnoty Y se kterou se pak porovnavat bude
   
if (kanal==1 && mereni==1)	//az v druhem kole, kdy mereni je jedna, 
{							//mereni se nastavi na jedna az po prepnuti zase na nulty kanal
	h_hranice=predchozi_ADCW_y+CITLIVOST;
	d_hranice=predchozi_ADCW_y-CITLIVOST;

	if (d_hranice<aktualni && aktualni<h_hranice)
		{LED_ON();}
	 	else{
		  	LED_OFF();
	  		acm=0x53;
			}
}


if (kanal==2 && mereni==0) 	   //vykonace se jen na zacatku, je to ulozeni vychozi
	predchozi_ADCW_z=aktualni; //hodnoty Z se kterou se pak porovnavat bude
   
if (kanal==2 && mereni==1)  //az v druhem kole, kdy mereni je jedna, 
{							//mereni se nastavi na jedna az po prepnuti zase na nulty kanal
	h_hranice=predchozi_ADCW_z+CITLIVOST;
	d_hranice=predchozi_ADCW_z-CITLIVOST;

	if (d_hranice<aktualni && aktualni<h_hranice)
		{LED_ON();}
	 	else{
			LED_OFF();
	  		acm=0x53; 
			}
}


//_delay_ms(10); //kratka prodleva abych videl zmen, pak smazat  

kanal++; //k prepnuti na dalsi kanal


if (kanal==1)
	ADMUX=(1<<REFS0)|(1<<REFS1)|(1<<MUX0); // kanal 01 - Y
if (kanal==2)
	ADMUX=(1<<REFS0)|(1<<REFS1)|(1<<MUX1)|(0<<MUX0); // kanal 02 - Z
if (kanal==3)
{
	ADMUX=(1<<REFS0)|(1<<REFS1)|(0<<MUX1)|(0<<MUX0); // zpet kanal 00 - X
	kanal=0;
	mereni=1; // mereni do jedna, pac uz byly zjisteny a ulozneny vychozi hodnoty
}

	

ADCSRA|=0b01000000;//znovu spusteni dalsiho prevodu

}[/code]

Převodník není třeba zakazovat. Stačí ho nespouštět.
Ty máš v ISR(ADC) příkaz ke spuštění převodu, takže převody běží nepřetržitě bez ohledu na nějaké podmínky v main().

ok, to se na to podivam, ale jak se to do toho isr vubec muze dostat pred spustenim prvniho prevodu? jeste nad tim mainem mam prece funkci,
ktera se zavola v pripade ze je clearovan pd2 a jeste i prevod v nule, ktery jako jediny vyhovuje, kdyz dojde dato 30h.

Tak s tou podminkou problem vyresen. Ja vul sundaval jinou propojku cele odpoledne.

ALe jak vyresit ten prevodnik, aby se mi prepinaly kanaly… a pritom nedochazelo k znovu zapnuti… To nevim.

Prevod prece musim zapinat vzdy, ne?

pokud trvas na rychlosti, tak je lepsi prevod nechat bezet. prvni spusteni prevodniku je totiz vyrazne pomalejsi. nicmene kanaly prepinas skutecne pomoci zapisu do ADMUX a spousteni resi ADCSRA. ovsem tak jako tak se pri prepnuti (v kontinualnim rezimu hlavne) nevyhnes tomu, ze muze zustat v bufferu hodnota predchozi. proto je nutne dobre osetrit bit prevod dokoncen, coz je tusim ADIF. nicmene to ted lepim z hlavy a navic to delam v asm, tak si to radeji over.