Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Registro CMCON PIC16F628

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[21] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 19 set 2014, 9:57

Puoi spiegarmi come mai eseguo entrambe le istruzioni a prescindere dal valore di tempo?

Ti propongo un codice che ho provato sul simulatore funziona bene , sul circuito(breadboard) funziona abbastanza male,cioè , mentre sul simulatore mi basta attivare le porte di un sensore ed ottengo tempi precisi( come da codice) sulla breadboard, se collego FRONTinhibitedPort a +5volt non ottengo un' onda precisa, bensì forme d' onda che assomigliano ad un disturbo, se invece tengo il filo in mano, ottengo una forma d' onda precisa, come i tempi da me impostati, solo invertita, cioè, 1,5 ms OFF e 18,5 ON.. ?%

ecco il codice :

Codice: Seleziona tutto
// definisco i fuses del PIC
#define _XTAL_FREQ 4000000
#pragma config FOSC=INTOSCIO
#pragma config CP=0
#pragma config CPD=0
#pragma config PWRTE=0
#pragma config WDTE=0
#pragma config MCLRE=1
#pragma config LVP=0
#pragma config BOREN=0


// importo le librerie
#include<stdio.h>
#include <htc.h>
#include <xc.h>
#include <PIC.h>
#define FRONTinhibitedPort RA0 // Dal sensore frontale
#define REARinhibitedPort RA1 // Dal sensore dietro

// PORTE DI INGRESSO DEL SEGNALE
#define MOTORE1INpos RB4
#define MOTORE2INpos RB5
#define MOTORE3INpos RB6
#define MOTORE4INpos RB7

// PORTE DI USCITA DEL SEGNALE
#define MOTORE1OUTpos RB0
#define MOTORE2OUTpos RB1
#define MOTORE3OUTpos RB2
#define MOTORE4OUTpos RB3



// prototipi delle funzioni
void start();

// variabili globali


unsigned int tempo=0;

void main(void){
   start();// chiamo la funzione di inizializzazione

}

void start(){
// imposto le porte come input o output
INTCON=0b10100100;
// Configuro le porte A come uscite
CMCON=0x07;
OPTION_REG=0b00000000; //Prescaler =1/2


TRISA=0b00001111; //Tutte le porte sono input
TRISB=0b11110000;// solo le porte RB7>RB4 sono input( per sfruttare gli interrupt)
// imposto le porte come livello basso
PORTA=0;
PORTB=0;
T0IF=0;
RBIF=0;
// imposto il valore di partenza del TMR0
TMR0=206;



while(1){

     if (FRONTinhibitedPort || REARinhibitedPort  ){
         if (FRONTinhibitedPort){
         while(tempo<150){
             MOTORE1OUTpos=1;
             MOTORE2OUTpos=1;
           
         }
         while(tempo>150 && tempo<1850){
             MOTORE1OUTpos=0;
             MOTORE2OUTpos=0;
         
         }


         }
//inserire un while che controlla le varie porte
     //ottimizzare con il switch case
//i sensori comunicano qualcosa?

     }else{




     MOTORE1OUTpos=MOTORE1INpos;
     MOTORE2OUTpos=MOTORE2INpos;
   
     tempo=0;
}

}
}



void interrupt ISR(void){
    if (RBIF){
        RBIF=0;
       
    }

     if (T0IF) // l' interrupt è stato causato dall' overflow del timer0
{ //l'interrupt è generato ogni 100 microsecondi

        T0IF=0;
        TMR0=206;
        if (tempo>2000)
            tempo=0;
        tempo++;

}
  // fine interrupt service routine
}


tu quali altre soluzioni proponi? di usare gli interrupt della porta B?
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[22] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 19 set 2014, 10:06

Davide90 ha scritto:Puoi spiegarmi come mai eseguo entrambe le istruzioni a prescindere dal valore di tempo?
... la risposta te l'ho già data.
Ti ho riportato anche il pezzo di codice sul quale concentrare la considerazione.
Supponi che la variabile tempo abbia valore pari a zero (o uno, se preferisci, tanto è la stessa cosa) e con questo presupposto "esegui" virtualmente riga per riga il codice che ti ho inserito nel Post [20] tenendo presente che lo stato del sensore ti consente di entrare ...
Poi fai sapere ( ... a proposito, nella teoria del "C", riguarda la sintassi del "do/while").

Saluti

p.s.
onde evitare d'indurre possibile confusione negli utenti che seguono il thread aggiungo che quanto riportato in questo Post e nel [20] fa riferimento al codice che l'OP ha inserito nel Post [15].
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[23] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 19 set 2014, 12:03

Davide90 ha scritto:sul circuito(breadboard) funziona abbastanza male
... o funziona o non funziona.
Davide90 ha scritto:sulla breadboard, se collego FRONTinhibitedPort a +5volt non ottengo un' onda precisa, bensì forme d' onda che assomigliano ad un disturbo, se invece tengo il filo in mano, ottengo una forma d' onda precisa
... controlla i collegamenti e l'interfacciamento tra sensore e i pin(s) d'ingresso del microcontrollore, controlla la configurazione delle porte ( ... guarda il datasheet).
Se "ritieni" il caso puoi anche riportare, fedelmente, lo schema del circuito e ... sistema l'indentazione.
Infatti, per quanto concerne il software, e sia chiaro che è una tua scelta del tutto rispettabile, ognuno "scrive" come gli pare ma non mi sembra coerente chiedere agli altri di guardare qualcosa che, potendo essere molto più leggibile, faciliterebbe la consultazione.
Sono solo quattro righe di codice ma bisogna guardarle sempre più d'una volta, per non equivocare, o riordinarsele dopo averle copiate; questo, di per sé, non è assolutamente una difficoltà ma da parte tua, un pochino più di attenzione se cerchi collaborazione: basta poco.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[24] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 20 set 2014, 8:32

Ho rivisto la teoria del c, come da te suggerito nel post 22, e non riesco proprio a capire per quale motivo le istruzioni debbano essere eseguite indipendente dal valore di tempo, il ciclo do while infatti, esegue solamente una volta tutte l'istruzioni, fino a che la condizione è vera, essendo che la verifica del valore sentinella è posto come ultima istruzione, le istruzioni vengono eseguite tutte almeno una volta, poi nel mio caso specifico, dato che era presente, come valore sentinella, una istruzione "Equal to" i due blocchi sarebbero stati eseguiti solamente 2 volte. Mi perdo qualcosa?

Purtroppo per l'altro post bisogna attendere la riparazione del PC, ha appena smesso di funzionare, in giornata lo ripristino!!

Grazie comunque fino ad ora!
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[25] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 20 set 2014, 9:59

EDIT del post sopra( che non mi permette più di modificare):
Mi sfuggiva che la variabile tempo viene resettata :)
Quindi il tuo ragionamento fila, come sempre!
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[26] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 20 set 2014, 12:48

Caro Foto UtenteDavide90, rileggi con attenzione quanto ho scritto nel Post [20] e [22].
Di per sé, non ha importanza l'azione di azzeramento compiuta sulla variabile "tempo".
Riscrivo: qualunque valore assuma la variabile "tempo" (eccetto i due considerati, e cioè 15 e 200, vedi appunto Post [20]), le istruzioni contenute all'interno del "do/while" vengono sempre eseguite, ad ogni scansione sequenziale del programma, almeno una volta.
Questo perché ?
Perché a prescindere dallo stato dell'esito (vero o falso) del test posto a governo del loop "do/while", il codice in esso contenuto viene sempre eseguito prima, appunto, di verificare lo stato dell'esito stesso.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[27] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 20 set 2014, 13:59

Hai ragione, la variabile tempo non c'entra nulla.
Intanto che ripristino il PC, potresti indicarmi con precisione come indentare bene il codice?
Ci ho provato, secondo me ne perde un po di leggibilità( è più scomodo secondo me) :D

Codice: Seleziona tutto
// definisco i fuses del PIC
#define _XTAL_FREQ 4000000
#pragma config FOSC=INTOSCIO
#pragma config CP=1
#pragma config CPD=1
#pragma config PWRTE=0
#pragma config WDTE=0
#pragma config MCLRE=1
#pragma config LVP=0
#pragma config BOREN=0


// importo le librerie
#include<stdio.h>
#include <htc.h>
#include <xc.h>
#include <PIC.h>
#define FRONTinhibitedPort RA0 // Dal sensore frontale
#define REARinhibitedPort RA1 // Dal sensore dietro

// PORTE DI INGRESSO DEL SEGNALE
#define MOTORE1INpos RB4
#define MOTORE2INpos RB5
#define MOTORE3INpos RB6
#define MOTORE4INpos RB7

// PORTE DI USCITA DEL SEGNALE
#define MOTORE1OUTpos RB0
#define MOTORE2OUTpos RB1
#define MOTORE3OUTpos RB2
#define MOTORE4OUTpos RB3



// prototipi delle funzioni
void start();


// variabili globali
unsigned int tempo=0;

void main(void){

    start();// chiamo la funzione di inizializzazione

}

void start(){
    // imposto le porte come input o output
    INTCON=0b10100100;
    // Configuro le porte A come uscite
    CMCON=0x07;
    OPTION_REG=0b00000000; //Prescaler =1/2
    TRISA=0b00001111; //Tutte le porte sono input
    TRISB=0b11110000;// solo le porte RB7>RB4 sono input( per sfruttare gli interrupt)
    // imposto le porte come livello basso
    PORTA=0;
    PORTB=0;
    T0IF=0;
    RBIF=0;
    // imposto il valore di partenza del TMR0
    TMR0=206;
    while(1){
             if (FRONTinhibitedPort || REARinhibitedPort  ){
                                                             if (FRONTinhibitedPort){
                                                                                        while(tempo<150){
                                                                                                         MOTORE1OUTpos=1;
                                                                                                         MOTORE2OUTpos=1;
                                                                                                         MOTORE3OUTpos=MOTORE3INpos;
                                                                                                         MOTORE4OUTpos=MOTORE4INpos;
                                                                                         }
                                                                                         while(tempo>150 && tempo<1850){
                                                                                                                          MOTORE1OUTpos=0;
                                                                                                                          MOTORE2OUTpos=0;
                                                                                                                          MOTORE3OUTpos=MOTORE3INpos;
                                                                                                                          MOTORE4OUTpos=MOTORE4INpos;
                                                                                         }


                                                              }

            }else{
                    MOTORE1OUTpos=MOTORE1INpos;
                    MOTORE2OUTpos=MOTORE2INpos;
                    MOTORE3OUTpos=MOTORE3INpos;
                    MOTORE4OUTpos=MOTORE4INpos;
                    tempo=0;
            }

     }
}



void interrupt ISR(void){
                            if (RBIF){
                            RBIF=0;
                            }

                            if (T0IF) // l' interrupt è stato causato dall' overflow del timer0
                            { //l'interrupt è generato ogni 100 microsecondi
                            /*
                               T0IF=0;
                               TMR0=206;
                                    if (impulsoStick==2000)
                                        impulsoStick=1000;
                               impulsoStick++;
                            */
                               T0IF=0;
                               TMR0=206;
                               if (tempo>2000)
                               tempo=0;
                               tempo++;
                              }
  // fine interrupt service routine
}


dimmi tu come correggere!
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[28] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 20 set 2014, 15:29

A prescindere dal codice qui contenuto, quello che qui ti riporto, sulla scorta del tuo scritto, è ciò che io interpreto come "buona" indentazione.
Ognuno poi ha il suo stile (non si può scrivere che uno sia migliore di un altro) ma una "stesura" ordinata e coerente si vede subito e offre immediata leggibilità.
Il mio comunque non era assolutamente un giudizio ma una osservazione di merito.

Il tuo codice, da me indentato:
Codice: Seleziona tutto
// definisco i fuses del PIC
#define _XTAL_FREQ 4000000
#pragma config FOSC=INTOSCIO
#pragma config CP=0
#pragma config CPD=0
#pragma config PWRTE=0
#pragma config WDTE=0
#pragma config MCLRE=1
#pragma config LVP=0
#pragma config BOREN=0


// importo le librerie
#include<stdio.h>
#include <htc.h>
#include <xc.h>
#include <PIC.h>
#define FRONTinhibitedPort RA3 // Dal sensore frontale
#define REARinhibitedPort RA2 // Dal sensore dietro

// PORTE DI INGRESSO DEL SEGNALE
#define MOTORE1INpos RB4
#define MOTORE2INpos RB5
#define MOTORE3INpos RB6
#define MOTORE4INpos RB7

// PORTE DI USCITA DEL SEGNALE
#define MOTORE1OUTpos RB0
#define MOTORE2OUTpos RB1
#define MOTORE3OUTpos RB2
#define MOTORE4OUTpos RB3

// prototipi delle funzioni
void start();

// variabili globali
unsigned int tempo=0;

void main(void)
{
   start();// chiamo la funzione di inizializzazione
}

void start()
{
    // imposto le porte come input o output
    INTCON=0b10100001;
    // Configuro le porte A come uscite
    CMCON=0x07;
    OPTION_REG=0b00000000; //Prescaler =1/2

    TRISA=0b00001111; //Tutte le porte sono input
    TRISB=0b11110000;// solo le porte RB7>RB4 sono input( per sfruttare gli interrupt)
    // imposto le porte come livello basso
    PORTA=0;
    PORTB=0;
    T0IF=0;
    // imposto il valore di partenza del TMR0
    TMR0=206;

    while(1)
    {
        if (FRONTinhibitedPort || REARinhibitedPort  )
        {
            //inserire un while che controlla le varie porte
            //ottimizzare con il switch case
            //i sensori comunicano qualcosa?

            while(FRONTinhibitedPort)
            {
                // dovrebbe simulare il segnale ppm
                do
                {
                    MOTORE1OUTpos=1;
                    MOTORE2OUTpos=1;
                }
                while(tempo==15);

                do
                {
                    MOTORE1OUTpos=0;
                    MOTORE2OUTpos=0;
                }
                while(tempo==200);
            }

            while(REARinhibitedPort)
            {
                // dovrebbe simulare il segnale ppm
                do
                {
                    MOTORE3OUTpos=1;
                    MOTORE4OUTpos=1;
                }
                while(tempo==15);
                // __delay_us(1500);

                do
                {
                    MOTORE3OUTpos=0;
                    MOTORE4OUTpos=0;
                }
                while(tempo==200);
            }
        }
        else
        {
            MOTORE1OUTpos=MOTORE1INpos;
            MOTORE2OUTpos=MOTORE2INpos;
            tempo=0;
        }
    }
}



void interrupt ISR(void)
{
    if (T0IF) // l' interrupt è stato causato dall' overflow del timer0
    { //l'interrupt è generato ogni 100 microsecondi
        /*
        T0IF=0;
        TMR0=206;
        if (impulsoStick==2000)
            impulsoStick=1000;
        impulsoStick++;
        */
        T0IF=0;
        TMR0=206;
        if (tempo>=200)
            tempo=0;
        tempo++;
    }
    // fine interrupt service routine
}


Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[29] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 28 set 2014, 9:23

Ciao, finalmente ho trovato un po di tempo per dedicarmi nuovamente al progetto !

Il attualmente il codice che mi da problemi è quello relativo alla generazione dei segnali, guardando il datasheet del mio ESC ho visto che vuole una frequenza di 403 Hz , quindi un periodo di 2,48 ms.
Ho impostato il timer2 per ottenere un overflow ogni 10us ( il timer0 mi servirà poi per fare altri calcoli)
ma il periodo,misurato con l' oscilloscopio, è di 3,08ms.
dove sbaglio?
Il quarzo è diventato a 16 MHz
il codice è questo

Codice: Seleziona tutto
void start();
// variabili globali
unsigned int tempo=100;
unsigned int impulsoStick=100;

unsigned int tempoon=0;
unsigned int tempooff=0;
void main(void){

    start();// chiamo la funzione di inizializzazione

}

void start(){
    // imposto le porte come input o output
    INTCON=0b10101101;
    T2CON=0b0000100;// Timer2
    PR2=40;//Timer2
    PIE1=0b00000010; // Abilito il flag Interrupt TMR2IE
    // Configuro le porte A come uscite
    CMCON=0x07;
    OPTION_REG=0b00000000; //Prescaler =1/2
    TRISA=0b00001111; //Tutte le porte sono input
    TRISB=0b11110000;// solo le porte RB7>RB4 sono input( per sfruttare gli interrupt)
    // imposto le porte come livello basso
    PORTA=0;
    PORTB=0;
   
    // imposto il valore di partenza del TMR0
    TMR0=236;

    while(1){
       
       tempoon=170;
        tempooff=(248-tempoon)+100; //qualche sensore sta comunicando di inibire una direzione
           
                    while(tempo<tempoon){
                        MOTORE1OUT=1;
                        MOTORE2OUT=1;
                 
                     }
                   
                     while(tempooff>tempo && tempo>tempoon) {
                        MOTORE1OUT=0;
                        MOTORE2OUT=0;
                 
                     }

           
         
     }
}




void interrupt ISR(void){
    if(TMR2IF){
        TMR2IF=0;
         T0IF=0;
         PR2=40;
    if (tempo>248)
          tempo=100;
    tempo++;
    }
    if (RBIF){
        RBIF=0;
   
    }
    if (T0IF) // l' interrupt è stato causato dall' overflow del timer0
    { //l'interrupt è generato ogni 10 microsecondi
     
      T0IF=0;
      TMR0=236;
      if (impulsoStick>248)
      impulsoStick=100;
      impulsoStick++;




     /*
   
      */
    }
  // fine interrupt service routine
}
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[30] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 28 set 2014, 22:48

Foto UtenteDavide90, sei certo di questi tempi, ovvero 3,08 ms rispetto a 2,48 ms ?
Poi, inoltre ma a prescindere, qual è la durata dello stato ON e quella dello stato OFF ?

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

PrecedenteProssimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 5 ospiti