Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Registro CMCON PIC16F628

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[11] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 18 set 2014, 11:46

Sicuramente rivedrò l'indentazione, proprio perché il primo a confondersi sono stato proprio io per via di quella riga.

In merito al discorso del timer2 anche io credo che l' efficienza dei due si equivalga, però, leggendo un po su internet ho visto che dicono che in genere il timer2 è più preciso. Ho comunque provato , ed il grafico proposto dall' oscilloscopio è identico in entrambi i casi.

Non riesco a capire, il timer dovrebbe essere impostato bene
FOSC=4 MHz
PS = 1:2
Preload = 206.
quindi un Interrupt ogni 100 us.

i segnali generati invece sono nell' ordine degli 8 us.

?%
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[12] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 18 set 2014, 12:08

Sempre facendo riferimento al codice del Post [7], ti suggerirei di:
i) adottare le parentesi "graffe" come ti ho indicato,
ii) in difetto di (i), elimina gli statement " if " che precedono i due loop "do/while" e sostituisci questi con i loop "while",
iii) quelle comparazioni eseguite per "corrispondenza" sostituiscile col test per "maggiore o uguale".

Davide90 ha scritto:In merito al discorso del timer2 anche io credo che l' efficienza dei due si equivalga, però, leggendo un po su internet ho visto che dicono che in genere il timer2 è più preciso.
... se ne scrivono di cose ... alcune corrette altre no.
Riscrivo: dipende da come utilizzi la risorsa, l'accuratezza del timer è un'altra questione.

Per ora questo, poi magari qualcos'altro.

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

0
voti

[13] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 18 set 2014, 13:23

Ho fatto le sostituzioni che mi hai indicato:

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>=150);

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

         
     }

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

}else{

     MOTORE1OUTpos=MOTORE1INpos;
   MOTORE2OUTpos=MOTORE2INpos;

}

}
}



void interrupt ISR(void){
// per il momento non è usato.forse non serve, bisogna verificare l' overing

     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
}


WALTERmwp ha scritto:i) adottare le parentesi "graffe" come ti ho indicato,

Fatto, non cambia nulla, molto probabilmente è valido il discorso fatto prima

WALTERmwp ha scritto:ii) in difetto di (i), elimina gli statement " if " che precedono i due loop "do/while" e sostituisci questi con i loop "while",


fatto, il segnale è lievemente più pulito

WALTERmwp ha scritto:iii) quelle comparazioni eseguite per "corrispondenza" sostituiscile col test per "maggiore o uguale".


Ti ho riportato il codice, forse ho sbagliato qualcosa, ma se cambio questo punto come suggerisci tu, il PIC si blocca.
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

1
voti

[14] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 18 set 2014, 14:51

Intanto direi di "stabilizzare" il codice di riferimento.
Conserva l'ultimo, quello del Post [13], e modifica questo, se sei d'accordo, in funzione delle osservazioni presenti e future.
La comparazione per " >= " adottala nella ISR.
In questa mi pare vi si trovi lo stretto necessario per cui nulla da evidenziare.
Quello che proprio non mi piace sono quei loop all'interno del main; ma sopratutto la comparazione con la variabile "tempo" non è coordinata.
Quindi, se non interpreto in modo errato (ma non lo escludere), al di là dello stile, che comunque ha la sua importanza, quando uno dei sensori (fronte o retro) ti consente di accedere allo " if " ...
Codice: Seleziona tutto
if (FRONTinhibitedPort || REARinhibitedPort  )
... non sei allineato sulla griglia della funzione conta-tempo e definita tramite la variabile "tempo".
Ovvero, quando passi ad eseguire il test specifico sul sensore ...
Codice: Seleziona tutto
while(FRONTinhibitedPort)
o
Codice: Seleziona tutto
while(REARinhibitedPort)
... "tempo" può avere un valore qualsiasi compreso tra 0 e 2000.
Il test nel main ed il conteggio (all'interno di ISR) sono dissociati; non c'è nessuna relazione tra l'intervento di un sensore ed il valore che la variabile "tempo" ha nel medesimo istante.

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

0
voti

[15] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 18 set 2014, 16:03

Ho aggiunto
Codice: Seleziona tutto
tempo=0

in
Codice: Seleziona tutto
}else{

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

in questo modo dovrei essere allineato.

Ho anche aggiornato i valori delle variabili, ho diviso tutto per 10, perché se l' interrupt si verifica ogni 100us , io ho bisogno di generare un segnale di 1,5 ms. quindi a variabile tempo dovrà assumere il valore 15.
Purtroppo il risultato non cambia!
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
}
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[16] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 18 set 2014, 16:39

Foto UtenteDavide90, hai tenuto in considerazione quanto prima ho riportato:
WALTERmwp ha scritto:Il test nel main ed il conteggio (all'interno di ISR) sono dissociati; non c'è nessuna relazione tra l'intervento di un sensore ed il valore che la variabile "tempo" ha nel medesimo istante.
... ?
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8986
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[17] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 18 set 2014, 17:01

forse non ho capito cosa intendi, ho solo inserito una inizializzazione della variabile tempo nel caso in cui nessun sensore comunichi nulla al PIC. Così facendo, quando si verifica che uno dei sensori inizia a trasmettere qualcosa al PIC, la variabile è correttamente inizializzata a zero.
La variabile è comunque visibile da tutte le funzioni.
Molto probabilmente tu intendevi altro, puoi provare a farmi un esempio ?
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[18] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 18 set 2014, 17:43

Sono io ad avere sbagliato: mi è sfuggita l'integrazione per alla quale, tra l'altro, hai dato evidenza: hai interpretato correttamente quello che prima intendevo.
Fai come non avessi scritto il Post [16].
Ora, però, se ti è possibile, non inserire più variazioni (o, per lo meno, sistema l'indentazione) rispetto al Post [15] e riporta (descrivi) quali sono, in questa condizione, le anomalie che hai modo di riscontrare.

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

0
voti

[19] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteDavide90 » 18 set 2014, 21:57

In attesa di sistemare un po l'indentazione ti scrivo quali problemi riscontro. Simulando il funzionamento con PIC Simulator IDE usando anche l'oscilloscopio integrato nel software, rilevo che lo stato ON non risulta essere 1,5ms bensì una numero variabile tra 4 e 8 microsecondi e lo stato off non risulta essere pari a 18,5 ms ma pari a pochi microsecondi... Il tutto è stato confermato da un oscilloscopio collegato ai pin del PIC.. Non riesco piu a capire quale sia il problema... Il timer dovrebbe essere impostato correttamente.. Non ho piu idee
Avatar utente
Foto UtenteDavide90
29 6
Frequentatore
Frequentatore
 
Messaggi: 130
Iscritto il: 5 lug 2012, 11:34

0
voti

[20] Re: Registro CMCON PIC16F628

Messaggioda Foto UtenteWALTERmwp » 19 set 2014, 2:15

Come ti scrivevo, l'impiego che fai del "do/while", con quel test, non è corretto.
I tempi che rilevi con l'oscilloscopio credo siano coerenti.
La gestione del timer 0 è corretta.
La forma d'onda che tu vuoi ottenere, nelle intenzioni, in pratica è un frenetico (microsecondi rispetto ai millisecondi) passaggio da 1 a 0 a 1 ... delle uscite.
Infatti, se hai un sensore attivo (esempio "FRONTinhibitedPort"), il flusso del programma, a prescindere dal valore che in quel momento ha la variabile "tempo" (può anche essere a 0, 1, 2 ... non importa), ti porta ad accedere a ...
Codice: Seleziona tutto
while(FRONTinhibitedPort)
{                         // entri qui ...
    do                                 
    {                     // ... ed entri qui ...
        MOTORE1OUTpos=1;  // ... e sequenzialmente fai questo ...
        MOTORE2OUTpos=1;  // ... poi fai questo ...
    }
    while(tempo==15);     // ... a prescindere dal valore di tempo

    do
    {                     // ... quindi entri anche qui ...
        MOTORE1OUTpos=0;  // ... e fai anche questo ...
        MOTORE2OUTpos=0;  // ... e poi fai anche questo.
    }
    while(tempo==200);    // ... sempre a prescindere dal valore di tempo
}
... dove sequenzialmente (senza quindi rispettare i periodi da te desiderati) le due variabili vengono prima poste a 1(uno) e poi a 0(zero) in quanto lo statement "do/while" lo esegui sempre, almeno una volta, pur non risultando valida la condizione che lo governa.
Ogni tanto, però, potresti riuscire a vedere un impulso corrispondente a poco più di 100 microsecondi.
Chiarito ciò, puoi trovare la soluzione (una soluzione) all'inghippo.
Puoi fare in diversi modi, proponine uno.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8986
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 11 ospiti