Registro PINx ATMEGA328

Scusate, ero convinto di essere nella sezione italiana...ho sistemato la formattazione.
Ho aggiunto qualche nota di chiarimento.Grazie per la pazienza.

Buongiorno a tutti,
nel dubbio mi presento nuovamente :slight_smile: mi sto studiando il linguaggio C e le applicazioni per Arduino . Il tutto finalizzato alla creazione di automatismi per uso personale.
Avrei bisogno di un chiarimento (magari con un esempio) sul registro PINx (Writing to the pin register provides toggle functionality for IO)...non mi è chiaro come si comporta nello specifico.
Nel mentre, per cercare di capire le manipolazioni bit sui registri ho implementato il classico blink su Arduino Uno per vedere come variano i valori della PORTx e PINx al variare dello stato logico della porta. Oltre allo sketch, riporto anche un estratto preso dalla seriale . Mi è chiaro il valore di PORTB, quello che non capisco è il valore del PINB5 ( se non sbaglio corrisponde al pinarduino 13) che rimane sempre a 1. Volevo portarlo a "0". E' possibile? Su datasheet ATMEGA 328 si parla di sola lettura per il registro PINx, è corretto solo lettura?
Ho provato a mettere PORTB &=~(1<<PB5) ma non cambia, ho provato anche con PINB &= ~(1<<PB5)
Grazie per l'aiuto

void setup() {
  
  pinMode(8, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  digitalWrite(8, HIGH);
  Serial.println("leggo PORTB valore con HIGH");

  Serial.println(PORTB, BIN);
  delay(2000);
  Serial.println("leggo PINB valore con HIGH ");
  Serial.println(PINB, BIN);
  delay(2000);
  digitalWrite(8, LOW);
  Serial.println("leggo PORTB valore con LOW ");
  Serial.println(PORTB, BIN);
  delay(2000);
  Serial.println("leggo PINB valore con LOW ");
  Serial.println(PINB, BIN);
  
  delay(1000);
}






output monitor seriale

leggo PORTB valore con HIGH

1

leggo PINB valore con HIGH

100001

leggo PORTB valore con LOW

0

leggo PINB valore con LOW

100000

ti segnalo che, nella sezione in lingua Inglese, si p scrivere SOLO in Inglese... quindi, per favore, la prossima volta presta pu attenzione in quale sezione metti i tuoi post;questa volta esso e stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana... la prossima volta potrebbe venire direttamente eliminato

@manu68 : oltra all'annotazione che ti ha fatto qui sopra un altro moderatore, ti rammento che In conformità al REGOLAMENTO, fosse anche per una sola riga, il codice va racchiuso negli appositi tag ... :roll_eyes:

... cortesemente, quindi, edita il tuo post più sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone a forma di piccola matita :pencil2: che si trova in basso del tuo post), seleziona la parte di codice e premi l'icona </> nella barra degli strumenti per contrassegnarla come codice.

Inoltre, così com'è, non è molto leggibile ... assicurati di averlo correttamente indentato nell'IDE prima di inserirlo (questo lo si fa premendo ctrlT su un PC o cmd T su un Mac all'intero del IDE). Grazie. :slight_smile:

Guglielmo

Ciao, manu
A quanto pare, PORT legge solo i bit normalmente utilizzabili (da PB0 a PB5), mentre PIN legge anche PB6 e PB7 che normalmente sono riservati al quarzo.

Uhmm... No! In PIN è PB5 che sta a 1!...
E' come se lo avessi impostato come ingresso con pull-up...

Impostando 12 e 13 come output non succede più:

void setup() 
{  
  pinMode (8, OUTPUT);
  pinMode (12,OUTPUT);
  pinMode (13,OUTPUT);
  
  Serial.begin(9600);

  digitalWrite(8, HIGH);
  Serial.println("leggo PORTB valore con HIGH");

  Serial.println(PORTB, BIN);

  Serial.println("leggo PINB valore con HIGH ");
  Serial.println(PINB, BIN);

  digitalWrite(8, LOW);
  Serial.println("leggo PORTB valore con LOW ");
  Serial.println(PORTB, BIN);

  Serial.println("leggo PINB valore con LOW ");
  Serial.println(PINB, BIN);
}

void loop() {}
12:40:24.655 -> leggo PORTB valore con HIGH
12:40:24.689 -> 1
12:40:24.689 -> leggo PINB valore con HIGH 
12:40:24.722 -> 1
12:40:24.722 -> leggo PORTB valore con LOW 
12:40:24.757 -> 0
12:40:24.757 -> leggo PINB valore con LOW 
12:40:24.792 -> 0

Il microcontrollore è CMOS, con ingressi ad altissima impedenza che, se lasciati aperti, possono accumulare cariche elettriche e portarsi a livello alto. All'accensione, tutti i pin sono impostati come ingressi: se non li imposti come uscite, se vai a leggerne lo stato puoi trovare indifferentemente alto o basso. Io addirittura leggevo 110001!

12:41:49.876 -> leggo PORTB valore con HIGH
12:41:49.910 -> 1
12:41:49.910 -> leggo PINB valore con HIGH 
12:41:49.944 -> 110001
12:41:49.944 -> leggo PORTB valore con LOW 
12:41:49.978 -> 0
12:41:49.978 -> leggo PINB valore con LOW 
12:41:50.012 -> 110000

Perché PORT legga diversamente non lo so...

Grazie Datman,
mi puoi dare qualche esempio per capire la funzionalità toggle che non mi è chiara.

... prima di giocare con PIN e PORT bisognerebbe, quantomeno, studiarsi bene il datasheet!

14.2.2 Toggling the Pin

Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port.

Guglielmo

La cosa strana avviene leggendo PIN, non scrivendo...

Rispondevo alla sua domanda di come si fa il TOGGLE di pun pin, cosa prevista e documentata nel datasheet.

Ricordate che PINx è SOLO per lettura menre PORTx è SIA per scrittura che per lettura ...
... per evitare errori allego un bel documento scritto a suo tempo dal nostro Leo: Manipoliamo direttamente le porte logiche di una MCU.pdf (226.4 KB) :slight_smile:

Guglielmo

1 Like

... la mia domanda era per capire la funzionalità toggle (che azione compie il Toggle), che non mi è chiara e non di come si imposta.

grazie

Ah ... consiglio comunque anche un'attenta lettura di TUTTO il capitolo 14 del datasheet, capitolo interamente dedicato alle I/O-Ports, alla loro gestione ed al loro funzionamento :wink:

Guglielmo

... come dice la parola, effettua il toggle del pin, ovvero se era 1 va a 0 e se era 0 va a 1.

Guglielmo

Ciao Guglielmo, altra cosa che non capisco è :slight_smile: **
14.2.2 Toggling the Pin**

Writing a logic one to PINxn toggles ecc... poi nel post successivo affermi che il PINX è solo per lettura.

Difatti apposta è indicato come una "funzione speciale" che effettua una cosa che normalmente dovresti fare con più istruzioni ...
... hanno scelto di usare una cosa che non avrebbe senso, scrivere su PIN e quando la MCU si accorge di questo non-senso, effettua in realtà uan cosa speciale, ovvero il toggle.

Guglielmo

Sì, sto vedendo...

Per la lettura degli ingressi bisogna usare PIN (Port In);

PORT va usato solo per impostare le uscite (quelle dichiarate con pinMode (x, OUTPUT);
e per attivare la resistenza di pull-up sui pin impostati come ingressi (salvo usare pinMode (x, INPUT_PULLUP); ) .
Leggendo PORT si vede solo lo stato dei pin impostati come OUTPUT, non di quelli impostati come INPUT.