PDA

View Full Version : [C] state machine e variabili globali


Unrealizer
19-09-2010, 14:58
salve a tutti!

intanto, per cominciare una domanda stupida: per fare in modo che una variabile possa essere utilizzata da altre funzioni, devo semplicemente dichiararla all'esterno del main, no? e per fare in modo che ci possano accedere funzioni contenute in altri file devo solo aggiungere la keyword extern o devo fare altro?

sto lavorando ad un progetto su pic per una specie di timer, che però deve utilizzare un display lcd 16x2 per visualizzare un menu.

per creare questo menu sto utilizzando 2 state machine: una per decidere se visualizzare il menu, o eseguire le sue "funzioni" e un'altra per gestire le pagine di menu.

non ho ancora scritto il codice, sono idee che mi frullano per la mente ancora :D

ho intenzione di mettere la prima state machine nel main, e in una funzione apposita la state machine del menu, il tutto basandolo su cicli switch case...

suggerimenti? è la prima volta che utilizzo una state machine :D

la domanda sulle variabili globali era per permettere al menu di passare al ciclo timer le impostazioni xD

PS: piccola premessa, essendo il pic un microcontrollore, ho a disposizione una quantità limitata (ma comunque sufficiente) di ram, 368 byte, ma soprattutto si tratta di un processore a 8 bit, per questo motivo il menu sarà limitato a 255 pagine per evitare di appesantire troppo la state machine :D ma tanto abbonderanno di sicuro, ma resta il problema che devo limitare l'uso dei tipi da int a salire il più possibile, e limitarmi agli unsigned char ovunque possa :sofico:

jedineon
24-02-2011, 17:54
Ciao, spero di non essere arrivato tardi...
anche io sto lavorando ad un progetto simile, devo creare un menù per un lcd 40x2 interfacciato ad un PIC.

per prima cosa: che compilatore usi? io il CCS C, però sto pensando di passare al C18

per rispondere alla tua prima domanda, per fare vedere la variabile da una funzione, ovunque essa si trovi, dichiarala all'esterno del main, subito dopo i settaggi dei fuse e dell'oscillatore.

Il sistema per gestire i menù che ho pensato io è questo:

due variabili (menu_counter e selected_counter) contengono la pagina di menù attiva e il valore della variabile che essa cambia.
Nella routine di input vado ad assegnare (tramite un puntatore ad un array che contiene gli indirizzi delle variabili) alle variabili da modificare il relativo valore del selected_counter; un altro array contiene i valori minimi e massimi accettabili per quella variabile.
Chiaramente con questo sistema l'indice dell'array è proprio il menu_counter, per cui mi basta gestire tramite input l'aumento e diminuzione di queste sole due variabili per modificarne molte altre.

Ora sto cercando di creare un menù modulare, in cui vengono create nuove pagine a seconda dei dati salvati su eeprom...

fammi sapere se questi suggerimenti ti sono di aiuto e se tu ne hai per me...
ciao!

Unrealizer
24-02-2011, 19:49
in effetti il thread è vecchio, ma quel progetto è per ora "in pausa" :D

io utilizzo 2 variabili, una contenente lo stato del sistema, un'altra contenente lo stato del menu. Ci sono anche due array, in memoria programma, uno contenente tutte le stringhe di menu, un'altro contenente tutti i "salti" (è un array bidimensionale, di una dimensione per 3, come 3 sono i pulsanti di scelta - avanti, indietro, OK). Nel caso il "salto" sia 0x00, viene interrogato un altro array contenente lo stato di impostare come stato sistema.

Come compilatore usavo l'hitech, ma da poco sono passato al C18

jedineon
25-02-2011, 08:42
ok, ora ho implementato anche io un array che contiene le stringhe del menù, effettivamente è molto più comodo tenere da una parte tutti i dati relativi al menù; ad inizio programma dichiaro:

array stringhe;
array valore max;
array valore min;
array indirizzo variabili;

dopodichè cambiando l'indice dell'array ottengo la pagina di menù relativa.

hai idea di come potrei mettere il tutto in una struttura? non ne sono per nulla pratico... :D

Unrealizer
25-02-2011, 11:13
mai usato strutture :D incredibile ma vero :D cmq adesso il menu è fermo, devo riuscire a far funzionare bene gli RTC (è incredibile che il più fornito negozio di elettronica di Palermo NON abbia quarzi da 32.768 kHz!), per ora un DS1307, più avanti un DS3232, e la comunicazione seriale col pc, tramite un client apposito in c# (per ora tramite la uart, successivamente con l'usb in emulazione seriale e poi forse tramite l'usb nativo :D)

!fazz
25-02-2011, 18:55
per le strutture è facile basta mettere la dichiarazione di tutte le variabili che ti interessano all'interno della definizione struttura

es


typedef struct
{
MyInt16T tm_sec;
MyInt16T tm_min;
MyInt16T tm_hour;
MyInt16T tm_mday;
MyInt16T tm_mon;
MyInt16T tm_year;
MyInt16T tm_wday;
MyInt16T tm_yday;
MyInt16T tm_isdst;
} MyTmT;




per usarle poi basta dichiarare una variabile del tipo della struttura e accedere ai campi con il punto

MyTmT miaStruttura;
miaStruttura.tm_sec=1;


se si usano i puntatori viene comodo sostiturie *struttura.campo con l'equivalente struttura->campo


per il resto niente da dire a parte che se usate variabili globali in un diverso file rispetto a dove le avete dichiarate dovete dichiarale anche in questo file con il modificatore extern davanti

Unrealizer
25-02-2011, 19:49
per le strutture è facile basta mettere la dichiarazione di tutte le variabili che ti interessano all'interno della definizione struttura

es


typedef struct
{
MyInt16T tm_sec;
MyInt16T tm_min;
MyInt16T tm_hour;
MyInt16T tm_mday;
MyInt16T tm_mon;
MyInt16T tm_year;
MyInt16T tm_wday;
MyInt16T tm_yday;
MyInt16T tm_isdst;
} MyTmT;




per usarle poi basta dichiarare una variabile del tipo della struttura e accedere ai campi con il punto

MyTmT miaStruttura;
miaStruttura.tm_sec=1;


se si usano i puntatori viene comodo sostiturie *struttura.campo con l'equivalente struttura->campo


per il resto niente da dire a parte che se usate variabili globali in un diverso file rispetto a dove le avete dichiarate dovete dichiarale anche in questo file con il modificatore extern davanti

grazie del chiarimento :D potrebbero essere utili per le flag dato che con pochi byte di ram è uno spreco usarne uno intero per ogni flag, dovrebbe bastare dichiarare una struttura con campi bit...

Il mio problema ora è con la seriale: tramite l'UART Tool del pickit2 funziona la trasmissione al pc, ma non dal pc al pic, mentre tramite il MAX232 e un convertitore RS232-USB basato sul PL-2303 non vedo assolutamente niente

!fazz
25-02-2011, 20:39
grazie del chiarimento :D potrebbero essere utili per le flag dato che con pochi byte di ram è uno spreco usarne uno intero per ogni flag, dovrebbe bastare dichiarare una struttura con campi bit...

Il mio problema ora è con la seriale: tramite l'UART Tool del pickit2 funziona la trasmissione al pc, ma non dal pc al pic, mentre tramite il MAX232 e un convertitore RS232-USB basato sul PL-2303 non vedo assolutamente niente

per i flag usa un intero e lavoraci sopra bit a bit

jedineon
12-03-2011, 10:16
Grande cosa le strutture, ho ridotto di tantissimo il codice del mio programma incapsulando variabili omologhe nella stessa struttura.

Il prossimo passo è creare un menù ad albero asimmetrico!
Mi spiego meglio:
voglio creare un menù con profondità variabile, ovvero dove si può scendere e salire di livello per arrivare a tutte le opzioni;
il problema di un menù del genere è ottimizzare sia la memoria programma in cui scriverlo sia la ram da tenere occupata a runtime.
Per ora ho pensato ad una struttura del genere:

dichiaro una struttura "nodo_menu" che ha come elementi
un puntatore ad un nodo_menu parent
un puntatore ad un array di nodo_menu children
un valore, per memorizzare un eventuale parametro/opzione
un puntatore a carattere, che rimandi alla stringa da visualizzare.

in questo modo quando devo costruire la schermata dell'LCD vado al nodo parent di quello attuale e prelevo l'array dei children, da cui rilevo le stringhe da caricare e gli indirizzi delle variabili da modificare...

chiaramente una cosa così complessa non mi riuscirà in breve tempo, se avete idee o miglioramenti aiutatemi!!!:D

Unrealizer
12-03-2011, 10:57
Grande cosa le strutture, ho ridotto di tantissimo il codice del mio programma incapsulando variabili omologhe nella stessa struttura.

Il prossimo passo è creare un menù ad albero asimmetrico!
Mi spiego meglio:
voglio creare un menù con profondità variabile, ovvero dove si può scendere e salire di livello per arrivare a tutte le opzioni;
il problema di un menù del genere è ottimizzare sia la memoria programma in cui scriverlo sia la ram da tenere occupata a runtime.
Per ora ho pensato ad una struttura del genere:

dichiaro una struttura "nodo_menu" che ha come elementi
un puntatore ad un nodo_menu parent
un puntatore ad un array di nodo_menu children
un valore, per memorizzare un eventuale parametro/opzione
un puntatore a carattere, che rimandi alla stringa da visualizzare.

in questo modo quando devo costruire la schermata dell'LCD vado al nodo parent di quello attuale e prelevo l'array dei children, da cui rilevo le stringhe da caricare e gli indirizzi delle variabili da modificare...

chiaramente una cosa così complessa non mi riuscirà in breve tempo, se avete idee o miglioramenti aiutatemi!!!:D

buona idea :D che compilatore usi?

edit: scusa l'avevi scritto sopra xD cmq ti consiglio di passare al C18, a quanto so CCS ha vari problemi

jedineon
12-03-2011, 15:40
lo so, anzi lo BEN so, però al momento questo progetto un pò vecchio è scritto in CCS e siccome ha delle gestioni degli interrput un pò complesse voglio evitare di fare il porting per C18, visto che lo utilizzo da poco e non sono abbastanza smaliziato; in ogni caso ho iniziato col C18 e credo proprio che lo userò, per ora ho dato un'occhiata soprattutto alla gestione della USB e in particolare alla USB - MIDI e usb audio

Unrealizer
12-03-2011, 20:24
lo so, anzi lo BEN so, però al momento questo progetto un pò vecchio è scritto in CCS e siccome ha delle gestioni degli interrput un pò complesse voglio evitare di fare il porting per C18, visto che lo utilizzo da poco e non sono abbastanza smaliziato; in ogni caso ho iniziato col C18 e credo proprio che lo userò, per ora ho dato un'occhiata soprattutto alla gestione della USB e in particolare alla USB - MIDI e usb audio

USB-midi? o.o
io aspetto che mi arrivino i 18F4550 e la l'assegnazione del PID per smanettare con l'USB HID :D

jedineon
13-03-2011, 10:29
assegnazione del pid? e a che ti serve? io la HID l'ho fatta andare senza problemi usando VID e PID a casaccio, oppure usando quelli Microchip!

Unrealizer
13-03-2011, 14:42
assegnazione del pid? e a che ti serve? io la HID l'ho fatta andare senza problemi usando VID e PID a casaccio, oppure usando quelli Microchip!

sto aspettando proprio quelli Microchip... in ogni caso, aspetto pure i 4550 :D