vergalabs Inserito: 11 aprile 2023 Segnala Share Inserito: 11 aprile 2023 ciao ragazzi devo fare una cosa banalissima utilizzando un pic 16f629 e cioè attivare in sequenza 2 uscite dopo un certo tempo per un certo tempo all'accensione del pic ( tempo>out 1 on>tempo>out 1 off>tempo>out 2 on>tempo>out 2 off ). fino ad ora per fare quei 4 progetti dove ho utilizzato i pic ho usato parsic ma ora visto che parsic non supporta quel tipo di pic sto provando a utilizzare mplab-x-ide. ho rispolverato le mie poche conoscenze di C (troppo arrugginite) e ho partorito questo codice #include <stdio.h> #include <stdlib.h> #include <xc.h> #include <time.h> #define _XTAL_FREQ 4000000 /* * */ #define _XTAL_FREQ 4000000 #define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0))) #pragma config FOSC = INTRCIO #pragma config WDTE = OFF #pragma config PWRTE = ON #pragma config MCLRE = OFF #pragma config BOREN = OFF #pragma config CP = OFF #pragma config CPD = OFF void main() { TRISIO = 0; GPIO = 0; int i = 0; while (i < 5) { __delay_ms(2500); GP0 = 1; __delay_ms(500); GP0 = 0; __delay_ms(500); GP1 = 1; __delay_ms(500); GP1 = 0; i = i + 1; } } il ciclo funziona ma non si interrompe mai sembra che la variabile "i" che dovrebbe inerrompere il "while" una volta arrivata a 5 o non si incrementa mai o viene azzerata. in questo esempio il ciclo dovrebbe ripetersi 5 volte e poi fermarsi solo per prova, a me interesserebbe ripeterlo una volta sola all'accensione del circuito. grazie per l'aiuto Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 11 aprile 2023 Segnala Share Inserita: 11 aprile 2023 Invece di "i = i +1" scrivi "i++;" che lasintassi corretta in "C" Per fare quello che desideri scrivi qualche cosa del genere int flg_1ciclo = 0; ........ if flg_1ciclo > 0 ...... else qui scrivi quello che vuoi eseguire la prima volta flg_1ciclo = 1; Questo è un modo ma ne esistono molti altri Link al commento Condividi su altri siti More sharing options...
vergalabs Inserita: 11 aprile 2023 Autore Segnala Share Inserita: 11 aprile 2023 grazie livio con i++ ho già provato ma non funziona lo stesso, il ciclo non si interrompe ma continua all'infinito. proverò come mi hai suggerito. l'istruzione void main è scritta giusta? viene proposta direttamente dal compilatore appena si apre il programma Link al commento Condividi su altri siti More sharing options...
ilguargua Inserita: 11 aprile 2023 Segnala Share Inserita: 11 aprile 2023 Premetto che non conosco i PIC,e non li ho mai usati, ma come regola generica su piattaforme MCU credo il programma non dovrebbe mai raggiungere la fine del main(), o perlomeno non mi è chiaro cosa accada in quel caso. l'MCU si blocca? Riprende dall'inizio? Se è vera la seconda è quello che accade nel tuo caso. Prova a racchiudere il tuo while(i<5) dentro un altro loop infinito (tipo while(1) o for(;;) ) e vedi cosa accade. Peraltro i (pochi) programmi per PIC che mi è capitato di vedere funzionano tutti così. Ciao, Ale. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 11 aprile 2023 Segnala Share Inserita: 11 aprile 2023 (modificato) 1 ora fa, ilguargua ha scritto: ma come regola generica su piattaforme MCU credo il programma non dovrebbe mai raggiungere la fine del main(), No Ale, non è corretta la tua ipotesi ,c'è una cosa che mi è sfuggita alla prima lettura: lui scrive "int i = 0;" subito prima del "while"; questo fatto comporta che ad ogni ciclo di main la variabile si riazzera e ripete il ciclo di while. Basta dichiarare la variabile prima dell'inizioo del loop di main ed il ciclo di while sarà eseguito una sola volta. In pratica la variabile "i" va trattata come se fosse piubblica. Ci sono altri metodi ma per non sconvolgere troppo quello che ha fatto vergablas, questa è la soluzione più pratica. Modificato: 11 aprile 2023 da Livio Orsini Link al commento Condividi su altri siti More sharing options...
vergalabs Inserita: 11 aprile 2023 Autore Segnala Share Inserita: 11 aprile 2023 grazie ancora livio, adesso non posso fare delle prove ma tra i tanti tentativi mi sembra di aver già messo "int i = 0;" prima del while ma il ciclo non si interrompeva lo stesso, se invece mettevo "int i = 6;" ,ad esempio, il ciclo non veniva eseguito. è da qui che mi sono perso perchè ,se con "int i = 6;", il ciclo non viene eseguito vuol dire che la condizione while "funziona" ed è per questo che ho scritto che mi sembrava fosse la variabile "i" a non essere incrementata o a essere azzerata ad ogni ciclo. ho provato a scrivere per la somma i++, i = (i+1), i = i+1 ma senza successo. non può essere un problema di configurazione dei "fuses" della mcu ? nella vita mi occupo di programmazione plc ma purtroppo in scl non ho scritto dei gran programmi più che altro awl o kop, sicuramente mi sfugge qualcosa magari legato proprio ai pic Link al commento Condividi su altri siti More sharing options...
drn5 Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 (modificato) Sotto al primo while ne metti un altro While (I=>5){ I=I; } Così va in loop all'infinito perché nel primo non entrerà e resterà sempre a 5 .ovviamente con le varianti già spiegate sopra per la dichiarazione public delle variabili esterne al main Modificato: 12 aprile 2023 da drn5 Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 11 ore fa, vergalabs ha scritto: ma tra i tanti tentativi mi sembra di aver già messo "int i = 0;" prima del while Noo! Leggi bene quello che ho scritto! L'azzeramento deve essere fatto nella dichiarazione e la dichiarazione deve essere esterna al loop di main, altrimenti ogni volta che ripete il ciclo di main si ripete il ciclo di while 11 ore fa, vergalabs ha scritto: non può essere un problema di configurazione dei "fuses" della mcu ? ma no! E solo questione di logica! Nemmeno di sintassi del "C" o altro. Purtroppo i PLC son stati progettati per per permetterne la programmazione anche a chi è completamente digiuno dei rudimenti elementari di programmazione. Gli yankees sempre pronti a creare acronimi chiamano questi casi "GIGO" ==> Garbage In, Garbage Out; ovvero se nella macchina entrano rifiuti dalla macchina escono rifiuti. La macchina è stupida, fa quello che il programmatore gli dice. Anche se tu avessi scritto in AWL o in KOP farebbe la stessa cosa. Pensa di aver scritto in OB1, usando AWL la medesima sequenza. Inizia l'OB e azzeri un merker, poi testi il merker e, se è zero, chiami un FB che scrive le condizioni iniziali del programma e al termine mette a 1 quel merker. Il programma eseguirà ilmciclo di OB1 sino al termine, per poi ripartire dall'inizio, quindi ripeterai lo FB di inizializzazione ad ogni ciclo di OB1. Però nella realtà tu andrai a chiamare lo FB di inizializzazione testando lo SM che sta alto solo al primo ciclo, perchè il firmware del sistema operativo del PLC, che tu non vedi e non conosci, pensa a tutto. Quindi per te è impossiible che il ciclo possa ripetersi dopo il prio ciclo. Qui non hai un SO che esegue tutte queste operazioni ma le devi predisporre da te. Che tu scriva in assembler o in "C" le cose non cambiano, la prima fase di progettazione è sempre la progettazione della logica con cui deve evolvere il programma. Bisogba sempre mettere su carta, inizialmente, o il digramma di flusso o, meglio se si usano linguaggi strutturati, le specifiche dettagliate. Se tu scrivi il diagramma di flusso, in modo corretto, ti accrgi subito che quel ciclio di while si ripete all'infinito. Link al commento Condividi su altri siti More sharing options...
vergalabs Inserita: 12 aprile 2023 Autore Segnala Share Inserita: 12 aprile 2023 THIS PIC MAKE ME CRAZY !!! livio è chiarissimo quello che hai detto e infatti mi era già venuto quel dubbio e avevo spostato int=0 prima dell'inizio del main subito dopo la dichiarazione dei fuses (nel messaggio precedente non lo avevo specificato) ma non ne vuole sapere di funzionare ho provato come mi hai suggerito a utilizzare if/else ma anche così il ciclo si ripete all'infinito. Ora il mio dubbio è non è che la formattazione o l'uso di parentesi, punteggiature, e spazi vari l'ho scritta sbagliata ? Prima di chiedere qui ho cercato esempi , "corsi" online e guardato programmi scritti da me tempo fa sia in scl che in c ma proprio non riesco a capire dove sbaglio. DRn5 non ho ben capito quello che vuoi dire chi e quando la variabile "i" viene messa a zero. Qui sotto vi ho messo due screen di quello che ho scritto in base ai vostri suggerimenti ma come già anticipato anche così il ciclo si ripete all'infinito Link al commento Condividi su altri siti More sharing options...
ilguargua Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 (modificato) Mah, io rimango della mia opinione, non dovresti uscire dal main(). Prova a mettere un while(1){}; subito dopo il tuo ciclo while, prima del termine del main(), vedrai funziona. Ciao, Ale. EDIT : Qui una spiegazione dettagliata di cosa accade quando si esce dal main(), con un esempio proprio sui PIC. Modificato: 12 aprile 2023 da ilguargua Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 19 minuti fa, ilguargua ha scritto: io rimango della mia opinione, non dovresti uscire dal main(). Ma non esce dal main, non può uscire non c'è alcun interrupt o chiamata a funzioni esterne. Se mette il "while (1) {} dopo il ciclo di while rimarrà bloccato li sino a quando non interviene un eventualeinterrupt a cavarlo fuori! Semmai, se proprio si vuole che cicli sempre nel main, cosa pleonastica, è meglio fare void main() { int i = 0; while (1) { while (i < 5) { ....... i++; } } } Questa è la sintassi corretta, anche se pleonastica, affinchè il ciclo di while più interno venga eseguito coiìn i da 0 a 4; con i = 5 il programma ciclerà a tempo indefinito del primo loop di while. Link al commento Condividi su altri siti More sharing options...
ilguargua Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 19 minuti fa, Livio Orsini ha scritto: Ma non esce dal main Perchè no? quando il suo while finisce, termina anche il main(), e li esce. Cosa accade a quel punto dipende dalla piattaforma, sui PIC a quanto pare viene riavviata l'MCU (n.b. non viene richiamato il main(), ma viene eseguito anche tutto quello che c'è prima), gli ARM invece entrano in un loop infinito e li rimangono. E comunque nell'embedded non ha molto senso uscire dal main(), perchè il comportamento è indefinito (perlomeno dallo standard, ogni piattaforma può fare quello che vuole.). Ciao, Ale. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 1 ora fa, vergalabs ha scritto: THIS PIC MAKE ME CRAZY !!! Quello che ti succede non è ammissibile, è fuori da ogni regola. Scrivi qual compliatore "C" stai usando ed in quale ambiente stai lavorando. Potrebbe anche essere un problema di compilatore mal settato. Sono alcuni anni che non lavoro con i PIC ma un compilatore "C" è un compilatore "C", punto tanto per darti un esempio, il primo che ho ritrovato in un CD che avevo a portata di mano /*-------------------------------01-05-2001 18.05--------------------------------------* * * * MAIN * * ------------------------------------------------------------------------------------*/ void calib () { int i = 0; char c; short a; vis_cal_mes(1); #asm bcf flg_key_pres bcf flg_mesure bcf flg_up bcf flg_cal loop: #endasm /*-----------------------------------------01-06-2001 16.55----------------------------* * Eseguo calibrazioni di base * ------------------------------------------------------------------------------------*/ if(flg_i == true) calib_i(); if(flg_mv == true) calib_mv(); if(flg_th == true) calib_th(); if(flg_ph == true) calib_ph(); #asm bcf flg_2_sec loop0: btfss flg_2_sec goto loop0 btfsc flg_mesure goto end btfss flg_Up goto loop end: bcf flg_key_pres bcf flg_up bcf flg_mesure #endasm } E il main che esegue un programma di test e che richiama funzioni esterne specifiche. Il programma cicla a tempo indefinito si o a quando non viene premuto un certo tasto. Il programma è sicuramente funzionante visto che è servito a collaudare una certa quantità di un tipo di strumento. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 (modificato) 17 minuti fa, ilguargua ha scritto: Perchè no? quando il suo while finisce, termina anche il main(), e li esce. E perchè mai dovrebbe uscire? Dipende dal tipo compilatore ma, che io ricordi, andando a vedere l'assembler generato dal compilatore alla fine c'è un bel salto all'inizio, almeno sui compilatori HiTech e sui comnpilatori CCSC, che sono i due compliatori che ho sempre usato per i PIC. Non è questione di Hw, ma esclusivamente questione di compilatore. Comunque, come ti ho scritto prima, mettere il secondo while come hai indicato blocca in loop il programma. Guarda l'esempio main che ho riportato, per uscire dal main devo dare un'apposito comando. Modificato: 12 aprile 2023 da Livio Orsini Link al commento Condividi su altri siti More sharing options...
vergalabs Inserita: 12 aprile 2023 Autore Segnala Share Inserita: 12 aprile 2023 lo so che è strano, sto utilizzando l'ambiente di sviluppo proposto da microchip mplab x ide con installato il compilatore xc8 per programmare il pic utilizzo un clone del pickit 2 andando a pescare il file hex dalla cartella creata da mplab x ide. Una volta finito il while quando i>5 il ciclo non dovrebbe "ciclare" all'interno del void main e quindi scrivere una sola volta all'avvio del pic 0 nella variabile i ? ora provo a inserire il secondo while, in un modo o nell'altro Link al commento Condividi su altri siti More sharing options...
ilguargua Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 (modificato) 25 minuti fa, vergalabs ha scritto: Una volta finito il while quando i>5 il ciclo non dovrebbe "ciclare" all'interno del void main e quindi scrivere una sola volta all'avvio del pic 0 nella variabile i ? No, non c'è niente che lo faccia ciclare, quindi il main() esce quando terminano le istruzioni al suo interno, come qualunque altra funzione, e il programma riparte dall'inizio, compresa l'inizializzazione a 0 della variabile fuori dal main(). 25 minuti fa, vergalabs ha scritto: ora provo a inserire il secondo while, in un modo o nell'altro Funziona in entrambi i modi, tra l'altro la soluzione proposta da Livio è quella che avevo messo anch'io nel mia prima risposta, se lo scopo è bloccare completamente il micro dopo la sequenza fino al successivo reset entrambe le soluzioni sono equivalenti. Ciao, Ale. Modificato: 12 aprile 2023 da ilguargua Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 28 minuti fa, vergalabs ha scritto: ora provo a inserire il secondo while, in un modo o nell'altro No, non in un modo o nell'altro, ma come l'ho scritto io nella risposta ad Ale; se lo scrivi come proposto da lui esegue si una sola volta il ciclo while (i<5) perchè poi si blocca nel secondo ciclo di while. Questo è il compilatore in versione gratuita fornito da microchip? Se si dovrebbe avere l'opzione, nel faile listi, di mostrare anche lo asm, quindi si potrebbe vedere bene come risolve. Link al commento Condividi su altri siti More sharing options...
vergalabs Inserita: 12 aprile 2023 Autore Segnala Share Inserita: 12 aprile 2023 AND THE WINNER IS........................................... LIVIO !!!!!!!!!!!!!! finalmente funziona, ho provato ad inserire i due cicli while come suggerito da ilguargua e livio e il modo proposto da livio funziona correttamente, il ciclo vien ripetuto 5 volte all'accensione del pic. come ragionamento ci sta si esegue prima il while più interno incrementando "i" e una volta raggiunto i=5 si rimane bloccati nel primo while (1) a tempo indefinito. ora sotto con il saldatore che il pic va inserito al suo posto grazie come sempre a tutte le persone che su questo sito sono sempre pronte a darti una mano Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 6 minuti fa, ilguargua ha scritto: No, non c'è niente che lo faccia ciclare, quindi il main() esce quando terminano le istruzioni al suo interno, come qualunque altra funzione, e il programma riparte dall'inizio, compresa l'inizializzazione a 0 della variabile fuori dal main(). No riparte da sotto l'apertura della grafa. Questo l'ho osservato parecchie volte qaundo vado a vedere l'espansione in ASM per apportare ottimizzazioni. Dove c'è la grafa il compilatore risolve con una label e quando arriva all chiusura della grafa del main mette un salto alla prima label. Se così non fossse il PC proseguirebbe con quello che trova scritto in memoria. 10 minuti fa, ilguargua ha scritto: se lo scopo è bloccare completamente il micro dopo la sequenza fino al successivo reset entrambe le soluzioni sono equivalenti. No la tua blocca, la mia cicla senza eseguire alcuna operazione se non il salto.🙂 Link al commento Condividi su altri siti More sharing options...
vergalabs Inserita: 12 aprile 2023 Autore Segnala Share Inserita: 12 aprile 2023 11 minuti fa, Livio Orsini ha scritto: No riparte da sotto l'apertura della grafa. Questo l'ho osservato parecchie volte qaundo vado a vedere l'espansione in ASM per apportare ottimizzazioni. Dove c'è la grafa il compilatore risolve con una label e quando arriva all chiusura della grafa del main mette un salto alla prima label. appunto allora con int=0 scritto prima del main avrebbe dovuto funzionare 21 minuti fa, Livio Orsini ha scritto: No, non in un modo o nell'altro, ma come l'ho scritto io nella risposta ad Ale; se lo scrivi come proposto da lui esegue si una sola volta il ciclo while (i<5) perchè poi si blocca nel secondo ciclo di while. avrei dovuto scrivere: nei due modi proposti Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 12 aprile 2023 Segnala Share Inserita: 12 aprile 2023 L'importante è che tu abbia risolto. Però se pubblicassi il listato con l'opzione asm sarei curioso di capire come il tuo complitaore risolve. Link al commento Condividi su altri siti More sharing options...
vergalabs Inserita: 12 aprile 2023 Autore Segnala Share Inserita: 12 aprile 2023 sto guardando ma non trovo come si fa Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 13 aprile 2023 Segnala Share Inserita: 13 aprile 2023 Hai 2 opzioni metti il programma su un sito di hosting e poi metti il link nel messaggio. Oppure, se è non molto lungo, usa il tasto "code" che è quello con l'icona "<>", si apre una finestra dove tu incolli il testo del listato, come ho fatto io con il programma che ho inserito. Link al commento Condividi su altri siti More sharing options...
giacomo56 Inserita: 17 aprile 2023 Segnala Share Inserita: 17 aprile 2023 Ciao a tutti. Ho compilato il programma originale. Il compilatore inserisce alla fine del main un goto 0x00, per questo non termina mai. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 17 aprile 2023 Segnala Share Inserita: 17 aprile 2023 1 minuto fa, giacomo56 ha scritto: Ho compilato il programma originale. Il compilatore inserisce alla fine del main un goto 0x00, per questo non termina mai. Sicuro che sia alla locazione 0x00 e non ad una label? Mi sembra strano perchè così facendo riparte anche l'inizializzazione. Potresti copiare il codice e riportarlo qui? Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati
Crea un account o accedi per commentare
Devi essere un utente per poter lasciare un commento
Crea un account
Registrati per un nuovo account nella nostra comunità. è facile!
Registra un nuovo accountAccedi
Hai già un account? Accedi qui.
Accedi ora