Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 16976
Don't know what I do
|
 |
« Reply #15 on: March 09, 2013, 06:12:30 am » |
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).
|
|
|
|
|
Logged
|
|
|
|
|
Roma (RM)
Offline
God Member
Karma: 3
Posts: 634
|
 |
« Reply #16 on: March 09, 2013, 06:45:59 am » |
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.
In quella maniera sovrascrivo tutte le impostazioni precedentemente date agli altri pin.
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 16976
Don't know what I do
|
 |
« Reply #17 on: March 09, 2013, 07:38:50 am » |
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 76
Posts: 7538
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #18 on: March 09, 2013, 07:45:27 am » |
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 //SBI e CBI #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
|
|
|
|
Logged
|
|
|
|
|
Roma (RM)
Offline
God Member
Karma: 3
Posts: 634
|
 |
« Reply #19 on: March 09, 2013, 09:48:35 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 47
|
 |
« Reply #20 on: March 09, 2013, 10:16:10 am » |
Ragazzi mi inserisco anche io nella discussione perché ho un problema con gli input utilizzando "true C". Non so se devo aprire un'altra discussione, nel dubbio posto la domanda... In pratica devo sostituire il classico DigitalRead(pin) con PINx. Il codice di test é questo: int encoder0PinALast=LOW; int countPulses=0; int n=LOW;
void setup() { Serial.begin(115200); pinMode(2,INPUT); pinMode(3,INPUT); digitalWrite(2,HIGH); digitalWrite(3,HIGH); }
void loop() { encoderMotor(); }
void encoderMotor(){ // n = digitalRead(2); n=PIND & _BV(PCINT2);//<== il mio dubbio é qui. n varrá di volta in volta 1 o 0 ??
if ((encoder0PinALast == LOW) && (n == HIGH ) ) { if (PIND & _BV(PCINT19) == LOW) { countPulses++; } else { countPulses--; } } encoder0PinALast = n; }
Il fatto é che l' if non procede nel modo corretto e non ottengo ne l'incremento ne il decremento della variabile. Potreste chiarirmi il concetto su PINx ? Grazie.
|
|
|
|
« Last Edit: March 09, 2013, 10:19:08 am by Augusto Picciani »
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 16976
Don't know what I do
|
 |
« Reply #21 on: March 09, 2013, 10:34:20 am » |
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. Scomponi le operazioni in 2 righe, una per l'attivazione con OR ed una per la disattivazione con AND. Esempio: PORTD |= ((1<<3) | (1<<5)); PORTD &= ~((1<<4) | (1<<2));
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 16976
Don't know what I do
|
 |
« Reply #22 on: March 09, 2013, 10:37:44 am » |
Ragazzi mi inserisco anche io nella discussione perché ho un problema con gli input utilizzando "true C". Non so se devo aprire un'altra discussione, nel dubbio posto la domanda... In pratica devo sostituire il classico DigitalRead(pin) con PINx. Il codice di test é questo: int encoder0PinALast=LOW; int countPulses=0; int n=LOW;
void setup() { Serial.begin(115200); pinMode(2,INPUT); pinMode(3,INPUT); digitalWrite(2,HIGH); digitalWrite(3,HIGH); }
void loop() { encoderMotor(); }
void encoderMotor(){ // n = digitalRead(2); n=PIND & _BV(PCINT2);//<== il mio dubbio é qui. n varrá di volta in volta 1 o 0 ??
if ((encoder0PinALast == LOW) && (n == HIGH ) ) { if (PIND & _BV(PCINT19) == LOW) { countPulses++; } else { countPulses--; } } encoder0PinALast = n; }
Il fatto é che l' if non procede nel modo corretto e non ottengo ne l'incremento ne il decremento della variabile. Potreste chiarirmi il concetto su PINx ? Grazie. PCINTxx indicano gli interrupt di cambio di stato, non i pin. Inoltre il PCINT2 è agganciato al pin PB2, non PD2. Per fare la lettura dello stato del pin 2 fai: if ((PIND & (1<<PB2)) == 1) { ... }
|
|
|
|
|
Logged
|
|
|
|
|
Roma (RM)
Offline
God Member
Karma: 3
Posts: 634
|
 |
« Reply #23 on: March 09, 2013, 10:41:05 am » |
Ok alla fine si è giunti dove dicevo io: 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?
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 16976
Don't know what I do
|
 |
« Reply #24 on: March 09, 2013, 10:44:15 am » |
Ok alla fine si è giunti dove dicevo io: 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?
Se vogliamo essere pignoli.... se in fallo  Perché puoi comporre il byte da passare alla porta PRIMA. Riprendendo il mio esempio precedente, possiamo fare così: byte temp = ((1<<3) | (1<<5)); temp &= ~((1<<4) | (1<<2)); PORTD = temp; Come vedi, con UNA SOLA operazione sulla porta, cambio i bit che mi interessano. 
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 76
Posts: 7538
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #25 on: March 09, 2013, 10:46:30 am » |
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.
Ma perché non leggi le risposte, che oltretutto sono la soluzione al tuo problema ? http://arduino.cc/forum/index.php/topic,152705.msg1149202.html#msg1149202
|
|
|
|
|
Logged
|
|
|
|
|
Genova
Offline
Faraday Member
Karma: 14
Posts: 2522
|
 |
« Reply #26 on: March 09, 2013, 11:07:29 am » |
Scomponi le operazioni in 2 righe, una per l'attivazione con OR ed una per la disattivazione con AND. Esempio: PORTD |= ((1<<3) | (1<<5)); PORTD &= ~((1<<4) | (1<<2)); secondo me non è che non legge, non ha spiegato cosa vuole di preciso spiegando in modo pratico passo-passo cosa vuole fare, è vero che le istruzioni qui sopra funzionano, ma in alcuni contesti è difficile utilizzarli, non posso sostituire lo 0 e 1 a piacimento, sono costretto a spostare a destra e sinistra i byte, eseguire delle negazioni sui bit, OR e AND, ma non vado diretto ai bit che mi servono e devo fare dei salti sul programma per attivare con |= o &= ~ per disattivare. Se non ho capito male, lui vuole ricostruire il byte e rispedirlo al PORTn Con questo metodo lo può fare ma diventa parecchio laborioso.
|
|
|
|
|
Logged
|
Meglio imparare dalle cose inutili piuttosto che non imparare niente. [Arduino Mega R3 + Ethernet shield W5100 + SD card 8Gb FAT32]
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 16976
Don't know what I do
|
 |
« Reply #27 on: March 09, 2013, 11:11:14 am » |
Vabbè, sono esempi. Il codice va scritto in base a quel che deve fare. Vuole leggere da un pin? Ok. Si può fare. Vuole impostare diversi pin di una stessa porta in modo diverso? Ok. Si può fare. Poi sta a lui risolvere i problemi in base alle necessità.
|
|
|
|
|
Logged
|
|
|
|
|
Roma (RM)
Offline
God Member
Karma: 3
Posts: 634
|
 |
« Reply #28 on: March 09, 2013, 11:17:25 am » |
Esatto.
@leo Ma in quel modo sovrascrivo tutto il valore della porta.
@astrobeed Ho letto il post ma sempre due operazioni sono.
Ricapitolo.
C'è un modo per impostare contemporaneamente 2 o 3 bit di una porta (PORTB/C/D) lasciando invariati tutti gli altri nello stato in cui sono. Ciao facendo una cosa del genere.
Stato della porta prima 01010101 vorrei che lo stato della porta sia 01010010 cambiando gli ultimi 3 bit lasciando invariati i primi 5 tutti insieme.
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Online
Brattain Member
Karma: 226
Posts: 16976
Don't know what I do
|
 |
« Reply #29 on: March 09, 2013, 11:19:10 am » |
1) ti leggi la porta e depositi il suo valore in una variabile tampone 2) esegui le modifiche del caso alla variabile tampone 3) riscrivi la variabile tampone sulla porta.
In questo modo cambi lo stato solo dei bit/pin che ti interessa alterare.
|
|
|
|
|
Logged
|
|
|
|
|
|