Lettura analogica. (RISOLTO)

Salve ragazzi, era da un pò che non tornavo sul forum...
Ultimamente mi stavo dedicando al linguaggio C tradizionale, (sono troppo tentato da usare l'atmega 164p e programmarlo tramite AVR studio),
Così ho cominciato a giocare con i registri ecc ecc, basandomi sul datasheet del 328p-pu ,(ho scelto questo coichè potessi usare direttamente arduino).
Ho provato a fare una lettura analogica, però non capisco il perchè il controllore non legge niente e quidi non mi riempie i registri ADCH ed ADCL restituendomi sulla seriale sempre e solo "0"..
Questo è il codice che ho utilizzato;

uint16_t analogico(byte c){
  uint16_t x=0;
ADMUX |= 0b01000000;
ADMUX &=0b01010000;
ADCSRA |=0b10000000;
ADCSRA |=0b01000000;
while(ADCSRA&0b00010000==0);
x=
return(ADCH*256+ADCL);
}
void setup(){
  Serial.begin(9600);
}
void loop(){
  Serial.println(analogico(0),DEC);
delay(100);
}

Potreste darmi una mano?

RISOLTO, posto il codice.
Ho usato le funzioni di arduino (void setup, loop, serial) per poter usare la seriale.
Consiglio l'utilizzo del datasheet dell'atmega 328p-pu nella parte "analog-to-digital-converter.

int x; // variabile a 16 bit che conterrà il valore letto.

void setup(){
  Serial.begin(9600); // inizializzazione seriale
  
  ADMUX=0x40;         // Setto il riferimento della tenzione (5v in questo caso). Setto il riempimento a destra o sinistra, (in questo caso a destra), dei registri che conterranno il valore letto (ADCL-ADCH).
                      // Seleziono il canale da leggere (in questo caso 0, corrispondente ad A0).
                
  ADCSRA &=0xf8;      // Imposto il prescaler a 2. ( Ogni due colpi di clock esegui l'operazione, lasciandolo invariato si importa automaticamente a 128 tramite le fuznioni di arduino.)
  ADCSRA |=1<<ADEN;   // Abilito il convertitore analogico-digitale(A-D).
}

void loop(){

  ADCSRA |=1<<ADSC;  // Avvio la conversione A-D, Ogni qualvolta finisce la conversione, questo bit ritorna 0, Quindi, lo forzo nuovamente ad 1 per poter eseguire dinuovo la lettura analogica.
  
  while((ADCSRA & (1<<ADIF)) ==0);  // il bit ADIF si resetta quando la conversione è finita, quindi, fino a quando la conversione non è finita,(fino a quando non trovo 0), non andare oltre nel programma.
  
  x=ADCL+ADCH*256; // Per poter assegnare alla variabile, il risultato della conversione, (contenuto in due registri ad 8 bit), siccome il riempimento dei registri è impostato a destra,
                   // (questo per poter avere un valore a 10 bit anzicchè 8), bisogna leggere per primo il registro ADCL, (la parte meno significativa del risultato), altrimenti il microcontgrollore
                   // Blocca automaticamente l'accesso al registro ADCH che contiene la parte più significativa del valore letto.
                   // Moltiplico ADCH per 256 in modo tale da spostare in avanti il valore di 8 posizioni,(si può usare la funzione shift ma andrebbero usate altre variabili).
                   // In fine sommo il contenuto dei registri ADCL e ADCH e metto il risultato nella variabile "x" a 16bit.


  Serial.println(x,DEC); // Stampo sulla seriale il valore di "x" in decimale.
}

TI consiglio di dare un'occhiata al codice contenuto nel file /hardware/arduino/cores/arduino/wiring_analog.c dove c'è la procedura di lettura di un pin analogico effettuata quando chiami la funzione analogRead.

Grazie epr la risposta veloce!!! Beh.. Ho capito un pò di cose, anche se alcune non mi sono molto chiare.. Però, non capisco come mai il codice che avevo fatto io non mi dà alcun risultato...

Non so, non ho analizzato cosa fa il tuo codice con i registri che manipoli.

Che succede se
ADCSRA |=0b01000000;
diventa
ADCSRA &=0b01000000;
?

Che cambia il senso dell'operazione. La prima mette a 1 il 7° bit indipendentemente dal suo stato, mentre la seconda intanto lascia a 1 il 7° bit solo se è già ad 1 e poi pone a 0 tutti gli altri bit anche se erano accesi.
Non si dovrebbero mai manipolare così i registri ma sempre usando direttamente i flag dichiarati dal compilatore oppure impostando i singoli bit con le operazioni apposite.
Ad esempio, per mettere ad 1 il 7° bit, che corrisponde al flag ADSC, del registro ADCSRA si dovrebbe usare la seguente sintassi:
ADCSRA |= (1<<ADSC)
per metterlo a 0:
ADCSRA &= ~(1<<ADSC)

Intendevo dire che:
ADCSRA |=0b10000000;
ADCSRA |=0b01000000;
a me sembrano due istruzioni identiche con valori diversi, pensavo che la seconda sovrascrivesse la prima, ma è solo la deduzione dell'ignoranza in materia. :grin:

Impostano la prima l'8° bit, la seconda il 7°. Ma come ho detto, è bene sempre non manipolare in questo modo i bit. Con l'OR non succede nulla, con l'AND tocchi anche i bit che a te non interessano.

up.

j84c3:
up.

Riferito a cosa?

all'aggiornamento, ho modificato il post iniziale scrivendo il codice giusto con tanto di appunti :slight_smile:

Quando modifichi un post, il thread viene automaticamente messo in cima alla lista e segnalato come "new", non c'è bisogno di uppare la discussione (che poi non è consentito dal regolamento :stuck_out_tongue: ).

ah, chiedo umilmente scusa T__T