Tecnica Impianti Inserito: 24 settembre 2012 Segnala Share Inserito: 24 settembre 2012 Buongiorno a tutti, ho decisamente un problema, beh in tanto vi informo che sono nuovo della programmazione PIC e piano piano sto imparando, ma ora mi trovo a scontrarmi con il lampeggio del led. Domanda come posso far lampeggiare un led sul pin RB1? con quale funzione? Di seguito vi riporto il codice che per ora mi fà accendere gli altri due led tramite pulsanti. Grazie #include <p18f2550.h> #include <delays.h> #pragma config1l FOSC = HS #pragma config WDT = OFF #pragma config LVP = OFF #pragma config PBADEN = OFF //OSC = HSPLL Impostato per lavorare ad alta frequenza con quarzo esterno //WDT = OFF Disabilito il watchdog timer //LVP = OFF Disabilito programmazione LVP //PBADEN = OFF Disabilito gli ingressi analogici void main (void){ // Imposto PORTA tutti ingressi TRISA = 0b1111111; ADCON1= 0b1111111;//Imposto come 1/0 tutti i pin del lato A, avrei potuto anche impostarne uno solo. // Imposto PORTB tutti ingressi TRISB = 0b11111000; // Imposto PORTC tutti ingressi TRISC = 0b1111111; //Dico al Pin RA0 che il suo stato se premuto è uguale a 1 cosi il Pin del LED RB0 si attiva while (1){ if(PORTAbits.RA0==1){ PORTBbits.RB0=1; } else{ PORTBbits.RB0=0; } //Stessa cosa al Pin RA1 come sopra riportato if(PORTAbits.RA1==1){ PORTBbits.RB2=1; } else{PORTBbits.RB2=0; } } } Si prega di notare, anche se non sono indicati i pulsanti codice di discussione e smile, sono ancora utilizzabili Link al commento Condividi su altri siti More sharing options...
Nikiki Inserita: 25 settembre 2012 Segnala Share Inserita: 25 settembre 2012 (modificato) ci sono vari modi. il più elementare (giusto per sperimentare) probabilmente è quello di incrementare una variabile ad ogni loop del main e verificando il valore con una "if" quando è X inverti lo stato dell'uscita e azzeri la variabile. maggiore sarà X e maggiore sarà il tempo necessario per raggiungerlo, di conseguenza il lampeggio sarà più lento. Il main luppa velocissimo, quindi se vuoi vedere lampeggiare il led non è sufficiente una int, ti servirà una long. esempio: #define lampeggio 100000 unsigned long tempo = 0; void main(void) { /*....configurazioni del micro varie...*/ while(1) { if (tempo == lampeggio) { /*..... inverti lo stato dell'uscita */ tempo = 0; } tempo ++; } } per rallentare i tempi di loop potresti inserire anche qualche delay (ho visto che avevi già incluso l'header delay.h) Altri metodi potrebbero essere l'utilizzo di un timer interno del micro ed eventualmente l'interrupt... ma probabilmente per questo è un po' presto Modificato: 25 settembre 2012 da Nikiki Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 25 settembre 2012 Autore Segnala Share Inserita: 25 settembre 2012 Ah ok ti ringrazio.... il mio obbiettivo però era utilizzare proprio delay10KTCYx() ieri ho provato ma non c'e' stato verso.... ti informo anche che nella mia basetta sperimentale c'e' un quarzo da 20Mhz collegata a osc1 osc2, ma non riesco proprio a utilizzare questo delay..... Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 25 settembre 2012 Segnala Share Inserita: 25 settembre 2012 Che compilatore usi? Verifica nell'help in linea cosa ti dice per la built in function delay10KTCYx(). Suggerimento. I delay, come i loop, sono da evitare perchè bloccano la CPU; si usano solo quando c'è da attendere per tempi brevissimi dell'ordine dei us e non è conveniente fare altrimenti. Per far lampeggiare un LED è meglio usare un temporizzatore basato su un interrupt legato ad un timer come, ad esempio, TIMER1 Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 25 settembre 2012 Autore Segnala Share Inserita: 25 settembre 2012 Buongiorno io uso MPlab con il PICKIT 2 e devo dire che mi trovo bene.... io non sono molto esperto mi sto cimentando da poco, sembra strano ma non riesco a fare lampeggiare un led, per ora sono riuscito a comandare 2 led con due pulsanti, poi ho provato a comandare un'altro led da un fotodiodo ma nulla da fare, fa delle cose stranissime. Ma quello poi me la vedo io. L'unica cosa che io vorrei e che quando dò corrente al mio PIC il led cominci a lampeggiare, ma non riesco proprio a farlo.... Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 25 settembre 2012 Segnala Share Inserita: 25 settembre 2012 Il programmino proposto da Nikiki dovrebbe far proprio quello che chiedi. Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 25 settembre 2012 Autore Segnala Share Inserita: 25 settembre 2012 IO so che lei è molto esperto e che avrebbe fatto un corso proprio sulla programmazione dei PIC su questo Forum, ma non sò se alla fine l'ha fatto o se ha lasciato stare. Io sarei molto interessato a seguirlo... Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 25 settembre 2012 Segnala Share Inserita: 25 settembre 2012 E' decaduto per scarsa partecipazione Link al commento Condividi su altri siti More sharing options...
GiRock Inserita: 25 settembre 2012 Segnala Share Inserita: 25 settembre 2012 (modificato) Sei fortunato, ho trovato un esempio in giro per le mie cartelle che funge da SUPERCAR su PORTB con timer ed interrupt, ora l'ho modificato per far lampeggiare il LED su RB7... +5V -> R 10k -> MCLR RB7 -> R 220 Ohm -> LED #include <htc.h> #include <18f2550.h> #define _INTOSC_FREQ 4MHZ #pragma config FOSC = INTOSCIO_EC #pragma config WDT = OFF #pragma config LVP = OFF #pragma config PBADEN = OFF #pragma config MCLRE = ON #pragma config PWRT = OFF #pragma config BOR = OFF #pragma config PLLDIV = 1 #pragma config LVP = OFF #pragma config DEBUG = OFF #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config VREGEN = OFF #pragma config CCP2MX = ON #pragma config PBADEN = OFF #pragma config LPT1OSC = ON #pragma config STVREN = OFF // __CONFIG(1, WDTEN & BOREN & PWRTEN & MCLREN & PLLDIV1 & PBADEN); bit sync, stato; static void interrupt isr(void) { if(TMR0IF&&TMR0IE) { TMR0IF=0; TMR0L=0xDC; TMR0H=0xB; sync=1; } } void InitGen(void) { OSCCON=0b01101110; ADCON0=0b00000000; ADCON1=0b00001111; CMCON=0x07; // Inizializzazione registro I/O LATB = 0x80; TRISB = 0B00000000; // Inizializzazione timer0 T0CON=0b10000010; TMR0ON=1; T08BIT=0; T0CS=0; T0SE=0; PSA=0; TMR0L=0xDC; TMR0H=0xB; // Abilitazione interrupt timer0 GIE=1; PEIE=1; TMR0IE=1; INT0IE=0; RBIE=0; TMR0IF=1; INT0IF=0; RBIF=0; // Disabilito l'Autoshutdown mode PRSEN=0; // Disabilito le pull-up su portB e cambio la priorità all'evento INT da hi in low INTCON2 =0b10000000; // Disabilito gli interrupt esterni su RB0 - RB1 - RB2 INTCON3 =0b00000000; // Inizializzo variabili stato=1; } void main(void) { InitGen(); // inizializza il PIC ad ogni RESET while (1) { while(!sync); sync=0; //SUPERCAR su PORTB //if (stato==0) LATB=LATB<<1; // else LATB=LATB>>1; //BLINKER SU RB7 RB7^=1; if (LATB0) stato=0; if (LATB7) stato=1; } } Modificato: 25 settembre 2012 da GiRock Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 25 settembre 2012 Autore Segnala Share Inserita: 25 settembre 2012 Ciao e grazie GIRock per aver scartabellato tra i tuoi documenti per me, sicuramente l'ho proverò ma devo anche cercare di capire cosa hai fatto, il copia e incolla non mi è mai piaciuto....... COMUNQUE grazie tantissimo...Come e decaduto....... che peccato io avrei partecipato attivamente..... seguire un corso è decisamente meglio che andare a leggere un pò qui un pò li sulla programmazione dei PIC. PECCATO.... Link al commento Condividi su altri siti More sharing options...
Nikiki Inserita: 25 settembre 2012 Segnala Share Inserita: 25 settembre 2012 (modificato) Perchè vuoi usare proprio la delay10KTCYx()?... c'è un motivo particolare o è semplicemente la prima che hai trovato? Questa funzione esegue un delay di un multiplo di 10000 cicli (10000 moltiplicato per il valore passato alla funzione), in questo caso per calcolare il tempo effettivo devi passare un valore tenendo in considerazione la frequenza di clock. Per un delay di un tempo x è più semplice usare la funzione DelayMs(x) che conta un delay di x millisecondi. L'unico limite è che x è una unsigned char, quindi il valore massimo che puoi passare è 255, ma come diceva giustamente Livio non è mai conveniente usare ritardi lunghissimi perchè durante il delay il micro rimane piantato li e non fa nient'altro. Comunque, sempre giusto per sperimentare, se vuoi tempi più lunghi basta chiamarla più volte consecutivamente. Ad esempio: DelayMs(250); DelayMs(250); DelayMs(250); DelayMs(250); esegue un delay di 1 secondo. Per usarla devi dare in pasto al preprocessore anche queste due righe: #include <delay.c > //include il file con le funzioni di delay #define XTAL_FREQ 20MHZ //dichiara la frequenza di clock del micro per calcolare il delay correttamente Ma che compilatore usi?... te l'hanno già chiesto ma non hai risposto. MPLAB è l'IDE ma il compilatore? Modificato: 25 settembre 2012 da Nikiki Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 26 settembre 2012 Segnala Share Inserita: 26 settembre 2012 Usa, propabilemente, la versione ligth dello High Tech che è inclusa free nel pacchetto MPLAB Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 26 settembre 2012 Autore Segnala Share Inserita: 26 settembre 2012 Ciao il compilatore è il C18 di MPlab appunto, ma il delay.c che dici tu è una libreria che io non ho. Io ho delays.h incluso sempre nel MPlab e la sequenza che lo fà funzionare è proprio delay10KTCYx. Anche questa funzione calcola x per millisec. con questa formula: Ritardo desiderato 500 ms Moltiplicatore=---------------------------- = --------------------- = 125 questo con una frequenza iniziale di 10 Mhz Ritardo base 4 ms Quindi facendo delay10KTCYx(125) ottengo un ritardo di mezzo secondo, adesso che il sistema poi patisca ok ma a questo punto usare questo o usare quello proposto da te non è la stessa cosa? Grazie Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 26 settembre 2012 Autore Segnala Share Inserita: 26 settembre 2012 Ed ecco qui finalmente sono riuscito..... atc che soddisfazione..... vi posto il codice cosi' se notate qualcosa di strano me lo dite. Prossima tappa e abilitare il quarzo esterno e iniziare a provare gli interrupt... c'e' la farà il nostro eroe? #include <p18f2550.h> #include <delays.h> #pragma config FOSC = HS #pragma config WDT = OFF #pragma config LVP = OFF #pragma config PBADEN = OFF //OSC = HSPLL Impostato per lavorare ad alta frequenza con quarzo esterno //WDT = OFF Disabilito il watchdog timer //LVP = OFF Disabilito programmazione LVP //PBADEN = OFF Disabilito gli ingressi analogici void main (void){ // Imposto PORTA tutti ingressi TRISA = 0b1111111; ADCON1= 0b1111111;//Imposto come 1/0 tutti i pin del lato A, avrei potuto anche impostarne uno solo. // Imposto PORTB tutti ingressi TRISB = 0b11111000; // Imposto PORTC tutti ingressi TRISC = 0b1111111; //Dico al Pin RA0 che il suo stato se premuto è uguale a 1 cosi il Pin del LED RB0 si attiva if(PORTAbits.RA0==1){ PORTBbits.RB0=0; } else {PORTBbits.RB0=1; } if(PORTAbits.RA1==1){ PORTBbits.RB1=0; } else{PORTBbits.RB1=1;} for(;{ PORTBbits.RB2=~PORTBbits.RB2; Delay10KTCYx(500); } while (1){ } Link al commento Condividi su altri siti More sharing options...
Nikiki Inserita: 26 settembre 2012 Segnala Share Inserita: 26 settembre 2012 adesso che il sistema poi patisca ok ma a questo punto usare questo o usare quello proposto da te non è la stessa cosa? Un delay è un delay... puoi fare anche un loop che cicla su se stesso. Ti ho suggerito un'altra funzione soprattutto perchè avevi detto che non eri riuscito a farla funzionare, dettagli non ne avevi dati, la funzione è elementare quindi ho semplicemente supposto che non fosse inclusa nel tuo compilatore e ne ho suggerita un'altra. In ogni caso anche se il calcolo è semplice, con DelayMs non c'è bisogno di calcolare niente, gli passi direttamente i millisecondi. vi posto il codice cosi' se notate qualcosa di strano me lo dite. ti sei accordo che nel configurare TRISA e TRISC hai messo solo 7 bit? Quando posti il codice mettilo tra i tag "code" o usa il pulsante "<>", in questo modo eviti incidenti tipo la faccina del post precedente che rendono la lettura difficile. Sembra che tu abbia fatto una "for" senza condizioni, che in pratica si comporta come una while(1).. tanto valeva che tu scrivessi il codice in questo blocco per far lampeggiare il led. Prossima tappa e abilitare il quarzo esterno e iniziare a provare gli interrupt... c'e' la farà il nostro eroe? L'esempio che ti ha postato GiRock usa appunto il timer0 e relativo interrupt. Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 27 settembre 2012 Autore Segnala Share Inserita: 27 settembre 2012 (modificato) Ciao e grazie per l ìe risposte il TRISA e il TRISC hanno solo 7 pin io sto utilizzando il 18f2550 per quello che ho messo solo 7 bit giusto? o faccio io confusione? IL codice che mi ha postato ROCK sicuramente devo provarlo ma prima devo capire come funzionano gli INTERRUPT e il TIMER0 altrimenti faccio solo un copia e incolla del suo codice e alla fine non ho capito nulla. Domanda gli INTERRUPT possono essere generati solo dall'esterno o anche dall'interno del chip? Il Delay che mi suggerisci tu io non c'e' l'ho nella mia libreria perchè uso come compilatore C18 e non HIGHT TECH quindi non saprei proprio come utilizzarlo, ma penso nella mia ignoranza che il delay che dici tu e quello che dico io in fine siano simili. Tra le altre cose nel codice che mi è stato suggerito da Rock c'e' questo simbolo << >> che sono gli shift ma io ancora non ben chiaro come funzionano, io piano piano sto usando una funzione per volta in modo da capirla fino in fondo come anche per i simboli, finchè non ho capito il loro utilizzo non ne faccio uso giusto per non confondermi le idee. è sbagliato come approccio il mio? Modificato: 27 settembre 2012 da Tecnica Impianti Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 27 settembre 2012 Autore Segnala Share Inserita: 27 settembre 2012 #include <delays.h> #pragma config FOSC = HSPLL_HS #pragma config PLLDIV=2 #pragma config IESO= ON #pragma config WDT = OFF #pragma config LVP = OFF #pragma config PBADEN = OFF //OSC = HSPLL_HS Impostato per lavorare ad alta frequenza CON PLL ATTIVATO //PLL = attivato la divisione //WDT = OFF Disabilito il watchdog timer //LVP = OFF Disabilito programmazione LVP //PBADEN = OFF Disabilito gli ingressi analogici //PLLDIV1= divisione PLL //Impostazione per bassa priorità void Low_Int_Event (void); #pragma code low_vector=0x18 void low_interrupt (void){ //salto per la gestione dell'interrupt a bassa priorità _asm GOTO Low_Int_Event _endasm; } #pragma code #pragma interruptlow Low_Int_Event //Funzione per la gestione dell'interrupt a bassa priorità void Low_Int_Event (void){ // controllo che l'interrupt sia stato generato dal timer0 if(INTCONbits.TMR0IF==1){ PORTBbits.RB2=~PORTBbits.RB2; INTCONbits.TMR0IF=0; } } void main (void){ //Abilitazione oscilatore interno OSCTUNEbits.INTSRC=1; OSCTUNEbits.TUN4=0; OSCTUNEbits.TUN3=0; OSCTUNEbits.TUN2=0; OSCTUNEbits.TUN1=0; OSCTUNEbits.TUN0=0; OSCCONbits.IRCF2=1; OSCCONbits.IRCF1=1; OSCCONbits.IRCF0=1; OSCCONbits.IOFS=1; OSCCONbits.SCS1=0; OSCCONbits.SCS0=0; //Abilitazione TIMER0 T0CONbits.TMR0ON=1; //abilito il timer0 T0CONbits.T08BIT=0; // lo configuro a 16 bit T0CONbits.T0CS=0; //clock interno T0CONbits.T0SE=0; T0CONbits.PSA=0; // assegno il prescaler al timer0 T0CONbits.T0PS2=1; //valore di prescaler 1:32 T0CONbits.T0PS1=1; //valore di prescaler 1:32 T0CONbits.T0PS0=1; //valore di prescaler 1:32 TMR0L=1; // sistema abilitato a bassa priorità TMR0H=0; // sistema non abilitato all'alta priorità INTCONbits.TMR0IE=1; //interruzioni abilitate INTCONbits.TMR0IF=1; // abilito la visualizzazione dell'evento sul timer1 INTCON2bits.TMR0IP=0; // abilito per bassa priorità // Imposto PORTA tutti ingressi TRISA = 0b11111111; ADCON1= 0b11111111;//Imposto come 1/0 tutti i pin del lato A, avrei potuto anche impostarne uno solo. // Imposto PORTB tutti ingressi TRISB = 0b11111100; // Imposto PORTC tutti ingressi TRISC = 0b11111111; //Dico al Pin RA0 che il suo stato se premuto è uguale a 1 cosi il Pin del LED RB0 si attiva if(PORTAbits.RA0==1){ PORTBbits.RB0=0; } else {PORTBbits.RB0=1; } if(PORTAbits.RA1==1){ PORTBbits.RB1=0; } else{PORTBbits.RB1=1;} while (1){ } } Domanda ho provato a rifare il codice per far lampeggiare il famoso led con il timer0 abilitando oscillatore interno cosi com'e non fa nulla ma aggiungendo PLLDIV=2 mi fà lampeggiare e anche male tutti i led che ci sono. come mai?????? Link al commento Condividi su altri siti More sharing options...
Nikiki Inserita: 27 settembre 2012 Segnala Share Inserita: 27 settembre 2012 il TRISA e il TRISC hanno solo 7 pin io sto utilizzando il 18f2550 per quello che ho messo solo 7 bit giusto? o faccio io confusione? Si, hanno solo 7 pin, ma internamente il registro ha ugualmente 8 bit. Come lo scrivi tu in pratica ometti il bit più significativo, per il PORT A potrebbe anche andare bene perchè il pin mancante è prioprio RA7, ma sul PORT C il pin mancante è l'RC3 quindi l'istruzione che usi tu non può influenzare il bit più significativo che corrisponde a RC7. Nel tuo caso cambia poco, perchè i bit del registro TRIS sono tutti a 1 al reset, ma se tu li volessi configurare come uscite, usando solo 7 bit nell'istruzione, il pin RC7 rimarrebbe un ingresso. Ci sono molti aspetti dell'hardware che non sono per niente scontati, e che è importante conoscere prima di tutto, quindi contemporaneamente ai tuoi esperimenti ti consiglio di leggere il datasheet del 18F2550 dove troverai tutto quello che c'è da sapere. Bisogna conoscere l'hardware, per poterlo padroneggiare con la programmazione. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 27 settembre 2012 Segnala Share Inserita: 27 settembre 2012 Bisogna conoscere l'hardware, per poterlo padroneggiare con la programmazione. Parole sante. Dopo 35 anni che traffico professionalemente con microprocessori e microcontrollori non posso che sottoscrivere. Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 28 settembre 2012 Autore Segnala Share Inserita: 28 settembre 2012 Guarda credimi che tra un pò lo conosco a memoria...... il problema e che è tutto in inglese quindi diventa anche laborioso, io l'inglese lo conosco da strada ovvero giusto per scambiare due parole con qualche straniero..... quindi....... Link al commento Condividi su altri siti More sharing options...
Nikiki Inserita: 29 settembre 2012 Segnala Share Inserita: 29 settembre 2012 Se ti può consolare io ad uno straniero avrei qualche difficoltà a parlargli... conosco l'inglese tecnico perché sono cresciuto sui datasheet, a scuola mi hanno "obbligato" a studiare il francese, una lingua inutile per chi vuole studiare elettronica... (in Italia siamo capaci anche di questo, ci si preoccupa piu di garantire il posto ad un insegnante di francese piuttosto che garantire il futuro a centinaia di studenti ). Comunque benché sia un po' faticoso il tempo perso sul datasheet te ne fa risparmiare parecchio sullo sviluppo. Link al commento Condividi su altri siti More sharing options...
Tecnica Impianti Inserita: 1 ottobre 2012 Autore Segnala Share Inserita: 1 ottobre 2012 E tu hai perfettamente ragione anchio odio il francese nonostante abbia parenti in Francia..... il problema che crea però tradursi il datasheet in italiano sta proprio nella traduzione, ovvero se tralasci qualcosa non ne vieni più a capo. IO infatti sto impazzendo con gli interrupt e il timer 0 non riesco più a capire cosa devo abilitare e no per riuscire a fare lampeggiare un cavolo di led. Riuscirò prima o poi?????? MA!!!!! Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 1 ottobre 2012 Segnala Share Inserita: 1 ottobre 2012 Devi abilitare solo l'interrupt del timer0 e poi gli interrupt globali, in questo ordine. 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