home | area personale         schemi | tutorial | robotica | pic micro | recensioni         forum | chat irc         faq | contatti         store | Ordina PCB
username
password
cerca

 
FORUM: Pic Micro
Tutto quanto riguarda questi microprocessori... progetti, suggerimenti, aiuti, discussioni...ecc


PORTA analogica in PIC16F873A
     
Autore Messaggio opzioni
picmicro675




una ogni 10 livelli


postato il:
15.09.2018, alle ore 20:08
DS30292A-page 72:
When the complete byte is received, it is transferred to the
SSPBUF register and flag bit SSPIF is set. If another complete byte is received before the SSPBUF register is read, a receiver overflow has occurred and bit SSPOV (SSPCON<6>) is set and the byte in the SSPSR is lost.

Non c'è un modo da disabilitarlo. La routine deve tenerne conto. Specialmente quando il valore viene letto/scritto.




Anno nuovo, forum nuovo.
Mi sa che lascio.
picmicro675




una ogni 10 livelli


postato il:
15.09.2018, alle ore 20:22
Ho un sentimento con questo progetto che mi stimola. Ho scritto un abbozzo. Non ha niente di pronto e funzionante, esprime un concetto.
/*                 Multi MCU controller project
*   This project attempts to design and use 6 16F873 tied up within a network
* using I2C protocol.
* For a semplified extent the internal clock is used, therefore the I2C clock
* will be limited to 100 kHz
*
* Basic functions for the project:
*   1 Master which use a LCD 16x2 display, potentiometers and push buttons
*   to administer the hardware
*
*   5 slaves which are used to gather digital and analog inputs and giving
*   also PWM and digital outputs
*
*   The network should handle packet command information, so that will allow
*   a variety of instruction and functions to be passed to the slaves        */

// compiled by   xc8
// file name mstr_main.c
// MCU 16F873
#include <xc.h>
#include "hwSetup.h"                // registers configuration
#include <LCD.h>                    // display port configuration

struct{                             // Flags for program
    unsigned readed_slv         :1; // flag to stop reading from the slaves
    unsigned written_slv        :1; // flag to stop to write to the slaves
    unsigned mstr_IO_OK         :1; // flag to stop reading from IO
    unsigned calc_OK            :1; // calc_action stop flag
    unsigned bit4               :1; //
    unsigned bit5               :1;
    unsigned bit6               :1;
    unsigned bit7               :1;
} flag = {1,1,1,1,0,0,0,0};

#define readed_slv      flag.readed_slv
#define written_slv     flag.written_slv
#define mstr_IO_OK      flag.mstr_IO_OK
#define calc_OK         flag.calc_OK

void main(void)
{
    init_vars();                    // set all structured variables
    init_LCD();                     // prepare the display
    init_ADC();                     // prepare the analog inputs
    init_IO();                      // prepare the digital I/O

/**************************MAIN LOOP*******************************************/
    while (1)
    {
        if ((ticks <= 20) && (readed_slv)) {
            i2c_read_slv();         // read data from all slaves and record' em
            // the routine will clear  the flag if all is gone good
            // otherwise there will be a repeatition
        }
        else if ((ticks >= 21) && (ticks <= 30) && mstr_IO_OK) {
            mstr_read_IO();         // read status from the master
            mstr_IO_OK = FALSE;     // this will perform once, only
        }
        else if ((ticks >= 41) && (ticks <= 80) && calc_OK) {
            calc_action();          // compute the expected in/ out actions
            calc_OK = FALSE;        // confirmed all processes are done
        }
        else if ((ticks >= 101) && (ticks <= 120) && written_slv) {
            i2c_wrt_slv();          // send instructions to all slaves
            // the routine will clear  the flag if all is gone good
            // otherwise there will be a repeatition
        }
        else if (ticks > 120) {
            flag = 0xf0;            // when all is performed, reset the flag
        }
        if (second == TRUE) {
            refresh_dsply();        // update the display status every second
            second = FALSE;
        }
    } // end main loop
}   //  end main routine

interrupt void ISR_Handler(void)
{
    if (T0IF) {
        T0IF=0;
        TMR0_Handler();
    }
    if (SSPIF) {
        LED_0 = ON;                 // Turn on LED to indicate I2C activity.
        SSPIF = 0;                  // Clear the interrupt flag.
        SSP_Handler();              // Do I2C communication
    }
    if (CCP2IF) {
        CCP2IF = 0;                 // Clear the interrupt flag.
        CCP2_Handler();             // Do timekeeping and sample tach inputs.
    }
    if (ADIF) {
        ADIF = 0;                   // Clear the interrupt flag.
        AD_Handler();               // Get A/D data ready and change channel.
    }
    if (RBIF) {
        RBIF = 0;                   // IOC the RB4~7, Clear the flag
        IOC_Handler();              // Do routine service for these inputs
    }
}//   end ISR_Handler

/*---------------------------------------------------------------------
 * This routine gets the data that is ready in the ADRES register and
 * changes the A/D channel to the next source.
---------------------------------------------------------------------*/
void AD_Handler(void)
{
}// end AD_Handler

/*---------------------------------------------------------------------
 * void CCP2_Handler(void)
---------------------------------------------------------------------*/
void CCP2_Handler(void)
{
    TMR1L = 0;                      // Clear Timer1
    TMR1H = 0;
}// end CCP2_Handler

/*---------------------------------------------------------------------
* This routine gets the data that is ready in the I2C network. Then
* one packet will be handled acconding the assigned flag
*---------------------------------------------------------------------*/
void SSP_Handler(void)
{
}// end SSP_Handler

/* This routine gets the inputs from the Interrup on change, caused on
 * the high nibble of PORTB
 * Commonly used to determine a push button and a digital filtering for that */
void IOC_Handler(void)
{
}// end IOC_Handler

/* This routine will handle the common clock so all process will be synchronize
 * by its ticking.
 * The time base is set at 5 mS. This will determines the main loop for
 * periodic actions                                                          */
void TMR0_Handler(void)
{
    TMR0 = 99;                      // reset the counter for 5 mS scheme
    if (++ticks < 200);             // as long as it reached not maximum
    else {
        ticks = 0;                  // else reset for a second ticking
        seconds = TRUE;             // set a flag to signalize a second is past
    }
}// end TMR0_Handler

La base del ciclo principale e da valutare quando poi si passa a verificare i tempi impiegati. Con il dubbio che meno possa determinare perdita di controllo, l' aggiornamento di un ciclo e sulla base di un secondo. Che poi è quello che si visualizza sul display.
Sarebbe meglio utilizzare una frequenza di lavoro di 16 MHz, che permetterebbe di quadruplicare le prestazioni.



Anno nuovo, forum nuovo.
Mi sa che lascio.
e.ferriani





postato il:
15.09.2018, alle ore 20:36
Purtroppo ci vuole tempo, capisco l'impegno a fondo perduto e lo apprezzo.

Come già detto più volte in passato, per chi non sa programmare a livello adeguato già scrivere ed inventarsi qualcosa che stia insieme è faticoso, leggere e capire cose scritte da altri di altro livello non è più semplice.

Ora sto traducendo le annotazioni per capire velocemente quello che fa, poi vedrò anche come, spero.

A supporto di quanto detto, quello che ho aggiunto e sembra risolvere, SSPIF = 0;, l'ho trovato proprio là.

Sto anche rivedendo i nomi delle variabili e delle altre cose, in modo da accorciarle.



Enea Ferriani
picmicro675




una ogni 10 livelli


postato il:
16.09.2018, alle ore 02:56
Direi che quello che hai fatto, è un bel lavoro e fa la sua strada. Se vuoi avere maggiori esperienze, come vedi sono disposto a condividere le mie. Ci potrà essere anche qualcosa di opinabile. non dico che ho la laurea o studiato a scuola per la programmazione. Ho imparato con le informazioni cercate e trovate, come titolo di interesse.

sembra risolvere, SSPIF = 0;

Direi che dovresti andare alla radice di come usare il flag (fatto notare quando cambia). Io penso che in questo modo rischi di perdere un carattere, perché nel momento in cui fai una trasmissione, se ti entra un interrupt che ti "assassina" il flag, quando riprende la trasmissione, dopo l'interrupt, si crede che hai già ricevuto il byte. Questo nel caso in cui si sta a vedere questo flag per determinare la fine della trasmissione.
Nella tua libreria è qualcosa di speciale, che non tiene conto di SSPIF, quindi non è certo a che punto legge SSPBUF durante la trasmissione.

Devo riordinare le routine della AN736, magari si dovranno organizzare come sono state descritte.



Anno nuovo, forum nuovo.
Mi sa che lascio.
picmicro675




una ogni 10 livelli


postato il:
16.09.2018, alle ore 04:54
Beh! ho riordinato i files della AN736, simili agli originali, salvo qualche svista e qualche riduzione di testate inutili..
http://www.grix.it/UserFiles/picmicro675/File/TransitFiles/A…
Ovvio da rivedere se passa con il compilatore xc8.
La cosa seccante di xc8 che non c'è una comunità che mantiene delle librerie.



Anno nuovo, forum nuovo.
Mi sa che lascio.
e.ferriani





postato il:
18.09.2018, alle ore 07:43
Ho convertito in interrupt quello che prima funzionava con flusso di programma gestito da delay.
Dopo aver risolto qualche giro strano del programma che bloccava nuovamente display e comunicazione, ma più che altro era la comunicazione a bloccare il display, ora funziona di nuovo.



Ora siamo pronti, credo, alla modifica pesante del firmware, andando ad attingere da quanto elaborato da Picmicro675.
Leggendolo velocemente ed a piccole dosi non sono ancora riuscito a capire come gira il fumo, perlomeno nel complesso, ovvero come sono incastrati i vari passaggi fra loro.
Le varie routine mi sembrano abbastanza chiare. C'è da far combinare il tutto nella sua interezza.
Qui c'è da studiare parecchio.



Enea Ferriani
e.ferriani





postato il:
18.09.2018, alle ore 07:45
Il video non va, non è raggiungibile, almeno sul mio pc. Ci riprovo.

https://youtu.be/M5uSfi05rKM



Enea Ferriani
picmicro675




una ogni 10 livelli


postato il:
18.09.2018, alle ore 09:30
e.ferriani:
Leggendolo velocemente ed a piccole dosi non sono ancora riuscito a capire come gira il fumo


Prendi l' esempio più semplice di far lampeggiare i LED a tempi diversi. Si basa su il fatto che si controlla se il tempo è arrivato allora si esegue il blocco di programma assegnato, altrimenti passa a quello successivo. In certi momenti non fa altro che passare da uno all' altro, dato che nessuno è pronto.



Anno nuovo, forum nuovo.
Mi sa che lascio.
e.ferriani





postato il:
22.09.2018, alle ore 21:05
Cosa significa una struttura del genere?

sflag.event.read_start

Ho messo un esempio per tutti.
Forse capendone il significato riesco ad andare avanti.





Enea Ferriani
picmicro675




una ogni 10 livelli


postato il:
23.09.2018, alle ore 06:14
La struttura è un blocco dati che contiene vari flags e bytes o altro.
Quindi per ogni connessione ad uno slave il master annota gli eventi e i dati gestiti.
Cosa significa una struttura del genere?
sflag.event.read_start


Quello è un flag, che determina la preparazione di trasmissione con gli slaves se il flag è a zero.

    if (!sflag.event.read_start)        // execute once per entire rounds of
                                        // slave reads

Quindi fa partire la funzione Service_I2CSlave() che ha diversi controlli.

I dettagli sono spiegati a DS00736A-page 7, in riguardo alle funzioni del master. Del quale si descrive 4 interrupt:
1) quello della trasmissione I2C
2) quello di errori di trasmissione
3) quello della trasmissione UART
4) quello del Timer1 che indaga i dati con gli slaves ad ogni decimo di secondo.



Anno nuovo, forum nuovo.
Mi sa che lascio.
segui questo thread con grixFC, per questa funzione devi aver installato il software grixFC

torna su
     

Come utente anonimo puoi leggere il contenuto di questo forum ma per aprire una discussione
o per partecipare ad una discussione esistente devi essere registrato ed accedere al sito




 







 
 
indietro | homepage | torna su copyright © 2004/2024 GRIX.IT - La community dell'elettronica Amatoriale