- Messaggi: 198
- Ringraziamenti ricevuti 26
switch case e pulsanti
- Cosimix
-
- Elit Utente
-
Less
Di più
6 Anni 8 Mesi fa - 6 Anni 8 Mesi fa #6
da Cosimix
Risposta da Cosimix al topic switch case e pulsanti
Salve!
Non c'è niente di banale, tranquillo
. E' più banale non porre/porsi domande.
Capire il funzionamento di un programma direttamente dalle righe di codice, non è semplicissimo. Non è semplice neanche concepire un programma scrivendo direttamente le istruzioni.
Per aiutarti, scrivi su un pezzo di carta il flow chart di quello che intendi realizzare, ossia una descrizione, attraverso un diagramma, di quello che il tuo programma deve fare. Successivamente devi tradurre il tuo flow chart in righe di codice.
Quello che ho scritto è inizialmente poco comprensibile anche perché nascono ambiguità a causa delle negazioni logiche, dovute al collegamento del pulsante all'alimentazione (mediante resistore di pull-up) a riposo.
Questo è un esempio di flow chart relativo alla pressione del pulsante:
Innanzitutto parti da una condizione iniziale in cui riconosci due diversi momenti di funzionamento del pulsante, perché si tratta appunto di un pulsante e non di un interruttore. Queste due condizioni le ho "tradotte" in codice servendomi di due variabili (stato_precedente e stato_attuale), inizializzandole a zero. Questa condizione iniziale la stabilisci una sola volta (non è rappresentata nel flow chart). Ormai è chiaro che il riconoscimento di questi due stati (e quindi due variabili) è indispensabile perché la pressione del pulsante non è istantanea, ma ha una certa durata. Durante questo tempo in cui il pulsante è chiuso (quello che io ho chiamato stato attuale) non ci deve essere nessun incremento della variabile i.
Una volta acquisito lo stato del pulsante, entra in gioco l'istruzione condizionale if, che traduce quello che trovi scritto nel rombo del diagramma. L'incremento della variabile i lo avrai solo nel momento in cui il pulsante sarà chiuso quando invece prima non lo era. E' una doppia condizione che deve essere verificata (nel codice ti servi dell'operatore &&).
Poi aggiorni lo stato precedente (subito dopo l'incremento della variabile i) perché quando ti porrai nuovamente la domanda devi avere memoria dello stato del pulsante nell'istante immediatamente precedente. Se in precedenza era chiuso, allora non ci sarà nessun incremento della variabile.
L'aggiornamento dello stato precedente ci sarà in tutti e due i casi, perché nel momento in cui arrivi all'if, devi sapere lo stato che il pulsante aveva una frazione di secondo immediatamente prima.
Per quanto riguarda le negazioni logiche attraverso l'operatore "!", tutto dipende dal collegamento fisico dell'ingresso con il pulsante. Se a riposo il pulsante fosse collegato a massa, non utilizzerei la negazione e il codice sarebbe forse più comprensibile. Avrei scritto ad esempio:
Ancora una piccola precisazione sull'istruzione condizionale, relativamente al codice da te in uso. Così come la leggi, stai dicendo:
"SE il pulsante è chiuso E precedentemente era aperto, allora...".
La verifica che fai scrivendo "== 0", è relativa solo alla variabile stato_precedente, non anche a !stato_attuale. Entrambe (&&) devono essere vere (cioè deve essere !stato_attuale diverso da zero E stato_precedente uguale a zero) affinché venga eseguito l'incremento della variabile i.
Saluti,
Cosimo
Non c'è niente di banale, tranquillo

Capire il funzionamento di un programma direttamente dalle righe di codice, non è semplicissimo. Non è semplice neanche concepire un programma scrivendo direttamente le istruzioni.
Per aiutarti, scrivi su un pezzo di carta il flow chart di quello che intendi realizzare, ossia una descrizione, attraverso un diagramma, di quello che il tuo programma deve fare. Successivamente devi tradurre il tuo flow chart in righe di codice.
Quello che ho scritto è inizialmente poco comprensibile anche perché nascono ambiguità a causa delle negazioni logiche, dovute al collegamento del pulsante all'alimentazione (mediante resistore di pull-up) a riposo.
Questo è un esempio di flow chart relativo alla pressione del pulsante:
Innanzitutto parti da una condizione iniziale in cui riconosci due diversi momenti di funzionamento del pulsante, perché si tratta appunto di un pulsante e non di un interruttore. Queste due condizioni le ho "tradotte" in codice servendomi di due variabili (stato_precedente e stato_attuale), inizializzandole a zero. Questa condizione iniziale la stabilisci una sola volta (non è rappresentata nel flow chart). Ormai è chiaro che il riconoscimento di questi due stati (e quindi due variabili) è indispensabile perché la pressione del pulsante non è istantanea, ma ha una certa durata. Durante questo tempo in cui il pulsante è chiuso (quello che io ho chiamato stato attuale) non ci deve essere nessun incremento della variabile i.
Una volta acquisito lo stato del pulsante, entra in gioco l'istruzione condizionale if, che traduce quello che trovi scritto nel rombo del diagramma. L'incremento della variabile i lo avrai solo nel momento in cui il pulsante sarà chiuso quando invece prima non lo era. E' una doppia condizione che deve essere verificata (nel codice ti servi dell'operatore &&).
Poi aggiorni lo stato precedente (subito dopo l'incremento della variabile i) perché quando ti porrai nuovamente la domanda devi avere memoria dello stato del pulsante nell'istante immediatamente precedente. Se in precedenza era chiuso, allora non ci sarà nessun incremento della variabile.
L'aggiornamento dello stato precedente ci sarà in tutti e due i casi, perché nel momento in cui arrivi all'if, devi sapere lo stato che il pulsante aveva una frazione di secondo immediatamente prima.
Per quanto riguarda le negazioni logiche attraverso l'operatore "!", tutto dipende dal collegamento fisico dell'ingresso con il pulsante. Se a riposo il pulsante fosse collegato a massa, non utilizzerei la negazione e il codice sarebbe forse più comprensibile. Avrei scritto ad esempio:
Code:
if(stato_attuale && stato_precedente == 0)
...
...
...
stato_precedente = stato_attuale; // Aggiorno lo stato del pulsante
Ancora una piccola precisazione sull'istruzione condizionale, relativamente al codice da te in uso. Così come la leggi, stai dicendo:
"SE il pulsante è chiuso E precedentemente era aperto, allora...".
La verifica che fai scrivendo "== 0", è relativa solo alla variabile stato_precedente, non anche a !stato_attuale. Entrambe (&&) devono essere vere (cioè deve essere !stato_attuale diverso da zero E stato_precedente uguale a zero) affinché venga eseguito l'incremento della variabile i.
Saluti,
Cosimo
Ultima Modifica 6 Anni 8 Mesi fa da Cosimix.
Si prega Accesso o Crea un account a partecipare alla conversazione.
- simoblack
- Autore della discussione
- Nuovo Utente
-
Less
Di più
- Messaggi: 14
- Ringraziamenti ricevuti 0
6 Anni 8 Mesi fa #7
da simoblack
Risposta da simoblack al topic switch case e pulsanti
Grazie Cosimix, hai ampiamente risposto alle mie domende. Avevo interpretato correttamente il tuo codice e la tua spiegazione mi ha totalmente soddisfatto. Posso dire di essere arrivato a questo punto con la consapevolezza di aver compreso ciò che sto facendo. Ora vorrei congelare un attimo l'argomento in oggetto per poi ritornarci a breve... Sto iniziando a "giocare" con gli Array, vediamo se riesco ad inserirmi in un quadro più grande e soprattutto vediamo se ci arrivo con le mie forze. :lol:
Si prega Accesso o Crea un account a partecipare alla conversazione.
- simoblack
- Autore della discussione
- Nuovo Utente
-
Less
Di più
- Messaggi: 14
- Ringraziamenti ricevuti 0
6 Anni 8 Mesi fa - 6 Anni 8 Mesi fa #8
da simoblack
Risposta da simoblack al topic switch case e pulsanti
Allora come promesso sono ritornato su questo argomento, inserisco di seguito il codice realizzato così da mettermi in discussione. Ho sviluppato il codice fin qui studiato ed ho realizzato un semplice counter a quattro cifre su display a sette segmenti in multiplexing che incrementa di una unità ad ogni pressione del pulsante UP e decrementa alla pressione del pulsante down. Il tutto funziona correttamente e mi farà da base per il classico orologio così da prendere confidenza con gli interrupt ed i Timer degli MSP430. Avvierò probabilmente un nuovo post nella sezione adeguata.
Vi ringrazio ancora per il grande aiuto dato :lol:
Code:
#include <msp430.h>
#define butt_up P1IN & BIT6
#define butt_down P1IN & BIT5
#define ZERO P2OUT = 0b11000000
#define UNO P2OUT = 0b11111001
#define DUE P2OUT = 0b10100100
#define TRE P2OUT = 0b10110000
#define QUATTRO P2OUT = 0b10011001
#define CINQUE P2OUT = 0b10010010
#define SEI P2OUT = 0b10000010
#define SETTE P2OUT = 0b11111000
#define OTTO P2OUT = 0b10000000
#define NOVE P2OUT = 0b10010000
#define UNT P3OUT = 0b1000
#define DEC P3OUT = 0b0100
#define CEN P3OUT = 0b0010
#define MIG P3OUT = 0b0001
void main(void) {
WDTCTL = WDTPW | WDTHOLD; // Disabilito il chiwawa
P2DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7; // Imposto le uscite P.2
P3DIR |= BIT0 + BIT1 + BIT2 + BIT3; // Imposto le uscite P.3
int i = 0; // Questa variabile conta il numero di pressioni del pulsante e incrementa le unità
int x = 0; // Questa variabile incrementa le decine
int y = 0; // Questa variabile incrementa le centinaia
int a = 0; // Questa variabile incrementa le migliaia
unsigned char up_attuale = 0; // E' lo stato (pressione) attuale del pulsante up (incremento)
unsigned char up_precedente = 0; // E' lo stato (pressione) precedente del pulsante up (incremento)
unsigned char down_attuale = 0; // E' lo stato (pressione) attuale del pulsante down (decremento)
unsigned char down_precedente = 0; //E' lo stato (pressione) precedente del pulsante down (decremento)
char Array_unt [] = {ZERO, UNO, DUE, TRE, QUATTRO, CINQUE, SEI, SETTE, OTTO, NOVE}; // Array unità
char Array_dec [] = {ZERO, UNO, DUE, TRE, QUATTRO, CINQUE, SEI, SETTE, OTTO, NOVE}; // Array decine
char Array_cen [] = {ZERO, UNO, DUE, TRE, QUATTRO, CINQUE, SEI, SETTE, OTTO, NOVE}; // Array centinaia
char Array_mig [] = {ZERO, UNO, DUE, TRE, QUATTRO, CINQUE, SEI, SETTE, OTTO, NOVE}; // Array migliaia
int delay = 0; // Variabile da utilizzare per il ritardo
int z = 0; // Variabile per il multiplexing
while(1)
{
//ritardo per visualizzare correttamente il multiplexer
for (delay = 0; delay < 600; delay++);{
z = z + 1; // incremento z ad ogni ciclo
if (z == 4) // riporto z a 0
z = 0;
switch (z) // switch case per gestione multiplexing
{
case 0:
P3OUT = UNT;
P2OUT = Array_unt [i];
break;
case 1:
P3OUT = DEC;
P2OUT = Array_dec [x];
break;
case 2:
P3OUT = CEN;
P2OUT = Array_cen [y];
break;
case 3:
P3OUT = MIG;
P2OUT = Array_mig [a];
break;
}
}
up_attuale = butt_up; // Memorizzo lo stato attuale del pulsante up
down_attuale = butt_down; // Memorizzo lo stato attuale del pulsante down
// se l'espressione è vera incrementa i
if(!up_attuale && up_precedente == 0)
{
i = i + 1;
}
// se l'espressione è vera decrementa i
if(!down_attuale && down_precedente == 0)
{
i = i - 1;
}
if (i==10) // al seperamento di nove Riporta le unità a zero e incrementa le decine
{
x = x + 1;
i = 0;
}
if (x==10) // al seperamento di nove Riporta le decine a zero e incrementa le centinaia
{
y = y + 1;
x = 0;
}
if (y==10) // al seperamento di nove Riporta le centinaia a zero e incrementa le migliaia
{
a = a + 1;
y = 0;
}
if (a==10) // a 9999 riporta a 0
a = 0;
if (i < 0) // funzione di decremento, quando i è inferiore a 0 riporto le unità a 9 e decremento le decine
{
x = x-1;
i = 9;
}
if (x < 0) // funzione di decremento, quando x è inferiore a 0 riporto le decine a 9 e decremento le centinaia
{
y = y - 1;
x = 9;
}
if (y < 0) // funzione di decremento, quando y è inferiore a 0 riporto le centinaia a 9 e decremento le migliaia
{
a = a - 1;
y = 9;
}
if (a + y + x + i == 0) // controlli di decremento
i = 0;
if (a + y + x == 0)
x = 0;
if (a + y == 0)
y = 0;
up_precedente = !up_attuale; // Aggiorno lo stato del pulsante up
down_precedente = !down_attuale; // Aggiorno lo stato del pulsante down
}
}
Ultima Modifica 6 Anni 8 Mesi fa da simoblack.
Si prega Accesso o Crea un account a partecipare alla conversazione.
- Cosimix
-
- Elit Utente
-
Less
Di più
- Messaggi: 198
- Ringraziamenti ricevuti 26
6 Anni 8 Mesi fa #9
da Cosimix
Risposta da Cosimix al topic switch case e pulsanti
Perfetto! 
Il lavoro procede bene!
Quando possibile, dichiara le variabili come "unsigned char", in modo da utilizzare meno memoria.
Tienici aggiornati sugli sviluppi.
Saluti,
Cosimo

Il lavoro procede bene!
Quando possibile, dichiara le variabili come "unsigned char", in modo da utilizzare meno memoria.
Tienici aggiornati sugli sviluppi.
Saluti,
Cosimo
Si prega Accesso o Crea un account a partecipare alla conversazione.
Moderatori: Mauro Laurenti, StefA
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.
Forum - Ultimi messaggi
-
- Freedom III e compilazioni fallite
- da Black
-
- MODULO GSM SIM900A
- da FABRIZIO
-
- LTerminal - nuove funzioni
- da Mauro Laurenti
-
- Aggiornamento sito completato
- da Mauro Laurenti
-
- registro a scorrimento PIPO in cascata
- da Mauro Laurenti