Vai al contenuto
PLC Forum


Rabbit (Progetto on-line)


Gabriele Riva

Messaggi consigliati

Ciao Livio , io se sono pacchetti da 20 byte , non uso interrupt , ma testo sempre il flag di buffer vuoto.

Anche io ho sempre programmato in ASM , inizio adesso con il C.

Penso che il tuo compilatore non sia il CCS che usa de direttive #USE RS232.

Per Walter , posso scrivere qualche cosa , ma adesso sono impegnato a disegnare una PCB che e' urgente , la devo consegnare questa sera.. appena finito , mentre corrode , provo qualche cosa.

per pochi byte , perde piu' tempo ad entrare nell'interrupt che fare tutto il resto.

Link al commento
Condividi su altri siti


  • Risposte 400
  • Created
  • Ultima risposta

Top Posters In This Topic

  • walterword

    154

  • dlgcom

    85

  • Livio Orsini

    46

  • ifachsoftware

    36

0k fratello

nel frattempo io faccio altre prove

provo a scrivere dal master allo slave , e poi far ripsondere quest'ultimo al master

che a sua volta se funzionera tutto accendere dei suoi led , anch'esso in I2C su un altro pcf8574

ciao

walter

Link al commento
Condividi su altri siti

in coclusione posto il codice e poi chiudo i battenti , troppo tempo per una trasmissione , scarse informazioni

scarse documentazioni e scarso anche internet con esempi , mi son proprio rotto .

MASTER

#include "pic_net1.h"

char d[4];

char in;

char val;

char string[5];

int y=0;

int count=0;

int outPCF8574;

int i;

int mem;

//INTERRUPT DI TRASMISSIONE ,ATTIVATO QUANDO IL BUFFER E' VUOTO

#int_TBE

TBE_isr()

{

output_high(PIN_C1); //ABILITO IL DRIVER MAX485 ALLA SCRITTURA

putc(string[count]);

count++;

if(count==4)

{

count=0;

disable_interrupts(INT_TBE);

output_low(PIN_C1);.

}

}

void main() {

disable_interrupts(INT_TBE);

enable_interrupts(global);

delay_ms(50);

while(1)

{

if(!input(PIN_A1) )

{

string[0]='1';

string[1]='A';

string[2]='B';

string[3]='\n';

string[4]='\r';

count=0;

enable_interrupts(INT_TBE);

}

if(!input(PIN_A2) )

{

string[0]='1';

string[1]='B';

string[2]='s';

string[3]='\n';

string[4]='\r';

count=0;

enable_interrupts(INT_TBE);

}

}

}

Link al commento
Condividi su altri siti

ciao

aaaaaah voi giovani volete la pappa pronta :P:D

di tanto in tanto ci vuole un po' di riposo (per la mente)

insomma mollare! poi la grinta ritorna.

forse gli esempi per internet li farai tu!

ciao

dario

Link al commento
Condividi su altri siti

be a 34 anni ti posso garantire che la pappa proprio pronta l'ho vista poche volte ;)

io per internet li sto gia facendo , ma non gli esempi , i cinema

se da google digiti rs485 ti verran fuori 4000 post che ho scritto

vedi te che figure di merda che mi tocca anche fare

Modificato: da walterword
Link al commento
Condividi su altri siti

SLAVE , il MASTER E' SOPRA DI qualche post

#include "pic_net1.h"

char d[4];

char in;

char val;

char buff_in[5];

int count2=0;

int outPCF8574;

int i;

//INTERRUPT DI RICEZIONE

#int_RDA

RDA_isr()

{

output_high(PIN_C0); //led spia che si accende ogni volta che entro nell'interrupt

buff_in[count]=getc(); //e si spegne quando ritorno nel mian loop

count++;

if(count==4)

{count=0;}

}

void main() {

enable_interrupts(INT_RDA);

enable_interrupts(global);

while(1)

{

if(buff_in[0]=='1')

{

if (buff_in[1]=='B')

{outPCF8574 =255;}

if(buff_in[1]=='A')

{outPCF8574=1;}

}

//scrivo al pcf8574 che accende o tutti i led o solo il primo

out_patt(0x40, 0x02, 0x80, outPCF8574 );

output_low(PIN_C0); //spengo il led spia

}

}

Modificato: da walterword
Link al commento
Condividi su altri siti

#include <16F876.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) 

void  trasmetti( char buffer , int lung){

       int i;
       
       output_high(PIN_C1); 


       for(i=0; i<lung; i++)

       putc(buffer[i]);

       output_low(PIN_C1); 
       
}

void main() {


   char  string;
   
   string[0]='1';
   string[1]='A';
   string[2]='B';
   string[3]='\n';
   string[4]='\r';

   trasmetti(string,5);

   
}

Cosi ad ogni reset dovresti trasmettere i 5 byte.

Per iniziare , poi si possono mettere i controlli .

Modificato: da dlgcom
Link al commento
Condividi su altri siti

niente da fare non funziona

ho perfino messo il settaggio di un led nel main per vedere se esegue il main

ma non si accende e non trasmette niente

quindi titubante ho ricaricato il master e funziona , quindi le porte ed il cablaggio no hanno subito

nessun danno

nello slave , ad ogni reset del master non si accende la spia di ricezione

e di conseguenza rimane tutto spento

pazzesco ....mi sta perfino venendo la congiuntivite

Link al commento
Condividi su altri siti

La prima parte tratta anche dell' interrupt di ricezione

#include <16F876.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 1

#int_rda

char  ricevi(){

      int r,lu;
      char ric;
      
      lu=getc();
      
      for(r=0; r<lu; r++)
      ric[r]=getc();
      
      return ric;
      
      }
      
      
      




void  trasmetti( char buffer , int lung){

       int i;
       
       output_high(PIN_C1); 
       
       putc(lung);

       for(i=0; i<lung; i++)

       putc(buffer[i]);
       
       output_low(PIN_C1); 
       
}

void main() {

   


   char  string;
   
   enable_interrupts(GLOBAL);
   
   string[0]='1';
   string[1]='A';
   string[2]='B';
   string[3]='\n';
   string[4]='\r';

   trasmetti(string,5);

   
}

Modificato: da dlgcom
Link al commento
Condividi su altri siti

Dovrebbe funzionare anche il led in ricezione

#int_rda

char  ricevi(){

      int r,lu;
      char ric;
      
      lu=0;
      lu=getc();
      
      for(r=0; r<lu; r++)
      ric[r]=getc();
      
      if(lu!=0) output_high(PIN_C0);

       else output_low(PIN_C0);
      
      return ric;
      
      }

Link al commento
Condividi su altri siti

ho provato il prog. della trasmissione , non mi alza il pin dell'abilitazione al driver 485, non so perche , allora

ho pensato di dargli il +5 v diretto con un cavallotto

ma niente da fare , non trasmette

lo slave non fa nemmeno una piega , di conseguenza il led spia ric . rimane spento

per far girare il programma ho anche aggiunto un delaydi 100ms prima di fare la scrittura ma niente da fare

allucinante , se vado avanti cosi mi ricoverano a san patrignano

mi sembra di essermi fatto mezzo litro di lsd

dopo 1 settimana che ci son sopra , son riuscito a trasmettere ed a ricevere con i sorgenti MASTER e SLAVE

posti sopra con il piccolo disguido che devo premere almeno quasi mezzo secondo i tasti

cioe non so piu cosa pensare <_<:(

Link al commento
Condividi su altri siti

non vorei dire un'idiozia

ma sembra che il main che viene eseguito un avolta sola non mi richiama

la funzione trasmetti , perche' all'interno di essa ho messo un led che si accende quando entra

devo capire come poter importare in MPLAB il sorgente .asm per vedere col simulatore

a parte che poi dovrei forzare il premere dei tasti , quindi come non detto

continuo a debuggare con i led

:(

x dlgcom

la funzione che hai scritto sopra , relativa alla gestione dell'interrupt di ricezione , restituisce

un carattere , ma come faccio ad ottenerlo ?

Dovrei richiamarla cosi :

char c=ricevi();

ma se e' un interrupt come faccio a chiamarla dal main o da un'altra funzione ? :unsure:

Modificato: da walterword
Link al commento
Condividi su altri siti

ciao

attenzione!

ma se e' un interrupt come faccio a chiamarla dal main o da un'altra funzione ?

le routin di interrupt non vengono chiamate con un call ocon dei salti ecc.ecc.

ma bensi' vengono chiamate dal hardware del micro!

cioe' l'interrupt di recezione della seriale verra' eseguito automaticamente quando un carattere sara' ricevuto.

per questo non capisco come mai venga detto che la gestione ad interrupt e' lenta (si perde tempo)

dopo aver compilato il programma ,l'entrata nel interrupt e' immediata (1 istruzione).

per quanto concerne gli altri interrupt e' la stessa cosa per esempio quello timer,

quando si raggiunge il conteggio(cioe' lo zero) il micro chiama una routin , appunto l'interrupt timer.

(il conteggio e' automatico , cioe' non lo devi fare tu)

avvo capito bene la domanda??

ciao a tutti

dario

Link al commento
Condividi su altri siti

riciao

dimenticavo....

all interrupt oltre che l'abilitazione va data anche una priorita',

in alcuni micro , pero', e' la stessa cosa:

priorita' =0 int disabilitato

priorita' =5 priorita 'media

ecc.

ciao

dario

Modificato: da Dario Valeri
Link al commento
Condividi su altri siti

interrupt nei micro , nei pl c, oppure metodo di gestione eventi in vc# sono la stessa cosa

sappiamo tutti benissimo che un interrupt e' una porzione di codice che viene eseguita al verificersi di un evento

la domanda che ho fatto a dlgcom consiste nel fatto che la funzione void ricevi() e' prededuta da #int_RDA

quindi presumo che sarebbe un interrupt , ma dal momento in cui la vedo non void , bensi char ricevi()

penso che essa mi restituisca un char , e che quindi per richiamarla devo , come in tutti i linguaggi di programmazione , "appoggiarla ad un tipo di dati uguale a quello che restituisce

char dato =ricevi();

credo che comunque sia un errore di distrazione , anche perche ieri sera di prove ne abbiamo fatte parecchie

ed eravamo tutti stanchi

non vedo altre spiegazioni

infatti stamattinna mi son svegliato ed ho gli occhi fuori dalle orbite

Comunque i due codici di cui sopra , MASTER e SLAVE sono scritti in maniera lecita

ed in effetti funzionano , bisogna pero premere i tasti con "sicurezza"

se premo un tasto velocemente vedo nello slave il led di ricezione lampeggiare 1 volta e non succede niente

, se ripremo ancora velocemente vedo il led rilampeggiare un'altra volta (2 volte ) e poi esegue le sue operazioni .

ho provato varie volte a scrivere (nem master ) i byte con ciclo come consigliatomi e cioe :

for(i=0;i<5;i++)

{

putch(buffer);

}

ma non funziona , anche se il compilatore pensa lui a vedere quando il registro TX e' vuoto

con l'interrupt funziona ma c'e' il problema sopra citato , in effetti non e' lampante

ciao

walter

Link al commento
Condividi su altri siti

Ciao Walter & C.

Il programma qui in basso funziona , l'ho provato ieri notte.

la funzione ricevi scrive in una stringa che e' definita come globale quindi visibile da tutti.

io ho fatto le prove con un 877 quindi devi cambiare l'include.

#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 1

char ric[5];

#int_rda

void  ricevi(){

      int r,lu;
      

      output_high(PIN_C1);

      lu=0;
      lu=getc();

      for(r=0; r<lu; r++)
      ric[r]=getc();

      output_low(PIN_C1);



      

      }







void  trasmetti( int buffer[] , int lung){

       int i;

       output_high(PIN_C0);

       putc(lung);

       for(i=0; i<lung; i++)

       putc(buffer[i]);

       output_low(PIN_C0);

}

void main() {



   char  string[5];
   
   enable_interrupts(global);
   enable_interrupts(int_rda);


   string[0]='l';
   string[1]='u';
   string[2]='c';
   string[3]='a';
   string[4]='\r';

   trasmetti(string,5);

    DO{

}WHILE(TRUE);


}

Link al commento
Condividi su altri siti

dunque ho caricato nel master la parte relativa alla trasmissione , e nello slave quella

della ricezione .

Premo il pulsante di reset nel master ed al suo rilascio lampeggia il led di trasmissione

mentre nello slave il led di ricezione rimane acceso 3 secondi (quanto ci mette a fare un ciclo

5 volte ?? cosi tanto ?? non credo )

quindi trasmete al riavviamento e riceve stando nell'interrupt di ricezione 3 secondi

sta di fatto che nello slave , nel main loop (do -while ) vado a verificare il pacchetto ricevuto

analizzando SOLO il 1° byte che deve essere , in base a quanto spedito ) un '1' .

in base a questo assegno alla avariabile PCF8574=255 e successivamente scrivo al device della philips

risultato , a parte il tempo che sta in ricezione 3 secondi , non funziona per l'ennesima volta

x Luca

non vorrei fare il professore saputello che poi fa figure di m....a ma

l'interrupt #int_RDA viene richiamato ogni volta che c'e' un byte pronto nella uart

quindi non capisco l'uso del ciclo for al suo interno ; tutt'al piu il ciclo for dovrebbe essere usato

(com edi solito mi capita ) all'interno di un interrupt che restituisce TUTTO il pacchetto e non solo un byte

....secondo me ..........

cioe se l'interrupt entra nella routine dopo aver ricevuto 1 byte , e noi facciamo un ciclo for andando a coinvolgere tutti i byte del buffer potremmo falsare il contenuto dello stesso .

Quindi ho provato a ricevere cosi : ric[count]=getc(); count++;if(count==5){count=0;}

ma nemmeno cosi funziona , adesso vedo di rifare la routine di trasmissione nel master

ciao

Link al commento
Condividi su altri siti

ciao

e' sconsigliato(*) usare dei for next o loop vari all'interno delle routin di interrupt, perche' quando esegui quella

gli altri interrpt , timer , altre seriali , tastiere, rimangono in attesa o vengono persi.!!!!

*= quasi proibito

ciao

dario

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora

×
×
  • Crea nuovo/a...