Go Down

Topic: Velocizzare l'IO delle porte digitali (Read 22143 times) previous topic - next topic

erpomata

Mar 07, 2013, 05:58 am Last Edit: Mar 07, 2013, 06:03 am by erpomata Reason: 1
Stavo leggendo questo interessante articolo:

http://www.skpang.co.uk/blog/archives/323

in cui spiega come velocizzare l'IO delle porte digitali agendo direttamente a basso livello senza passare dai metodi di arduino.

In quell'articolo viene riportata anche la funzione digitalwrite per far vedere quante cose fa prima di impostare il pin.

Ora vedendo quel metodo noto che spegne, a volte, anche il pwm
Code: [Select]
(if (timer != NOT_ON_TIMER) turnOffPWM(timer);)

Se io volessi lavorare con le porte a basso livello dovrei spegnerlo io il pwm a mano? Magari nel setup?
Ho provato a chiamare la turnOffPWM ma dice "Blink:16: error: 'turnOffPWM' was not declared in this scope"

Sbaglio qualcosa?

Grazie

leo72


Stavo leggendo questo interessante articolo:

http://www.skpang.co.uk/blog/archives/323

in cui spiega come velocizzare l'IO delle porte digitali agendo direttamente a basso livello senza passare dai metodi di arduino.

http://www.arduino.cc/en/Reference/PortManipulation
Puoi fare quel che ti pare con le porte del microcontrollore.

Quote

In quell'articolo viene riportata anche la funzione digitalwrite per far vedere quante cose fa prima di impostare il pin.

Il problema della manipolazione diretta delle porte è proprio questo, ossia capire/sapere cosa fa il core di Arduino. Il core di Arduino è molto complesso e dietro la semplificazione che offre all'utente c'è tutta una struttura di funzioni nascoste all'utente che permettono di utilizzare l'HW con semplici comandi.

Quote

Ora vedendo quel metodo noto che spegne, a volte, anche il pwm
Code: [Select]
(if (timer != NOT_ON_TIMER) turnOffPWM(timer);)

Lo fa per evitare di trovarti un segnale PWM attivato da un analogWrite sullo stesso pin che poi vuoi usare come semplice uscita digitale.

Quote

Se io volessi lavorare con le porte a basso livello dovrei spegnerlo io il pwm a mano? Magari nel setup?
Ho provato a chiamare la turnOffPWM ma dice "Blink:16: error: 'turnOffPWM' was not declared in this scope"

Sbaglio qualcosa?

Grazie

Sì, a chiamare quella funzione dallo sketch, che è visibile solo all'interno del file wiring_digital.c
Potresti provare a prenderla e ricopiarla, magari togliendo i controlli che non riguardano l'Atmega328 (che ha solo 3 timer, mentre quella funzione ne controlla di più, tutti quelli disponibili anche sulla Mega, per esempio), direttamente nel tuo sketch.

erpomata

Ho provato a copiare il codice ma dovrei importare mezza libreria di arduino.

Un'ultima domanda, disabilitare o meno pwm è dato solo dal fatto che se voglio ragionare a I/O digitali invece che analogici, cioè mi protegge.
Se io sono sicuro di non utilizzare mai la analogWrite me ne posso fregare?

astrobeed


Se io sono sicuro di non utilizzare mai la analogWrite me ne posso fregare?


Se non hai precedentemente utilizzato AnalogWrite su un pin, in realtà vale per una coppia, non devi disabilitare il PWM per utilizzare il pin in modo digitale, in caso contrario devi prima disabilitarlo.
C'è la proposta per una nuova funzione denominata noAnalogWrite() per disattivare il PWM, però non è ancora stata implementata, puoi comunque farlo da sketch con questa sequenza di istruzioni:

Code: [Select]

analogWrite(9, 128);
delay(1);
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);


Trovi i riferimenti qui
Scientia potentia est

leo72


Ho provato a copiare il codice ma dovrei importare mezza libreria di arduino.

Un'ultima domanda, disabilitare o meno pwm è dato solo dal fatto che se voglio ragionare a I/O digitali invece che analogici, cioè mi protegge.

Giusto per precisione, un'uscita PWM non è un'uscita analogica.
Comunque il concetto è che siccome il core di Arduino non sa se hai attivato un segnale PWM su un pin (non tiene traccia della cosa), e non fa neanche un controllo sui registri per motivi di snellezza del codice, semplifica la cosa e disattiva il PWM sui pin con tale capacità a prescindere.

Quote

Se io sono sicuro di non utilizzare mai la analogWrite me ne posso fregare?

Sì  ;)

PaoloP


erpomata

Grazie a tutti.
Superlativi come al solito

Janos


...
http://www.arduino.cc/en/Reference/PortManipulation
Puoi fare quel che ti pare con le porte del microcontrollore.
...


Li è scritto dettagliatamente come funzionano le porte del micro. Se vuoi avere un'infarinatura generale puoi leggere questo mio vecchio post:

http://arduino.cc/forum/index.php/topic,72628.msg545828.html#msg545828

erpomata

Grazie tante.
Ottima spiegazione ma anche il link che ho trovato io è molto chiaro.

erpomata

Scusate, riprendo l'argomento per chiedere se è possibile, ed eventualmente come faccio, ad impostare 2 o 3 pin contemporaneamente.

Queste guide parlano sempre di un pin alla volta.

PaoloP

Guarda questa discussione --> http://arduino.cc/forum/index.php?topic=124080.0

Comunque settando la porta puoi settare più pin contemporaneamente.
Quote
PORTD |= B10101000; // sets digital pins 7,5,3 HIGH

erpomata

Si quel metodo mi è chiaro.
Non sono stato chiaro io.
Intendevo con la notazione tipo:

Code: [Select]
PORTD |= 1<<2; // Set bit 2 high

PaoloP


Si quel metodo mi è chiaro.
Non sono stato chiaro io.
Intendevo con la notazione tipo:

Code: [Select]
PORTD |= 1<<2; // Set bit 2 high


--> http://arduino.cc/forum/index.php/topic,124080.msg933207.html#msg933207
Quote
Code: [Select]
PORTD |= ((1<<3) | (1<<5));

erpomata

Caspita che hai l'indirce del forum in testa?

Grazie per la dritta.

erpomata

Comunque, mi pare di aver capito che è impossibile settare per una stessa porta un pin HIGH e l'altro LOW.
Devono essere 2 operazioni differenti.

Sbaglio?

Go Up