BaroneRosso.it - Forum Modellismo

BaroneRosso.it - Forum Modellismo (https://www.baronerosso.it/forum/)
-   Circuiti Elettronici (https://www.baronerosso.it/forum/circuiti-elettronici/)
-   -   info linguaggio c x pic (https://www.baronerosso.it/forum/circuiti-elettronici/189595-info-linguaggio-c-x-pic.html)

elicottero78 01 dicembre 10 01:37

ci sto provando ma niente


char tempo;
void interrupt(){
if((OPTION_REG.INTEDG == 1) && (INTCON.F1 == 1))
{
TMR0 = 0;
OPTION_REG.INTEDG=0; //fronte di discesa
INTCON.F1=0; //reset del flag

if (INTCON.T0IF=1)
{
tempo=0;
}
}
if((OPTION_REG.INTEDG == 0) && (INTCON.F1 == 1))
{
tempo=TMR0; //prento il timer
OPTION_REG.INTEDG=1; //imposto controllo sul fronte di salita
INTCON.F1=0; //reset del flag
}

}
void main() {
trisa=0;
trisb=0b00000001;
porta=0;
portb=0;
OPTION_REG.T0CS = 0; //imposto l'utilizzo del clock
OPTION_REG.PSA = 0; //imposto il tipo di prescaler da utilizzare
OPTION_REG.PS0 = 1; //
OPTION_REG.PS1 = 1; //imposto il prescaler a 16
OPTION_REG.PS2 = 0; //
INTCON.T0IF = 0; //azzero interrupt timer
OPTION_REG.INTEDG = 1; //imposto controllo sul fronte di salita
INTCON.F1 = 0; //reset flag
INTCON = 0b00010000; //impostato unico interrupt rb0
INTCON.GIE = 1;
while(1){
if(tempo > 80)
{
portb=160;
delay_ms(500);
portb=32;
delay_ms(500);
portb=128;
delay_ms(500);
portb=32;
delay_ms(500);
}else{
portb=0;

}
if(tempo=0)
{
portb.f7=1;
delay_ms(1000);
portb.f7=0;
delay_ms(1000);
}

}
}

MSchiepp 01 dicembre 10 08:49

Citazione:

Originalmente inviato da elicottero78 (Messaggio 2329688)

if(tempo=0)
{
portb.f7=1;
delay_ms(1000);
portb.f7=0;
delay_ms(1000);
}

In C il test di uguaglianza vuole 2 segni == !!

if (tempo == 0)

oppure:

if (!tempo)

Michele

illez 01 dicembre 10 08:55

Premessa: non mi ci ritrovo tanto con il Mikroc, sono abituato al ccs.

Se non capisco male, vuoi fare qualcosa su portb se tempo>0.
Forse vuoi far lampeggiare dei led, aspettando mezzo secondo tra una configurazione e l'altra.

Codice:

        if(tempo > 80)
        {
            portb=160;
            delay_ms(500);
            portb=32;
            delay_ms(500);
            portb=128;
            delay_ms(500);
            portb=32;
            delay_ms(500);
        }else{
            portb=0;

        }

Il problema di fondo che io vedo è legato all'uso della variabile tempo.
Questa viene impostata in maniera asincrona dalla funzione che gestisce l'interrupt e controllata all'interno del ciclo while infinito nel main.
Leggi la variabile tempo e in base al suo valore decidi cosa fare.
Perfetto.
Solo che la variabile tempo cambia continuamente di valore perché gli interrupt arrivano uno dietro l'altro.
Per rimediare puoi per esempio fare così:
puoi effettuare la misurazione e, una volta impostata la var tempo, disabilitare gli interrupt. La routine nel main esamina tempo e quando lo trova impostato, esegue qualcosa e riabilita gli interrupt.
Evita di eseguire lungi cicli come
Codice:

if(tempo=0)
  {
      portb.f7=1;
      delay_ms(1000);
      portb.f7=0;
      delay_ms(1000);
    }

In questi 2 secondi sai quanti interrupt arrivano e tu non esamini il valore di tempo?
Per assurdo potresti leggerlo sempre a 0.
Ad esempio: lo leggi una volta, è zero, esegui quanto sopra che dura circa 2 secondi (!) durante i quali chissà quante volte viene impostato tempo. Poi ripeti il controllo e, putacaso, tempo è stato appena azzerato per cui rifai quanto sopra per altri 2 secondi...!:rolleyes:

[EDIT]
:icon_rofl
Badavo alla logica del programma e mi era sfuggito if (tempo=0)!!!

Vado a prendere il caffé, meglio :D

elicottero78 01 dicembre 10 13:50

grazie mille,stasera appena la bimba è a letto,mi rimetto all opera

x illez
io ho messo if tempo =0
xchè quando spengo la radio con lo stic alto,il pic continua a far lampeggiare i 2 led alternati.....evidentemente xchè a in memoria ancora l ultimo valote del trm0.....io invece voglio che se non c è piu segnale...tutto si deve spegnere e deve solo lampeggiare a cadenza di un secondo il led su portb.f7

xò ho notato anche una cosa a me strana con radio sempre accesa,se alzo lo stic della radio,attivo i 2 led alternati.....ma quando porto lo stic a 0,questi 2 led alternati,prima finiscono il loro ciclo e poi si spengono....

la mia domanda è: xchè quando porto lo stic a 0 i 2 led alternati non smettono immediatamente di lampeggiare?

illez 01 dicembre 10 14:54

Citazione:

Originalmente inviato da elicottero78 (Messaggio 2330078)
[...]
la mia domanda è: xchè quando porto lo stic a 0 i 2 led alternati non smettono immediatamente di lampeggiare?

Non smettono immediatamente cosa vuol dire?

Come ti dicevo, il codice non è strutturato benissimo.
Di sicuro questo pezzo di codice non può essere interrotto (non sto parlando degli interrupt)
Codice:

if(tempo > 80)
  {
    portb=160;
    delay_ms(500);
    portb=32;
    delay_ms(500);
    portb=128;
    delay_ms(500);
    portb=32;
    delay_ms(500);
  }else{
    portb=0;
 }

se tempo>80, le istruzioni dopo l'if vengono eseguite una dietro l'altra ed eventuali interrupt portano solo ad un cambiamento della variabile tempo, non uscirai dall'if solo perché l'int ti ha cambiato il valore della variabile.
Mi son spiegato?
Tralasciamo gli interrupt per un attimo: il microprocessore esegue le istruzioni una dopo l'altra; quando arriva all'if sopra citato, controlla il valore della (locazione di memoria associata alla) variabile tempo, lo confronta con 80 e se maggiore esegue il contenuto dell'if, altrimenti salta ad eseguire la parte nell'else. Fatto questo controllo, prosegue con le istruzioni successive, ritornerà ad eseguire questo if solo dopo essere arrivato alla fine del while e ricontrollato la condizione (sempre vera). Per fare questo impiegherà almeno 2 secondi (ci sono 4 delay_ms(500) )durante i quali, in apparenza, non farà altro.
In realtà, durante questi 2 secondi, il microprocessore interrompe la sua normale esecuzione e 'salta' ad eseguire la routine di interrupt ogni volta che si verifica l'evento di cambio di livello su RB0 (fronte di salita o discesa, a seconda di come è stato programmato l'interrupt).
Salta vuol dire che vengono salvati i registri, si interrompe l'esecuzione del flusso normale del programma e si passa ad eseguire la routine dedicata alla gestione degli int. Terminata questa, vengono ripristinati i registri e il microprocessore ritorna ad eseguire il programma nel punto in cui si era interrotto, come se nulla (si fa per dire) fosse accaduto.

Dimenticavo:

Cambia immediatamente quel


Codice:

if tempo =0
in
Codice:

if (tempo==0)
!!!!!!!!!!!!!!!!!!!!!!!!!:blink:

elicottero78 01 dicembre 10 18:28

scusami :unsure:, if tempo =0 l ho scritto velocemente come testo non come lo scrivo nel programma

penso di aver capito che fin quando non finisce

if(tempo > 80) {
portb=160;
delay_ms(500);
portb=32;
delay_ms(500);
portb=128;
delay_ms(500);
portb=32;
delay_ms(500);
}else{
portb=0;
}


i 2 led lampeggieranno sempre fino alla fine del ciclo.....allora provo a spararne una grossa cavolata........

ma se io invece di scrivere

while(1)

scrivessi

while(tempo > 80)
non risolverei questo problema ?

scusami se ho detto una cavolata

illez 01 dicembre 10 18:32

Citazione:

Originalmente inviato da elicottero78 (Messaggio 2330507)
scusami :unsure:, if tempo =0 l ho scritto velocemente come testo non come lo scrivo nel programma

penso di aver capito che fin quando non finisce

if(tempo > 80) { portb=160; delay_ms(500); portb=32; delay_ms(500); portb=128; delay_ms(500); portb=32; delay_ms(500); }else{ portb=0; }
i 2 led lampeggieranno sempre fino alla fine del ciclo.....allora provo a spararne una grossa cavolata........

ma se io invece di scrivere

while(1)

scrivessi

while(tempo > 80)
non risolverei questo problema ?

scusami se ho detto una cavolata

:rolleyes:
Codice:

portb=160;
  delay_ms(500);   
portb=32;   
delay_ms(500);
    portb=128;
  delay_ms(500);   
portb=32;   
delay_ms(500);

Queste istruzioni impiegano circa 2 secondi per essere eseguite.
Vedi qualcosa tra un'istruzione e l'altra che ne possa interrompere l'esecuzione una dopo l'altra???
(la risposta è, ovviamente, no)
Il problema non è il while, ma il fatto che queste istruzioni non possono essere interrotte...

claudio476 03 dicembre 10 15:20

Citazione:

Originalmente inviato da illez (Messaggio 2330514)
Il problema non è il while, ma il fatto che queste istruzioni non possono essere interrotte...


Aggiungo giusto una cosetta per chi non la sapesse: i cicli, di qualunque tipo siano, while, for etc.. controllano la condizione ad inizio o fine ciclo ma mai nel mezzo..


Tutti gli orari sono GMT +2. Adesso sono le 20:07.

Basato su: vBulletin versione 3.8.11
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
E' vietata la riproduzione, anche solo in parte, di contenuti e grafica. Copyright 1998/2019 - K-Bits P.I. 09395831002