Vai al contenuto
PLC Forum


P18F2550 Delay10Ktcyx()


Tecnica Impianti

Messaggi consigliati

Tecnica Impianti

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


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 :smile:

Modificato: da Nikiki
Link al commento
Condividi su altri siti

Tecnica Impianti

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

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

Tecnica Impianti

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

Tecnica Impianti

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

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: da GiRock
Link al commento
Condividi su altri siti

Tecnica Impianti

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

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: da Nikiki
Link al commento
Condividi su altri siti

Tecnica Impianti

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

Tecnica Impianti

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

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? :smile:

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

Tecnica Impianti

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: da Tecnica Impianti
Link al commento
Condividi su altri siti

Tecnica Impianti

#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

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. :smile:

Link al commento
Condividi su altri siti

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

Tecnica Impianti

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

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

Tecnica Impianti

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

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 account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...