Delucidazioni sull'esempio Switch(C18 Step by Step) e sui pulsanti in generale

  • patana93
  • Autore della discussione
  • Giovane Utente
  • Giovane Utente
Di più
11 Anni 6 Mesi fa - 11 Anni 6 Mesi fa #1 da patana93
Salve a tutti! Inizio con lo scusarmi per queste mie domande molto banali ma purtroppo non riesco a venire a capo di un problema da diversi giorni e purtroppo sul forum non ho trovato nulla che possa aiutarmi.

Andando subito al dunque, sto studiando dalla guida C18 Step by Step e sono arrivato all'esempio sullo switch ma non riesco bene a capire quale sia lo scopo del programma e come si gestiscono i pulsanti, ossia quando si parla di #define BT1 xxxxxxxx cosa sto settando? Oppure la variabile button non riesco a capire a cosa si riferisca di preciso. E neanche la parte button = button & 0xF0. Insomma un po' tutto xD

Per farmi comprendere meglio, sono riuscito a capire che i 4 bit meno significativi di ogni pulsante vanno settati a 0 perchè sono quelli più significativi a decretare se il pulsante è premuto o meno(ma non ho capito bene come si identificano i 4 pulsanti) e sperimentando ho capito che se setto il default come 0x0F ho tutti i pulsanti spenti invece che accesi.

Infine posto il codice della guida:
Code:
#include <p18f4550.h> #include <portb.h> #pragma config FOSC = HS #pragma config WDT = OFF #pragma config LVP = OFF #pragma config PBADEN = OFF //FOSC = HS Impostato per lavorare ad alta frequenza //WDT = OFF Disabilito il watchdog timer //LVP = OFF Disabilito programmazione LVP //PBADEN = OFF Disabilito gli ingressi analogici #define BT1 0b11100000 #define BT2 0b11010000 #define BT3 0b10110000 #define BT4 0b01110000 void main (void){ // Variabile per la lettura pulsanti unsigned char button; // Imposto PORTA tutti ingressi LATA = 0x00; TRISA = 0xFF; // Imposto PORTB tutti ingressi LATB = 0x00; TRISB = 0xFF; // Imposto PORTC tutti ingressi LATC = 0x00; TRISC = 0xFF; // Imposto PORTD tutte uscite LATD = 0x00; TRISD = 0x00; // Imposto PORTE tutti ingressi LATE = 0x00; TRISE = 0xFF; // Abilita i resistori di pull-up sulla PORTB EnablePullups(); // Ciclo infinito while(1){ button = PORTB; button = button & 0xF0; // Controllo del tasto premuto switch(button) { case BT1: LATD = 0xF0; break; case BT2: LATD = 0x02; break; case BT3: LATD = 0x04; break; case BT4: LATD = 0x08; break; default: LATD = 0x0F; } } }

Grazie! :)
Ultima Modifica 11 Anni 6 Mesi fa da Mauro Laurenti.

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • StefA
  • Moderatore
  • Moderatore
Di più
11 Anni 6 Mesi fa #2 da StefA

quando si parla di #define BT1 xxxxxxxx cosa sto settando?

La direttiva define in questo caso è usta per chiamare con un altro nome un qualcosa di più scomodo da scrivere. Se scrivi #define BT1 0b11100000 stai dicendo al compilatore, quando trovi scritto BT1 leggilo come 0b11100000.


Oppure la variabile button non riesco a capire a cosa si riferisca di preciso

In quella variabile, viene salvato lo stato della porta b con l'istruzione button = PORTB; siccome sulla porta b ci sono collegati i 4 pulsanti, quella variabile identifica lo stato della porta e di conseguenza dei pulsanti.


E neanche la parte button = button & 0xF0

0xF0 è un valore esadecimale, se lo vedi in binario sarebbe 0b11110000.
Quella istruzione fa l'AND logico tra il valore button (lo stato delle porte e quindi dei pulsanti) e il valore 11110000.
In questo modo i primi 4 bit vengono messi a zero e gli altri 4 sono uguali a quelli della variabile button.
Questo ha senso perché i 4 pulsanti della freedom sono collegati ognuno ad un pin della porta b, in particolare su RB4, RB5, RB6, RB7, quindi non usando i pin RB0, RB1, RB2, RB3 si mettono a zero.


Per farmi comprendere meglio, sono riuscito a capire che i 4 bit meno significativi di ogni pulsante vanno settati a 0 perchè sono quelli più significativi a decretare se il pulsante è premuto o meno(ma non ho capito bene come si identificano i 4 pulsanti) e sperimentando ho capito che se setto il default come 0x0F ho tutti i pulsanti spenti invece che accesi.

Aspetta, stai facendo un po' di confusione, ogni pulsante non ha 8 bit, ogni pulsante corrisponde ad un solo pin del pic e quindi ad un solo bit della porta a cui è collegato (in questo caso porta b).
I pulsanti della freedom II sono collegati con il pull-up e quindi senza premere niente si trovano a 1.
Quindi facendo button = PORTB; ho che la variabile vale (in binario) 0b11111111.
Facendo l'AND logico metto a zero i primi 4 bit che non mi interessano, quindi facendo button = button & 0xF0; ottengo che button vale 0b11110000.
In questo caso non ho pulsanti premuti, infatti questo valore non corrisponde a nessun pulsante BT1, BT2, BT3, BT4 e non si accende niente.

Vediamo ad esempio il caso in cui è premuto BT2, questo pulsante è collegato al pin RB5 e quando è premuto il valore del pin va a zero, per cui con l'istruzione button = PORTB; avrò per la variabile button il valore 0b11011111,
poi facendo button = button & 0xF0; otterro 0b11010000 e questo è proprio il valore che identifica BT2.
Nello switch sono nel caso BT2 e di conseguenza accendo i led sulla porta d eseguendo l'istruzione LATD = 0x02;

Ste

..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • patana93
  • Autore della discussione
  • Giovane Utente
  • Giovane Utente
Di più
11 Anni 6 Mesi fa #3 da patana93
Grazie mille sei stato gentilissimo!
Ora ho capito tutto quello che riguarda i pulsanti! ^^
Ultima curiosità, se io premo un pulsante allora, non si dovrebbe accendere un led dal 5 all'8(in base a quale pulsante premo)e spegnere i primi 4?
Perchè tutto è nato proprio dal fatto che premo i pulsanti ma sulla Freedom II rimangono sempre i primi 4 accesi(quando dico i primi quattro intendo, partendo da destra).
Grazie ancora :)

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • StefA
  • Moderatore
  • Moderatore
Di più
11 Anni 6 Mesi fa #4 da StefA

se io premo un pulsante allora, non si dovrebbe accendere un led dal 5 all'8(in base a quale pulsante premo)e spegnere i primi 4?
Perchè tutto è nato proprio dal fatto che premo i pulsanti ma sulla Freedom II rimangono sempre i primi 4 accesi(quando dico i primi quattro intendo, partendo da destra).

Non proprio.
I led sono collegati alla porta d, led0- RD0, led1-RD1...led7-RD7, quindi quando scrivi un valore sulla porta, si accendono i led corrisponenti.

Esempio: scrivi LATD = 0x34; quello è un valore in esadecimale, in decimale corrisponde a 52 e in binario sarebbe 0b00110100, quindi hai quel valore della porta d che corrisponde allo stato dei suoi 8 pin e siccome ci sono collegati dei led e la porta è settata come uscita avrai accesi i led led2,led4, led5.

Nel tuo programma il primo case è scritto male, non deve essere
Code:
case BT1: LATD = 0xF0; break;

ma
Code:
case BT1: LATD = 0x01; break;

al di là di questo l'esempio fa accendere a seconda del pulsante premuto, uno per volta, i led 0,1,2,3 (tutti gli altri sono spenti) e se non si preme niente sono accesi contemporaneamente i led 0,1,2,3.
Infatti se vedi lo switch case trovi i 4 casi dei pulsanti..ad esempio il quarto..
Code:
case BT4: LATD = 0x08; break;
0x08 è sempre esadecimale e in binario sarebbe 0b00001000, quindi si accende solo il led3.

se non è premuto nessun pulsante viene eseguita l'istruzione..
Code:
default: LATD = 0x0F;
sempre convertendo sarebbe 0b00001111, quindi i led da 0 a 3 (i primi 4) accesi

Se il comportamento è quello che dici il programma non ti funziona, gli esempi del libro si possono scaricare dal sito, prova quello che funziona sicuramente (l'ho anche riprovato adesso)

Ste

..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]

Si prega Accesso o Crea un account a partecipare alla conversazione.

  • patana93
  • Autore della discussione
  • Giovane Utente
  • Giovane Utente
Di più
11 Anni 6 Mesi fa #5 da patana93
Purtroppo ho usato anche il codice, scaricato da questo sito, ma la mia situazione rimane sempre la stessa. Ho i primi 4 led accesi, poi premo un qualsiasi pulsante, ma la situazione non cambia. Se vuoi posso postare un video. Spero non sia un problema della Freedom :( . Ti ringrazio ancora per l'aiuto.

Si prega Accesso o Crea un account a partecipare alla conversazione.

Moderatori: Mauro LaurentiStefA

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Forum - Ultimi messaggi