cloe Inserito: 4 aprile 2006 Segnala Share Inserito: 4 aprile 2006 ciao a tutti, ho un problema con la seriale gestita tramite interruzioni che mi sta mandando al manicomio...premetto che interfaccio il pic con labview per la gestione di un motore passo-passo.il codice è Questo:#include <16f876.h>#FUSES HS, WDT//clock 20Mhz con reset del watchdog nei timers#use delay(clock=20000000, restart_wdt)#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)#priority rda, timer1 //dà la priorità all'interrupt della serialeBYTE stop;#int_rdavoid serial_isr() { char cmd; int i; for (i=0;i<5;i++) { output_high(PIN_B7); delay_ms(200); output_low(PIN_B7); delay_ms(200); } cmd=getch(); if (cmd == 's') stop=0; }int16 ang_vel();int16 ang_vel(){ char cmd1, cmd2, cmd3; int16 d1, d2, d3, val; cmd1=getch(); //centinaia d1=(int16)cmd1-48; delay_ms(100); cmd2=getch(); //decine d2=(int16)cmd2-48; delay_ms(100); cmd3=getch(); //unità d3=(int16)cmd3-48; delay_ms(100); val=(d1*100)+(d2*10)+d3; return val;}void main(){ int16 step; int16 i, t, w; int16 angolo, ang_fin, num_step, step_rimanenti; int16 rpm, rpm_fin, duty, giri, num_giri; int q, r, d, riduzione; int16 q1,r1; SET_TRIS_A(0b00001000); SET_TRIS_B(0x00); SET_TRIS_C(0x80); stop = 1;//azzera il buffer di ricezione // BuffLen=0; //led alimentazione output_high(PIN_B7); //accensione motore output_high(PIN_A2); //rotazione impostata in senso antiorario di default output_high(PIN_A1); delay_us(150); while(TRUE) { //restart_wdt(); //resetta il watchdog switch(getch()) { case 'c': output_high(PIN_A2); //rotazione in senso antiorario delay_us(150); output_high(PIN_A1); delay_us(150); break; case 'd': //rotazione in senso orario delay_us(150); output_low(PIN_A1); delay_us(150); break; case 'v': rpm=ang_vel(); rpm_fin=rpm*2*riduzione; duty=3*1000000/(40*rpm_fin); q1=duty/256; q=(int)q1; r=(int)duty-q1*256; putc('w'); break; case 'r': //rotazione continua //disable_interrupts(global); //disabilita tutti gli interrupt enable_interrupts(int_rda); //abilita gli interrupt della seriale enable_interrupts(global); //riabilita tutti gli interrupt if (duty>=210) //velocità imponibile a motore fermo { while (stop) { output_high(PIN_A0); for (t=0;t<q;t++) delay_us(255); delay_us®; output_low(PIN_A0); for (t=0;t<q;t++) delay_us(255); delay_us®; } } else { d=210; while( d>duty & stop) { //buffer di ricezione vuoto for (w=0;w<50;w++) { output_high(PIN_A0); delay_us(d); output_low(PIN_A0); delay_us(d); } d=d-1; } if (d<=duty) { while (stop) { output_high(PIN_A0); delay_us(duty); output_low(PIN_A0); delay_us(duty); } } } putc('y'); break; case 'b': riduzione=ang_vel(); putc('n'); break; } }}la prima domanda è Questo: ho notato che se non metto le istruzioni di abilitazione all'interno del "case'r' " il motore non si muove (il motore si muove con la sequenza di impulsi sul pinA0). seconda domanda: mettendo le istruzioni nel case 'r' il motore ruota la prima volta, ma quando vado a riavviarlo esegue tutte le istruzioni ma non manda tensione su A0 quindi il motore non si muove. la domanda sorge spontanea: non è che le interruzioni in qulache modo interferiscono col PIN A0?per favore aiutatemi perchè non ce la faccio +grazie Link al commento Condividi su altri siti More sharing options...
ifachsoftware Inserita: 4 aprile 2006 Segnala Share Inserita: 4 aprile 2006 Un interrupt va processato ed abbandonato il prima possibile.Il metterci un ritardo di 200 ms per di piu' bloccante nella funzione che processa un interrupt e' una cosa senza capo ne' coda.Nell'interrupt si acquisisce su di un bit il comando di start o stop ; poi nel main loop lo si puo' andare a processare.Ciao Link al commento Condividi su altri siti More sharing options...
cloe Inserita: 4 aprile 2006 Autore Segnala Share Inserita: 4 aprile 2006 effettivamente mettere il for nella routine di servizio dell'interrupt non è una cosa proprio carina, ma l'avevo aggiunta per motivi di debug. comunque anche togliendo il for il motore non riparte.putroppo il controllo sul carattere ricevuto non posso metterlo fuori dalla routine di interrupt altrimenti non riesco a dare la coppia di spunto necessaria al motore per accelerare.hai altri suggerimenti?grazie ancora Link al commento Condividi su altri siti More sharing options...
ifachsoftware Inserita: 4 aprile 2006 Segnala Share Inserita: 4 aprile 2006 La lettura del carattere VA FATTA nell'interrupt (se no a cosa serve l'interrupt ?).Quando viene ricevuto l'interrupt la funzione getch() non aspetta nulla perche' il carattere e' gia' presente (e' il motivo per cui ti viene alzato l'interrupt) e a quel punto puoi o mettere il valore in un buffer globale che processi nel main loop quando hai ricevuto tutti i dati della tua scritta oppure decodificare la stringa direttamente nell'interrupt (a patto di non metterci troppo tempo e per capire quanto ci mette puoi usare il debugger dell'MPLAB con un paio di break point all'entrata ed all'uscita dell'interrupt e misurare il tempo che ci mette che naturalmente dovra' essere inferiore al tempo di arrivo tra un carattere e l'altro altrimenti rischi di perdere dei dati della seriale).Per quello che non ti funziona sarebbe una bella cosa spiegare esattamente che cosa non va e magari ti si puo' dare una mano ...Ciao Link al commento Condividi su altri siti More sharing options...
cloe Inserita: 4 aprile 2006 Autore Segnala Share Inserita: 4 aprile 2006 ti spiego...in base al carttere che il pic riceve via seriale si entra in un ramo del case. quindi prima gli faccio settare il verso di rotazione, poi la velocità e il rapporto di riduzione ed infine, quando mi arriva il carattere 'r' faccio partire il motore mandandogli degli mpulsi sul pin A0. a Questo punto il motore si mette in rotazione fino a quando non gli invio il carattere 's' che determina stop=0 quindi il motore si ferma.il problema è Questo: la prima volta che metto il moore in rotazione non ci sn problemi. io però vorrei poter far rimettere il motore in movimento magari con un'altra velocità di rotazione (infatti c'è il while (true)) ma il pic esegue il main correttamente senza però mandare tensione su A0 quindi non riesco ad avere successive rotazioni. so per certo che il pic esegue il codice perchè invia a labview correttamente tutti i caratteri di sincronizzazione.spero di essere stata il + chiaro possibile, così almeno potete aiutarmigrazie 1000 per l'aiuto 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