Errore compilatore PicC

Save a tutti Sto facendo un programmino che scrive dei dati su un display e mi sono creato la funzione Display(); che fa tutte le operazioni di scrittura, Quando vado a compilare mi da questo errore:

function _Display appears in multiple call graphs: rooted at _prv_int and _main (error)

Praticamente non gli va bene che richiamo la funzione sia nel main che nella funzione di interrupt, però a me serve richiamarla in tutti e 2 i momenti.... Come si puo ovviare a questo problema? Io sto usando PicC della HI-TECH

Reply to
NeMeSi
Loading thread data ...

non conosco il tuo compilatore ma la soluzione più ovviam mi pare sia dichiarare questa funzione #inline (direttiva del CCS) oppure copiare il codice della stessa nella ISR (è chiaro che occuperai più rom)

anche se credo il problema sia un altro... il chiamare una function è una jmp_to_address per la ISR per cui è forse un problema di ricorsione... la isr() chiama la display() la quale potrebbe essere interrotta dall'interrupt stesso e poi? prova a disattivare gli interrupt mentre stai eseguendo la display()

-ice-

Reply to
ice

"ice" ha scritto nel messaggio news:45ae70f6$0$32722$ snipped-for-privacy@reader1.news.tin.it...

Gia provato a mettere GIE=0 durante l'esecuzione di display() ma il problema rimane. Ho anche provato a commentare le chiamate alla funzione prima nel main e poi nel interrupt e l'errore non viene piu dato quindi è proprio la presenza della stessa chiamata a darlo.

Reply to
NeMeSi

dovresti, a questo punto, postare il codice incriminato per provare a capire meglio...

-ice-

Reply to
ice

Non conosco l'HI-TECH, ma sembra sia una sua precauzione per impedirti di fare pasticci... Prova a dichiarare un puntatore a funzione (assumendo che non abbia parametri e non restituisca niente, ma puoi modificare di conseguenza)

void (*dispPtr)(void);

quindi assegni

dispPtr=display;

e chiami , sia nel main che nella routine di interrupt

dispPtr();

invece di display();

Buona fortuna Pasu

Reply to
Pasu

"Pasu" ha scritto nel messaggio news:SXxrh.59767$ snipped-for-privacy@newsfe2-win.ntli.net...

Provato ma niente si accorge che puntano alla stessa funzione.. Ho anche provato a mettere il puntatore da una parte e la chiamata dall'altra ma sempre uguale..

Reply to
NeMeSi

"ice" ha scritto nel messaggio news:45ae8a44$0$2036$ snipped-for-privacy@reader2.news.tin.it...

Eccolo:

#include #include #define XTAL_FREQ 4MHZ #include "delay.c" __CONFIG (WDTDIS & XT & PWRTEN & UNPROTECT & LVPDIS & WRTDIS); //WDT disattivato, quarzo XT, PWRT attivato, non protetto

#define BusBanco1 PORTB //Definizione I/O #define BusBanco2 PORTD #define DispCK RA1 #define DispData RA2 #define PagMacchina RA3 #define Inibit RC0 //PORTC Lettore monete #define Cent5 RC1 #define Cent10 RC2 #define Cent20 RC3 #define Cent50 RC4 #define Euro1 RC5 #define Euro2 RC6 #define Accumulatore RC7

//Definizione costanti #define ValCent5 1 #define ValCent10 2 #define ValCent20 4 #define ValCent50 10 #define ValEuro1 20 #define ValEuro2 40 #define SecondiInibit 30

void Display (void); void MioRit(void);

//variabili unsigned int Credito,e,d,CountSec,SecInibit; //char Migliaia,Centinaia,Unita,Decine,TempoBase,TempoMin,Minuti,Secondi,ContaCifre,Dato[35],Cifra; char TempoBase,TempoMin; bit FTempo,FPagato;

main(){

TRISA=0b00100001; // Display, Pagato, LowPW TRISB=0b11111111; //BusBanco1 TRISC=0b11111110; //Lettore Monete TRISD=0b11111111; //BusBanco2 TRISE=0b00000000; //Non usato

//Impostazioni al reset Credito=0; CountSec=61; //Moltiplicatore per arrivare al secondo FTempo=0; FPagato=0; PagMacchina=0; Inibit=0; SecInibit=SecondiInibit;

//Inizio lettura dati TempoBase=BusBanco1; TempoMin=BusBanco2;

OPTION=0b11000101; //settaggio TMR0 GIE=1; //Attivo l'interrupt del timer per la visualizzazione delle cifre T0IE=1;

Credito=TempoBase; MioRit(); Credito=TempoMin; MioRit(); Credito=0;

Inibit=1;

while(1){

if (Cent5==0){ Credito=Credito+TempoBase; Display(); while(Cent5==0){Inibit=0;} Inibit=1; } if (Cent10==0){ Credito=(Credito+(TempoBase*ValCent10)); //Display(); while(Cent10==0){Inibit=0;} Inibit=1; } if (Cent20==0){ Credito=(Credito+(TempoBase*ValCent20)); //Display(); while(Cent20==0){Inibit=0;} Inibit=1; } if (Cent50==0){ Credito=(Credito+(TempoBase*ValCent50)); //Display(); while(Cent50==0){Inibit=0;} Inibit=1; } if (Euro1==0){ Credito=(Credito+(TempoBase*ValEuro1)); //Display(); while(Euro1==0){Inibit=0;} Inibit=1; } if (Euro2==0){ Credito=(Credito+(TempoBase*ValEuro2)); //Display(); while(Euro2==0){Inibit=0;} Inibit=1; }

if ((Credito>=TempoMin)&&(FPagato==0)){ //Al raggiungimento del tempo minimo PagMacchina=1; FTempo=1; FPagato=1; }

if((Credito==0)&&(FPagato==1)){ //Al raggiungimento del fine credito PagMacchina=0; FTempo=0; FPagato=0; Inibit=1; SecInibit=SecondiInibit; } }

}

//***************************** Routine di interrup *********************** void interrupt prv_int(void){ GIE=0;

if (CountSec>0) --CountSec; else if (CountSec==0){ if (FTempo==1){ if (Credito>0){ Credito=Credito-1; Display(); } CountSec=61;

} if ((SecInibit>0)&&(FPagato==1)) --SecInibit; else if ((SecInibit==0)&&(FPagato==1)) {Inibit=0;} }

T0IF=0; GIE=1; }

//**************************** Ritardo vario **************************** void MioRit(void){ e=0;

while (e

Reply to
NeMeSi

Un puntatore di puntatore? :-) Cambiare compilatore? :-)

Più che il codice forse sarebbe più utile avere un'idea del flusso del programma. Perchè ad esempio hai bisogno di chiamare la display() nel main? Se ho capito bene l'interrupt viene chiamato ogni 61esimo di secondo...Non puoi chiamare la display() quando fai il controllo del tempo (con un opportuno flag...), anzichè solo quando c'è credito?

Pasu

P.S. Lo sai che la routine di display la potevi fare con un decimo del codice? ;-) Probabilmente se googli MM5450, PIC, o roba del genere, trovi il codice già scritto!

Reply to
Pasu

ripeto che non conosco il compilatore in questione quello che vedo subito è:

- la display() la dichiari in fondo, dopo il main()... è permesso?

- mi pare ci sia un errore con le graffe nella display(), prova a controllare

-ice-

Reply to
ice

[...]

Uhm...Forse l'ottimizzatore riesce a risolvere l'assegnazione e quindi toglie il puntatore e sostituisce la chiamata diretta. Prova, se puoi, a disabilitare l'ottimizzatore. Altrimenti dovresti cercare di ingannarlo facendo qualche assegnazione farlocca Non so...

dispPtr=0; //durante l'inizializzazione cippolo=0; //variabile culica

nel main e all'interrupt: if (++cippolo) dispPtr=display; if (dispPtr) dispPtr(); //questo if è buona cosa metterlo comunque quando usi puntatori

Ma resto dell'idea che basta chiamare la display() solo nella routine di interrupt. Questi sono soltanto esperimenti, non fare queste cose nel codice finale!! Ci vado poco a lavare la macchina, ma quando ci vado non voglio buttare via i soldi! :-))

Pasu

Reply to
Pasu

"Pasu" ha scritto nel messaggio news:upIrh.40112$ snipped-for-privacy@newsfe2-gui.ntli.net...

Ad esempio?? Consigli?? Io uso un Pic16f877..

Si potrei anche fare cosi, ma l'usare la funzione anche nel main mi è sembrato al momento la soluzione piu comoda..

Azz... a farsi le cose da soli se la prende sempre in quel posto :-) Mi farò un giro, grazie del consiglio..

Reply to
NeMeSi

finale!! Ci vado poco a lavare la macchina, ma quando ci vado non voglio

LOL

Reply to
ice

Guarda, io mi son trovato bene con il loro (Microchip). Più che altro non ho avuto scelta, dato che il modello di PIC che usavo non era supportato dagli altri compilatori.. E poi mi piaceva l'idea che il compilatore fosse fatto da chi veramente conosce la macchina... Ma è solo un'opinione ovviamente, non ho avuto modo di provare altri compilatori. Poi mi serviva poter usare l'in circuit debugger e non so se altri lo supportano. Ma in generale non mi fido di compilatori ad alto livello, se l'applicazione lo permette programmo in assembler!! :-)

Già, lo so bene anch'io :-(

Ciao Pasu

Reply to
Pasu

"Pasu" ha scritto nel messaggio news:_LJrh.68610$ snipped-for-privacy@newsfe7-gui.ntli.net...

Ma quale usi di Microchip?? Ho visto che c'è il C17, C18 e C30 sai quali sono le differenze e quale di questi va bene per i pic serie 16F....?

Reply to
NeMeSi

Ehm, sì, hai ragione, il C18 che uso è solo per i 18F a quanto pare. Penso che nessuno di quelli che hai elencato vada bene per la famiglia 16F. D'altra parte non sono pensati per essere usati con compilatori (--> il codice generato è molto poco efficiente) perchè, a differenza della famiglia

18F, non hanno adeguati modi di indirizzamento. Io ti consiglierei di usare l'assembler. All'inizio può sembrare pesante da imparare e scrivere, ma impazzisci di meno con questi problemi e soprattutto hai un effettivo controllo di quello che la macchina sta facendo.

Pasu

Reply to
Pasu

"Pasu" ha scritto nel messaggio news:71Lrh.68628$ snipped-for-privacy@newsfe7-gui.ntli.net...

Si ma sono abbastanza capace anche in assembly il problema è che mi ci vuole molto piu tempo e poi conto di passare molto presto anche io a 18F e cosi inizio a imparare cosi..

Reply to
NeMeSi

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.