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 (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"
in cui spiega come velocizzare l'IO delle porte digitali agendo direttamente a basso livello senza passare dai metodi di arduino.
Puoi fare quel che ti pare con le porte del microcontrollore.
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.
Ora vedendo quel metodo noto che spegne, a volte, anche il pwm (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.
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.
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?
erpomata:
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:
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.
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.
Se io sono sicuro di non utilizzare mai la analogWrite me ne posso fregare?
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?
Sì.
0=LOW
1=HIGH
Quindi se riprendiamo la porta dell'esempio precedente, PORTD, e facciamo questa assegnazione:
PORTD = 0b10101010;
Hai impostato le porte collegate ai bit dispari su LOW (1-3-5-7) e quelle collegate ai bit pari su HIGH (0-2-4-6).
erpomata:
Si ma se io volessi impostare, ad esempio i bit 0 e 1 rispettivamente a HIGH ed a LOW ma preservando gli altri bit della porta non lo posso fare.
Per settare i singoli bit di un port, o un registro, puoi usare le macro SBI(reg,bit) e CBI(reg,bit), usano le omonime istruzioni assembly e richiedo solo due cicli macchina per l'esecuzione.
SBI = Set Bit in I/O Register
CBI = Clear Bit in I/O Register
Certo che l'ho letto ma se per settare a HIGH devo usare una OR e per metterla a LOW devo usare una AND come faccio a combinare la cosa su pin diversi, mantenendo lo stato degli altri pin della porta e facendo l'operazione contemporaneamente su tutta la porta.
Non mi pare di vedere ciò che mi serve in quel post.