Problém s A/D převodníkem, funguje pouze simulace s ATtiny24

Zdravím… mám trochu problém s A/D převodem, v simulátoru vše funguje, ale v reálu už pak ne.

Použivám MCU ATtiny24. Program má podle vstupního napětí na pinu AD převodníku vykonat různé funkce, ale jaksik nedělá nic.

[code]int main(void)
{
/Nastavení přerušení/
GIFR=(1<<PCIF0);
GIMSK=(1<<PCIE0);
PCMSK0=(1<<PCINT0);
sei();

/*Nastavení AD převodníku*/
ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); //povolení AD převodu, nastavení předděličky (8)
DDRA = 0b01000000;        //nastavení portu A (vstupy a výstupy)
    
ADMUX = 0x80;            //nastavení ADC , interních referenční napětí, vyběr vstupního kanálu ADC
ADCSRA |= (1 << ADSC);  // start konverze
while(!(ADCSRA & (1<<ADIF)));   // počkat na dokončení konverze 
ADCSRA |= (1<<ADIF);       // vynulovat flag (nuluje se zápisem "1") 
_delay_ms(3);            //zpoždění kvůli provedení AD převodu.
/*výběr funkce*/
if (ADCW >=3371)        
    {prvni();}             //provede se 1.fce


if ((ADCW >=1325)&(ADCW<3371))
    {druha();}             //provede se 2.fce

if (ADCW <1325)
     {treti();}            //provede se 3.fce   

}[/code]

Na pin AD převodníku je neustále přivedeno napětí, proto nevím jestli náhodou není chyba ve while(!(ADCSRA & (1<<ADIF))); kde se čeká na dokončení převodu?

:arrow_right: administrator: přejmenováno z "Problém s A/D převodníkem"

ADCSRB není nikde nastaven, takže ADLAR = 0. Z toho plyne, že výsledek může nabývat nejvyšší hodnotu 1023. Funkce 1 a 2 se nemohou nikdy vykonat.

no jasně… taková hlupá chyba. Ještě otázečka. Jaká bude nejmenší hodnota ADCW když zarovnám výsledek do leva (ADLAR=1)?

Taky 0, ale LSB bude 64 a maximální hodnata 64*1023. Jinak řečeno ADCW<<6.

No a když teda nastavím ADLAR=1 tak může ADCW nabývat stejných hodnot jako když je ADLAR=0? Nebo bude krok se kterým ADCW poroste roven 64? Pokud je LSB 64 tak se mi tím pak zmenší “rozlišovací” schopnost toho převodníku, nebo se pletu?

Nastavit ADLAR=1 a číst ADCW je nelogické.

Smysl zarovnání je tento:

Pokud požadujeme desetibitový výsledek převodu, nastavíme ADLAR=0
a hodnotu (0-1023) čteme z ADCW.

Pokud nám stačí osmibitový výsledek, nastavíme ADLAR=1
a hodnotu (0-255) čteme z ADCH.

ADCSRA |= (1 << ADSC); // start konverze while(!(ADCSRA & (1<<ADIF))); // počkat na dokončení konverze ADCSRA |= (1<<ADIF); // vynulovat flag (nuluje se zápisem "1") _delay_ms(3); //zpoždění kvůli provedení AD převodu.
Delay je tady zbytečné, dokončení převodu signalizuje bit ADIF.

Jednodušší je

ADCSRA |= (1 << ADSC); // start konverze while(ADCSRA & (1<<ADSC)); // počkat na dokončení konverze
Bit ADSC po dokončení převodu přechází do úrovně “0”.