+ Rispondi
Pagina 3 di 8 PrimaPrima 1 2 3 4 5 ... UltimaUltima
Risultati da 21 a 30 su 76
  1. #21

    Iscritto dal
    12/02/2012
    Località
    Genova
    Messaggi
    174
    Quote Originariamente inviato da thermidor Visualizza il messaggio
    Va beh però non è del tutto vero. Un system-tick ha dei valori un po' alti, che so 1ms, ma se tu devi aspettare che il dato sia stabile, o che l' A/D abbia finito la conversione, usi certamente un delay software. Insomma i ritardi di microsecondi si usano eccome.
    Del resto nelle librerie di un po' tutti i compilatori ci sono, mica saranno stati messi a caso?
    Ti devo smentire su tutti i fronti.
    Il tick a 1ms è quello standard anche per me. Proprio con i PIC18 uso anche un tick a 125us (con clock a 4MHz) che mi serve per un'ulteriore UART fatta via FW. E' tanto veloce che ho dovuto modificare l'ISR (quello fornito dal C18,) perché il solo PUSH-POP dei registri se lo mangiava.
    Per quanto riguarda l'A/D quello che si usa non è una routine di delay ma la normale procedura di polling su GO/DONE che dura pochi micro secondi (è funzione del tempo di conversione).
    Nelle librerie sono messe per chi fa lampeggiare dei LED e basta, ma non per chi, come me, che fa dei programmi che giungono a 30000 righe di sorgente.
    Camillo

    Se hai un'amico immaginario, dicono che sei pazzo; invece, se in tanti hanno lo stesso amico immaginario, è religione.
    Anonimo

  2. #22

    Iscritto dal
    03/12/2011
    Messaggi
    56
    Va bene, ma ad esempio a me è successo di dovere effettuare una comunicazione un po' particolare, decodificare una sorta di linea seriale sotto interrupt.<br>Premetto che non è una 485 o 232, ma un protocollo piuttosto strano. Il sistema è composto da molti moduli e la lunghezza della linea è veramente tanta.<br>Sulla linea durante le commutazioni, e a seconda della distanza in cui si trova il modulo, sono presenti dei ringing la cui ampiezza dipende dalla distanza.<br>Insomma sul fronte parte l' interrupt, ma per leggere il dato devi aspettare che il disturbo sia passato, questione di microsecondi, insomma devi usare un delay.<br>Tu mi dirai fai funzionare bene la linea, certo sono d' accordo, ma se la linea non è di tua proprietà ti devi adeguare.<br>Premetto che non sono un softwarista, e i pochi firmware che ho scritto non hanno un grosso impegno della cpu, per cui di mettere dei delay non mi costa granchè. <br>Molto probabilmente tu hai a che fare con situazioni completamente diverse, e certamente userai soluzioni più raffinate e poi mi pare di capire che è il tuo campo, ma io quando arrivo sul posto e mi trovo una situazione che non mi spettavo devo risolvere il problema e subito, e se la soluzione è un delay la uso.
    I hear Jerusalem bells are ringing
    Roman Cavalry choirs are singing

    --Viva la vida-- Coldplay
    http://thermidor.altervista.org

  3. #23

    Iscritto dal
    12/02/2012
    Località
    Genova
    Messaggi
    174
    Abbiamo parlato di routine di delay non di brevi delay all'interno del programma.
    Sicuramente mettere dei delay è la cosa più semplice ma come fai a sapere di quanto tempo metterli se non sai quanto dura il disturbo.
    A me sembra che il problema sia un caso di rimbalzo di linea probabilmente in un sistema con seriale sincrono progettato male.
    Queste cose si risolvono con un'analisi del segnale usando il capture di un timer il cui ingresso è collegato alla linea ed il suo interrupt a fronti alterni vede cosa succede e che durata c'è.
    Camillo

    Se hai un'amico immaginario, dicono che sei pazzo; invece, se in tanti hanno lo stesso amico immaginario, è religione.
    Anonimo

  4. #24

    Iscritto dal
    27/09/2011
    Messaggi
    2,095
    Quote Originariamente inviato da Camillo Visualizza il messaggio
    Uso il C18 della Microchip e non uso librerie mi faccio le cose da solo.
    Le routine di delay sono la più grossa stro..... mai proposta non vanno assolutamente usate, sospendono la normale esecuzione, questo non deve mai avvenire.

    Un buon programma deve avere un system-tick e tutto deve basarsi su di esso.
    sono d'accordissimo
    quando scrivo un programma senza metterci le routine di delay mi sento realizzato

  5. #25

    Iscritto dal
    03/12/2011
    Messaggi
    56
    Quote Originariamente inviato da Camillo Visualizza il messaggio
    Abbiamo parlato di routine di delay non di brevi delay all'interno del programma.
    Sicuramente mettere dei delay è la cosa più semplice ma come fai a sapere di quanto tempo metterli se non sai quanto dura il disturbo.
    A me sembra che il problema sia un caso di rimbalzo di linea probabilmente in un sistema con seriale sincrono progettato male.
    Queste cose si risolvono con un'analisi del segnale usando il capture di un timer il cui ingresso è collegato alla linea ed il suo interrupt a fronti alterni vede cosa succede e che durata c'è.
    Allora siccome non vorrei che si trasformasse il thread in una competizione a chi ne sa di più, premetto:
    non sono un softwarista e mai e poi mai avrei la presunzione di insegnare il mestiere della programmazione a chi ne sa più di me, in questo caso tu.
    Nel caso avessi dato questa impressione mi scuso.
    Come hardwarista mi capita, raramente per fortuna dato che sono un analogico, di dovere usare un microcontrollore ma sempre e solo per fare poche cose, per cui non ho la necessità di sfruttare tutte le potenzialità dell' oggetto in questione, quindi inserire dei ritardi personalizzati quando serve non credo sia una eresia, insomma non vado a installare un cooperative operating system per leggere quattro ingressi e comandare magari due relè.
    Per quanto riguarda l' impianto in questione, non è un sistema seriale sincrono e non è progettato male, i dettagli di come funziona non li posso mettere su questo forum dato che riguarda il mio lavoro. Ma il disturbo l' ho misurato e anche calcolata l' entità secondo la posizione in cui viene inserito il mio oggetto. E' un disturbo che varia in ampiezza, frequenza e smorzamento secondo la lunghezza del cavo e dei carichi che vede, per cui trovato lo smorzamento più lungo inserisci un delay tale da compensare.
    Però hai ragione si tratta di un breve delay personalizzato, non di certo una routine di delay.
    I hear Jerusalem bells are ringing
    Roman Cavalry choirs are singing

    --Viva la vida-- Coldplay
    http://thermidor.altervista.org

  6. #26
    Ex- Ser Fabrium
    Iscritto dal
    12/10/2011
    Messaggi
    269
    Ragazzi sappiate che anche se non rispondo attivamente leggo attentamente tutto ciò che scrivete e che posssa essere spunto per imparare .. capisco tu cosa dici Camillo, e certamente hai ragione, questa è la terza o forse quarta volta che scrivo un programma per pic, quindi sto ancora imparando tutti i meccanismi e pian piano miglioro l'efficienza, ad ora ho realizzato un solo programma che ha un system tick generato senza routines di delay, è tutt'altra cosa, però il programma in questione dovrebbe essere semplice e poco impegnativo per la cpu perciò mi permetto di fare in questo modo.. direi che ci siamo quasi, lo posto tra poco

  7. #27
    Ex- Ser Fabrium
    Iscritto dal
    12/10/2011
    Messaggi
    269

    Sorgente

    Ragazzi cari il sorgente è stato partorito e testato con PIC18 Simulator , sembra andare tutto bene, il programma è molto commentato in previsione di presentarlo alla commissione che altrimenti non capirà un emerito cacio :P

    Non fate caso agli eeprom_write commentati, erano lì per dei test col simulatore, non li ho tolti ancora

    Ogni commento - replica - bestemmia sul codice è ben accetta , sono solo un piccolo programmatore in gavetta :P

    codice:
    #define _LEGACY_HEADERS 
    #include<htc.h>
    #include "delay.c"
    #define XTAL_FREQ 4MHZ  //Quarzo a 4MHz
    #define SOURCE_IDLE1 0b00000001 //Valori per ADCON0 in modo da accendere il modulo
                                  //e portarlo in 'ascolto' dell'ingresso analogico AN0
    #define SOURCE_IDLE2 0b00000101 //Valori per ADCON0 in modo da accendere il modulo
                                  //e portarlo in 'ascolto' dell'ingresso analogico AN1
    #define ROTAZIONI 5 //Quante volte effettuare la rotazione completa del motore ogni ciclo di rotazione
    #define SOGLIA 1 // Soglia luminosa oltre la quale entra in azione il sistema di correzione dell'inclinazione
    #define REFRESH 50 //Ms (1-65535) tra un refresh e l'altro delle condizioni del sistema
    #define T_BUIO 3 //Durata buio
    #define SOGLIA_BUIO 50 //Soglia al di sotto della quale il segnale luminoso è considerato un ambiente buio
    
    void lettura (int n_sensore, int *tensione);
    void rotazione (int verso, int velocita);
    void asp (int sec);
    
    
    
    main(void)
    {
        TRISA=0b00000011;   //Bits 0 e 1 come ingressi (analogici AN0 e AN1), il resto uscite
        TRISB=0b00000011; //Bits 0 e 1 come ingressi (finecorsa), il resto uscite
        TRISC=0b00000000; //Inutilizzate, tutte uscite    
        PORTA=0; //Azzeramento uscite per evitare disturbi    
        
        ADCON1=0b00001101;  //Valori per ADCON1 in modo da settare le porte RA0 e RA1 come ingressi analogici AN0 e AN1
        ADCON2=0b10010100; //Valori per ADCON2 in modo da settare 'giustifica a destra dei Bits',
                          //'Tempo di acquisizione' 16 Tad = 64us e 'Clock di conversione' Fosc/16 = 4us
        
        int tensione0=0, tensione1=0, ddp=0, buio=0;
        
        //eeprom_write(0, 0);
        //eeprom_write(1, 0);
        
        while(1)
        {        
            do
            {
                lettura(0, &tensione0);
                lettura(1, &tensione1);
                ddp=tensione0-tensione1;
                
                if((ddp>SOGLIA)&&(RB0==0))
                {
                    rotazione(0,(int)ddp/4);
                    buio=0;
                }
                if((ddp<SOGLIA*(-1))&&(RB1==0))
                {
                    rotazione(1,(int)ddp/4);
                    buio=0;
                }
                //eeprom_write(5, ddp);
                //eeprom_write(6, buio);
                if((ddp<=SOGLIA)&&(ddp>=SOGLIA*(-1))&&(((tensione0+tensione1)/2)<=SOGLIA_BUIO)) //Controlla se è buio
                {
                    buio++;
                }
                
            }while(!((ddp<=SOGLIA)&&(ddp>=SOGLIA*(-1)))); //Effettua le rotazioni fin quando la ddp è compresa nella soglia
            
            asp(REFRESH);
            
            if(buio>=T_BUIO)
            {
                buio=0;
                while(RB0==0)
                {
                    PORTA=0b10000000;
                    rotazione(1,100);
                }
            }
        }
    }        
            
        
        void rotazione (int verso, int velocita)
        {
            int step[4]={4,8,16,32}, j;
            
            for(int i=0;i<ROTAZIONI;i++) //ciclo per le rotazioni
            {
                switch(verso)
                {
                    case 0: //rotazione oraria
                    for(j=0;j<4;j++)
                    {
                        PORTA=step[j];
                        DelayUs(256-velocita);
                        DelayUs(256-velocita);                    
                    }
                    break;
                    
                    case 1: //rotazione anti-oraria
                    for(j=3;j>=0;j--)
                    {
                        PORTA=step[j];
                        DelayUs(256-velocita);
                        DelayUs(256-velocita);                    
                    }
                    break;                
                }
            }
            PORTA=0;
        }
                    
    
        void lettura (int n_sensore, int *tensione)
        {
            switch(n_sensore)
            {
                case 0: //rilevazione e conversione sorgente AN0
                ADCON0=SOURCE_IDLE1;
                DelayUs(10);
                GO=1;
                while(GO) //attesa conversione
                continue;
                
                //eeprom_write(0, ADRESH);
                //eeprom_write(1, ADRESL);            
                
                *tensione=(ADRESH<<8)+ADRESL; //unione registri
                break;
                
                
                case 1: //rilevazione e conversione sorgente AN1
                ADCON0=SOURCE_IDLE2;
                DelayUs(10);
                GO=1;
                while(GO) //attesa conversione
                continue;
                
                //eeprom_write(2, ADRESH);
                //eeprom_write(3, ADRESL);            
                
                *tensione=(ADRESH<<8)+ADRESL; //unione registri
                break;
            }
            
        }
        
        void asp (int sec)
        {
            int i;
            for(i=0;i<sec;i++)
            {
                DelayMs(1);
            }
        }
    EDIT: al link si capisce un po meglio http://codepad.org/yibIsDnw

  8. #28

    Iscritto dal
    12/02/2012
    Località
    Genova
    Messaggi
    174
    Dovresti mettere dei commenti in testa ad ogni function per descriovere quello che fa.

    codice:
                ADCON0=SOURCE_IDLE2;
                DelayUs(10);            
                GO=1;
                while(GO) //attesa conversione
                continue;
    
    Lascia solo il puntovirgola il continue è un'errore.
    Ti fa uscire senza terminare la conversione per poi rientrare e farla ripartire.
    
    Non vedo neppure la necessità del delay a meno che l'impedenza della
     sorgente analogica sia tanto alta da richiederlo.
    
    Nel commento della definizione di SOURCE_IDLEx dici che lo accendi, vero,
     ma dove lo spegni? e se non lo spegni è inutile riaccenderlo, dopo la prima
     volta lo è per sempre.
    Camillo

    Se hai un'amico immaginario, dicono che sei pazzo; invece, se in tanti hanno lo stesso amico immaginario, è religione.
    Anonimo

  9. #29
    Ex- Ser Fabrium
    Iscritto dal
    12/10/2011
    Messaggi
    269
    Grazie Camillo per aver risposto
    1. Giusto, per le funzioni avevo dimenticato di commentare, aggiungerò a breve..
    2. Quindi tu dici di lasciare unicamente while(GO); ?
    3. Il delay l'ho messo giusto perchè nel datasheet diceva che bisogna attendere un attimo che si stabilizzi il segnale sugli ingressi, se è come dici tu lo ometto.
    4. si, in effetti dico che lo accendo, ma dico anche che seleziono l'ingresso ANx e quindi perciò nel codice continuo a richiamarlo in lettura, dire che lo accendo era puramente informativo , comunque lo tolgo e metto solo della selezione.. (che poi potevo farla anche controllando i soli bits direttamente interessati, ma lo trovo più comodo così )

    Grazie

    Ora sono alle prese con un problemino.. non prendevo il pickit2 (clone) da un po', ed ora, riprendendolo, e ricordando come si usa (nulla di che), non riesco a programmare il pic, mi da sempre un errore in un indirizzo Xxxxxx della Program Memory, pensavo fosse questo hex, ma provando con altri che ho già usato in altri pic18 uguali mi fa lo stesso problema, domani provo a cambiare pic, ma non penso sia lui il problema.. secondo voi c'è qualche impostazione che mi sfugge??

    Ciao Ragà!

  10. #30

    Iscritto dal
    12/02/2012
    Località
    Genova
    Messaggi
    174
    Quote Originariamente inviato da R3cycl0r Visualizza il messaggio
    Grazie Camillo per aver risposto
    1. Giusto, per le funzioni avevo dimenticato di commentare, aggiungerò a breve..
    2. Quindi tu dici di lasciare unicamente while(GO); ?
    3. Il delay l'ho messo giusto perchè nel datasheet diceva che bisogna attendere un attimo che si stabilizzi il segnale sugli ingressi, se è come dici tu lo ometto.
    4. si, in effetti dico che lo accendo, ma dico anche che seleziono l'ingresso ANx e quindi perciò nel codice continuo a richiamarlo in lettura, dire che lo accendo era puramente informativo , comunque lo tolgo e metto solo della selezione.. (che poi potevo farla anche controllando i soli bits direttamente interessati, ma lo trovo più comodo così )

    Grazie

    Ora sono alle prese con un problemino.. non prendevo il pickit2 (clone) da un po', ed ora, riprendendolo, e ricordando come si usa (nulla di che), non riesco a programmare il pic, mi da sempre un errore in un indirizzo Xxxxxx della Program Memory, pensavo fosse questo hex, ma provando con altri che ho già usato in altri pic18 uguali mi fa lo stesso problema, domani provo a cambiare pic, ma non penso sia lui il problema.. secondo voi c'è qualche impostazione che mi sfugge??

    Ciao Ragà!
    Tanto per cominciare mi cospargo il capo di cenere, ho scritto una cavolata (nell'ambiente vengono chiamate "camillate").
    Il "continue;" di cui sopra va benissimo, questa è un'ennesima dimostrazione di come lo stile di scrittura influenzi il debug mentale di un programma.
    Passando a rispondere:
    1) Niente da dire, se non che i commenti sono sempre troppo pochi. Ti consiglierei anche di mettere in rilievo i confini del main e delle funzioni.
    2) Io avrei scritto:
    codice:
        while(DONE) ;    // Attende il termine della conversione.
    o per evidenziare maggiormente 
        while(DONE){ ; }    // Attende il termine della conversione.
    E' per questo che il mio debug mentale ha fallito.
    3) Dipende dall'impedenza della sorgente. Un piccolo delay non fa di sicuro male.
    Non so come gli estensori della libreria se la siano cavata con un tempo di 10 micro secondi visto che con un clock di 4MHz il tempo di ciclo e di un micro secondo. Una pura chiamata/ritorno impiega 4us e qui c'è da considerare il passaggio e poi la gestione del parametro.
    4) Se ti è più congeniale non cambiarlo. Io trovo più chiaro l'agire direttamente sui soli bit di selezione.

    Prego.

    Qui non ti posso essere d'aiuto non uso il pickit.
    Camillo

    Se hai un'amico immaginario, dicono che sei pazzo; invece, se in tanti hanno lo stesso amico immaginario, è religione.
    Anonimo


 
+ Rispondi
Pagina 3 di 8 PrimaPrima 1 2 3 4 5 ... UltimaUltima

Autorizzazioni

  • Non puoi iniziare nuove discussioni
  • Non puoi rispondere alle discussioni
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
Powered by vBulletin™ Version 4.1.5
Copyright © 2019 vBulletin Solutions, Inc. All rights reserved
SEO by vBSEO ©2011, Crawlability, Inc.
Fuso orario: UTC +1, sono le 06:18.