Vai al contenuto
PLC Forum


Rabbit (Progetto on-line)


Gabriele Riva

Messaggi consigliati


  • Risposte 400
  • Created
  • Ultima risposta

Top Posters In This Topic

  • walterword

    154

  • dlgcom

    85

  • Livio Orsini

    46

  • ifachsoftware

    36

perfetto , la stessa cosa la dice il datasheet del max485

:D

sto implementando anche un sito in asp.net , con server web iis.

mi collego alla rete tramite una dll per rs232 ,

certo la pagina html che visualizzo e' statica , bisogna refresharla ogni tot tempo

pero funziona

ma quante cose potranno venir fuori qua ?

:lol::lol::lol:

dall'applicazione asp.net lanciero il client verso il rabbit server

cosi potremmo pilotare il coniglio e tutta la sua rete da localita remote

Modificato: da walterword
Link al commento
Condividi su altri siti

sto cercando di implementare la libreria "rs485.c"

Quindi ho aperto unnuovo progetto con un pic16f876 , e includo tale libreria

senza scrivere nessun codice controllo se viene accettato tutto , quindi compilo e mi da alcuni errori

alcuni riparati , ma quello che non capsco e' qua , evidenziato dopo un tentativo di compilazione

#use rs232(baud=9600, xmit=RS485_TX_PIN, rcv=RS485_RX_PIN, enable=RS485_ENABLE_PIN, bits=9, long_data, errors, stream=RS485)

l'errore dice che i parametri utilizzati nello #USE sono fuori range

:angry:

c'e' qualcuno che ha gia usato questa libreria ? cioe quando , e non so quando , verra compilato il progetto con essa , quali sono le funzioni da usare e come ?

presuppongo che nel main , prima del loop infinito si debba inserire questa funzione

rs485_init() ;

poi non capisco questa definizione

getenv("AUART"); cosa vuol dire getenv() nonc'e' nella guida

come vanno usate le altre funzioni della libreria ?

in uno schema che ho trovato dice di collegare (nel max485 ) il +5 con A e la massa con B attraverso 2 resistenze da 620 hom , e' vero ?

grazie a tutti coloro che mi daranno una mano

ciao

walter

Modificato: da walterword
Link al commento
Condividi su altri siti

ciao

string getenv ( string varname)

Restituisce il valore della variabile d'ambiente varname, oppure FALSE in caso di errore.

come vedi qualcuno c'e'

dario

Link al commento
Condividi su altri siti

in sostanza includo il file .c (driver rs485 ) nel file .c del mio progetto

ma in fase di compilazione mi da un sacco di errori

tra l'altro nella guida del compilatore non c'e' nemmeno una spiegazione di getenv ()

e' un discorso troppo complicato , variabili d'ambiente

no no

bisogna che metto giu 4 righe per comunicare in rs485 , questa libreria la fa troppo pesante

devo riuscire a comunicare in maniera piu sintetica :

nel master

-devo trasmettere ?

-si . alzo il bit di abilitazione al max485

-scrivo un byte

-abbasso il bit di abilitazione trasmissione

nello slave:

abbasso il bit di trasmissione

nell'interrupt , quando ricevo un byte

lo leggo con getc() e lo appoggio su di un byte .

poi nel main loop lo confronto e faccio accendere un led piuttosto che un altro

deve funzionare cosi , semplicemente , stando alle specifiche dei componenti e del rs485

poi quando sara il momento andro a rovinarmi la vita con librerie e drivers vari

ma adesso deve funzionare cosi , seno prendo e butto tutto nella pattumiera

e buonanotte suonatori , ho perso troppo tempo e speso troppi soldi per trasmettere una cagata di un byte

di m...a

grazie dario per le gentili informazioni

ciao

walter

Link al commento
Condividi su altri siti

non capisco cosa devo fare

nel master scrivo cosi :

#include "pic_net1.h"

#include "Lib_I2C.c"

// delay routines

//void delay_ms(long t);

//void delay_10us(int t);

char d[4];

char in;

char val;

char string[7];

int y=0;

char buff_in[10];

int count=0;

int outPCF8574;

int i;

byte a,b,c;

#int_TIMER1

TIMER1_isr()

{

}

void main() {

setup_adc_ports(NO_ANALOGS);

setup_adc(ADC_CLOCK_DIV_2);

setup_spi(FALSE);

setup_counters(RTCC_INTERNAL,WDT_576MS);

setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);

setup_timer_2(T2_DIV_BY_16,62,3);

setup_ccp1(CCP_OFF);

setup_ccp2(CCP_OFF);

setup_adc_ports( RA0_ANALOG );

setup_adc(ADC_CLOCK_INTERNAL );

set_adc_channel( 0 );

disable_interrupts(INT_RDA);

disable_interrupts(INT_TBE);

enable_interrupts(INT_TIMER1);

enable_interrupts(global);

delay_ms(50);

while(1)

{

output_low(PIN_C0);

delay_ms(100);

output_high(PIN_C0);

output_high(PIN_C1); //abilito la trasmissione

delay_ms(100);

putc('*');

putc('B');

putc(13);

output_low(PIN_C1);

//printf("\n\r");

}

}

mentre nello slave scrivo cosi :

#include "pic_net1.h"

#include "Lib_I2C.c"

void _8591_ad_meas(int dev_adr, int *d);

void out_patt(int dev_code, int adr, int dirs, int patt);

// delay routines

//void delay_ms(long t);

//void delay_10us(int t);

char d[4];

char in;

char val;

char string[7];

int y=0;

char buff_in[10];

int count=0;

int outPCF8574=0;

int i;

char c;

#int_TIMER1

TIMER1_isr()

{

}

#int_RDA //interrupt data avaible

RDA_isr()

{

output_high(PIN_C0); //led spia per vedere se entro nell'interrupt e quindi vedo se i dati arrivano

c=getc();

}

void main() {

setup_adc_ports(NO_ANALOGS);

setup_adc(ADC_CLOCK_DIV_2);

setup_spi(FALSE);

setup_counters(RTCC_INTERNAL,WDT_576MS);

setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);

setup_timer_2(T2_DIV_BY_16,62,3);

setup_ccp1(CCP_OFF);

setup_ccp2(CCP_OFF);

setup_adc_ports( RA0_ANALOG );

setup_adc(ADC_CLOCK_INTERNAL );

enable_interrupts(INT_RDA);

disable_interrupts(INT_TBE);

enable_interrupts(INT_TIMER1);

enable_interrupts(global);

delay_ms(150);

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

while(1)

{

delay_ms(100);

if(c=='A')

{outPCF8574 =12;}

if(c=='B')

{outPCF8574 =4;}

output_low(PIN_C0);

out_patt(0x40, 0x02, 0x80, outPCF8574 );//scrivo al remotato pcf8574 in I2C

}

}

nell'interrupt dello slave relativo alla ricezione del byte metto un led che si accende , e che si spegne dopo 100ms

che sono rientrato nel mian loop , quindi vuol dire che i dati arrivano , o no ?

pero poi vado a controllare il byte arrivato ed in base a questo decido di dare un valore al byte che scrivo in I2C

al chip delle 8 uscite digitali

ma non funziona , sembrerebbe che il dato arrivato non sia quello che spedisco

nel master ho provato di tutti i colori , boh non so piu cosa fare

ciao a tutti

Modificato: da walterword
Link al commento
Condividi su altri siti

ciao

anche io solitamente opto per fare da me le routin di questo tipo.

io farei cosi' :

dopo aver messo la stringa nel buffer (10 byte?? ok)

verifico se' e' il momento di iniziare a trasmettere (il max 485 e' sempre abilitato!)

si e' il momento di scrivere , allora metto il primo byte nel registro di trasmissione (io non uso getc o putc o printf)

abilito la trasmissione di quella uart del micro.

a questo punto il micro spara fuori due byte , il tuo dato e i vari caratteri come start , stop ,parita' .

appena il micto genera l'interrupt di fine trasmissione incrementare il puntatore

al dato da trasmettere e se uguale a 10+1 disabilitare la trasmissione (nel micro)

siamo ancora dentro all'interrupt, mettere il successivo dato nel registro di trasmissione del micro

e attendere il nuovo interrupt di trasmissione eseguita.

niente di piu' semplice.!!

tutte queste operazioni vanno fatte dall'interno della routine di interrupt perche' appena esci

parte automaticamente la trasmissione.

per la recezione vale lo stesso discorso.

se intendi , comunque , buttare tutto nella spazzatura sappi che io ho un grande cestino ...vuoto.

purtroppo non ti posso aiutare in modo diretto perche' non conosco i pic

ciao

dario

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

dunque c'e ' qualcosa di strano :

nel master scrivo

putc('*');

putc('B');

putc('\');

nello slave il led spia posto nell'interrupt di ricezione mi si accende , quindi vuol dire che nell'interrupt entro e che quindi il dato arriva , allor aho fatto una modifica nello slave

char buff_in[3];

int count=0;

int outPCF8574=0;

#int_RDA

void int_ric()

{

buff_in[count]=getc();

count++;

if(count==3){count=0;}

}

void main ()

{

delay_ms(50);

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

{

outPCF8574=16;

}

// cosi funziona , cioe riconosce il carattere '*' e di conseguenza assegna il valore a PCF8574

//se invece faccio

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

{

outPCF8574=16;

}

//non succede niente e non capisco perche????????

dal master spedisco 3 caratteri '*' , 'B', '\'

cioe sembrerebbe che il buffer di ricezioni venga scritto correttamente , se mi riconosce '*' deve riconoscere anche gli altri caratteri

DLGCOM dove seiiiiiiiiiiiiiiiiiiiiii??????????????????????????????'''

:rolleyes:

ciao

walter

Modificato: da walterword
Link al commento
Condividi su altri siti

si ho provato ma non va , ho fatto varie prove di cui :

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

{

outPCF8574=16;

}

non funziona

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

{

outPCF8574=16;

}

non funziona

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

{

outPCF8574=16;

}

non funziona

mentre

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

{

outPCF8574=16;

}

funziona

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

{

outPCF8574=16;

}

funziona

if( buff_in[2]=='*')

{

outPCF8574=16;

}

funziona

non so piu cosa pensare , che ferragosto di mmmmmmmmm.............................aaaaaaaaaaaaaaaaaa

:angry::angry::angry: maledetto il giorno che mi e' venuto in mente di studiare i micro

azzzzzzz

ma come e' possibile????

dal master scrivo :

putc('*');

putc('B');

putc(13);

adesso faccio l'ultima prova ,invece di usare putc() uso printf(stringa) e compongo la stringa con i caratteri di prima , poi accendo il fuoco per un'altra bella grigliata , viene un'amica dalla toscana con la ciccia fresca e buona (ciccia=costate carne chianina )

f.....o!!! i micro

ciao

walter

Modificato: da walterword
Link al commento
Condividi su altri siti

OK ADESSO FORSE FUNZIONA

ho fatto una modifica nel master

char string[5];

void main()

{

while(1)

{

delay_ms(100);

string[0]='*';

string[1]='B';

string[2]='A';

printf(string); //scrivo sulla seriale

printf("\n\r");

}

}

nello slave c'era un errore nell'interrupt , e cioe azzeravo l'indice del buffer_in quando arrivavo a 3

invece doveva essere a 2

quindi adesso nello slave e' cosi :

char buffer_in[5];

int count =0;

#int_RDA

void int_byteric()

{

//accendo led spia

buff_in[count]=getc();

count++;

if(count==4){count=0;}

}

void main()

{

outPCF8674=0;

while(1)

{

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

{outPCF8574=16;}

//spengo il led spia

//scrivo sul PCF8574 in I2C

}

}

adesso funziona o almeno sembrerebbe .dario forse ti va male per il tuo cestino ;):lol:

bene bene bene

domani 4 prove ancora giusto per mettere giu un protocollino , e poi entra di scena il rabbit che sara master

delle 2 schede del pic , poi tiro fuori l'applicazione client modbus tcp\ip che avevo scritto 1 mese fa

e metto il rabbit anche in ethernet col pc

poi finalmente il mio progetto sudatissimo e ' sara quasi finito

.... devo solo riprovare con asp.net in localhost un sito web con server web IIS , con un thread che gestira

il client verso il rabbit che sara anche server .

Con asp .net avevo gia provato a lanciare dei comandi sulla seriale verso il pic e funzionava

Cosi poi avro a disposizione le tecnologia , e dovro solo processare i buffer in ingresso ed uscita relativi al protocollo modbus seriale e tcp\ip

bene signori , il mio progetto continua , ed un altro passo , quello che temevo di piu l'ho superato

e cioe la trasmissione rs485 sia a livello hw che sw , che poi nel sw non e' che cambi molto dal rs232

a parte le abilitazioni del driver

:lol:

adesso si che mi posso fare un a bella grigliatina tranquillo e rilassato , una bell abottiglia di vino rosso e.......

a piu tardi o domani

ciao

walter

Link al commento
Condividi su altri siti

dunque nel PIC master ho 2 pulsanti , relativamente PIN_A1 e PIN_A2

a seconda di quello che premo decido il bufferino da inviare

quindi

char buff[5];

if(input(PIN_A1)

{

buff[0]='*';

buff[1]='B';

buff[2]='Z';

printf(buff);

print ("\n\r");

}

if(input(PIN_A2)

{

buff[0]='*';

buff[1]='A';

buff[2]='Z';

printf(buff);

print ("\n\r");

}

nello slave gestisco la ricezione nel buff_in e fin qui adesso funziona tutto , poi nel loop controllo nella posizione

buff_in[1] quale carattere c'e' , e cosi se trovo 'A' sparo in I2c al pcf8574 255 quindi si accendono tutti i led ad esso connesso , se invece trovo 'B' scrivo 1 ed accendo solo il primo led collegato al PCFxxxx.

Pero vedo che di continuo , pur non essendoci niente in rete , lo slave continua ad entrare nell'interrupt

di ricezione e non capisco perche .

poi c'e' un problemino sul PCf8574 e cioe ogni tanto sfarfallano in sequenza i led , per poco pero mi rompe

non capisco come mai .

Nel master sto gia pensando di utilizzare dei "merker" come fronte di salita per il premere dei 2 pulsanti

in modo tale da esser sicuro si spedire solo una volta il pacchetto perche vedo che e' molto lento il sistema

cioe per far prendere al pcfxxx il dato devo premere per piu di un secondo la spedizione , seno mi ritorna

quella precedente , mah saranno accorgimenti .......

domani dovro poi far rispondere lo slave in base alle richieste del master e poi entra il Rabbit

ciao

walter

Link al commento
Condividi su altri siti

ok ho risolto i problemi sopra elencati

solo che pero quando premo un tasto , per fare arrivare tutto il pacchetto devo premere piu volte per l'esattezza 4 volte , e sempre cosi

allora ho aggiunto un ciclo for che mi ripete la scrittura 2 volte e adesso funziona che e' una meraviglia

int mem;

if ((input(PIN_A1) && !bit_test(mem,0))

{

buff[0]='*';

buff[1]='B';

buff[2]='Z';

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

{

printf(buff);

print ("\n\r");

}

bit_set(mem,0);

}

if(!input(PIN_A1))

{

bit_clear(mem,0);

}

in questa maniera premo una volta sola P1 e trasmetto in modo tale che lo slave accenda tutti i led

mentre se premo P2 si accende un solo led come volevo .

Gli sfarfallii non ci sono piu , ed il led spia posto nell'interrupt dello slave lampeggia solo 1 volta

quando gli arriva il pacchetto .

:) lo lascio cosi che va bene , poi ci sara da ridere pero quando dovro spedire pacchetti a seconda della logica del micro , quindi mi sa che dovro utilizzare l'interrupt di trasmissione

buonanotte

walter

Link al commento
Condividi su altri siti

Ciao Walter e company,

Scusa se non ti ho risposto prima , ma per il fine settimana lo dedico alla famiglia , quindi niente internet e PC.

Per la libreria , anche io ho questa libreria da poco , e' presente solo nelle ultime versioni di CCS.

Oggi provo a fare una piccola routine per veder se a me funziona.

Se da esito positivo ti faccio sapere.

Io avevo fatto alcune prove in assembler e funzionave bene .

Link al commento
Condividi su altri siti

ciao fratello

sono riuscito ieri a trasmettere un pacchetto di 5 byte dal pic master al pic slave

nello slave un led spia mi si accende solo quando arriva il pacchetto (lo setto nell'interrupt di ricezione e lo resetto

nel main loop )

spedisco il pacchetto sul premere di 2 pulsanti , quindi spedisoc 2 pacchetti differenti solo per un carattere ,

usando due memorie bit che mi fanno da fronte di salita (che poi in realta sarebbe di discesa)

solo che pero devo usare un ciclo for per ripetere la spedizione 2 volte , una volta sola non basta per farmi arrivare il pacchetto intero (dorei premere 2 volte il pulsante ) , non capsico perche visto che uso purintf

forse sara legato al fatto che il micro impiega piu di un ciclo di clock per effettuare la scrittura su seriale

Comunque cosi funziona , adesso faro delle prove di risposta da parte dello slave e poi devo assolutamente

provare col rabbit master

ciao

walter

Link al commento
Condividi su altri siti

Ciao Walter,

Penso di aver risolto il mistero.

La libreria funziona solo dalla versione 3.180 in poi e aggiunge queste funzioni:

New options for #UASE RS232:
   SAMPLE_EARLY A getc() normally samples data in the middle of a bit time.  This option causes the
                sample to be at the start of a bit time.  May not be used with the UART.
   RETURN=pin   For FLOAT_HIGH and MULTI_MASTER this is the pin used to read the signal back.
                The default for FLOAT_HIGH is the XMIT pin and for MULTI_MASTER the RCV pin.
   MULTI_MASTER Uses the RETURN pin to determine if another master on the bus is transmitting at
                the same time.  If a collision is detected bit 6 is set in RS232_ERRORS and all
                future PUTC's are ignored until bit 6 is cleared.  The signal is checked at the
                start and end of a bit time.  May not be used with the UART.
   LONG_DATA    Makes getc() return an int16 and putc accept an int16.  This is for 9 bit data formats.
   DISABLE_INTS Will cause interrupts to be disabled when the routines get or put a character.
                This prevents character distortion for software implemented I/O and prevents interaction
                between I/O in interrupt handlers and the main program when using the UART.

   See RS485.C in the drivers directory for an example RS485 protocol implementation.

Penso che il tuo sia piu' vecchio e per questo che ti da errori.

Per mandare un byte il pic usa solo un ciclo di clock perche deve solo traferire il byte nel registro della uart, a meno che tu non stai usando un pic senza uart interna o hai assegnato dei pin per tx e rx sbagliati.

Come usi la il comando #use rs232?

Quale pic usi?

Link al commento
Condividi su altri siti

uso 2 PIC16F876

#use delay(clock=4000000,RESTART_WDT)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)

uso un quarzo da 4 Mhz perche quelli da 20 non li avevano

i pic RC6 ed RC7 sono quelli soliti dedicati alla uart per il PIC16F876

:(

adesso sto provando e non va niente , cioe arriva il pacchetto allo slave ma non comanda piu

il pcf in I2C , ho gia controllato tutti i fli , ma che palle ..............

dovevo fare delle prove e invece mi devo mangiare il fegato anche oggi

Link al commento
Condividi su altri siti

adesso ho fatto in un'altra maniera

sul fronte del premere dei pulsanti preparo il maledetto schifosissimo inafame buffer di mmm.a

ed abilito l'interrupt di trasmissione

all'interno del buffer di trasmissione sparo i 5 byte cosi :

#int_TBE

void_trasm()

{

putc(buffer[count]);

count++;

if(count==4){count=0; disable_interrupt(TBE);

}

funziona ma deve premere 2 volte il tasto seno dall'altra parte no arriva

ca**o ma come devo fare , non ne posso piu

Modificato: da walterword
Link al commento
Condividi su altri siti

forse ho capito perche devo premere 2 volte

mmmmmmmm...........

in effetti nello slave testo il secondo byte del buffer , quindi vuol dire che il mio errore e' stato quello di pensare

che tramite l'interrupt di trasmissione venisse spedito tutto il pacchetto

mentre l'interrupt mi dice solo quando ha spedito un byte

sta di fatto che comunque all'interno di esso gli faccio spedire un altro byte , cosa che pero il pic non fa

I byte li devo spedire da un 'altra parte , e l'interrupt mi dice solo quando il byte e' stato spedito per preparare il byte successivo , ma dall'interrupt non spedisce .

Questo lo vedo dal led spia nello slave che riceve .

Quindi e 'qua l'inghippo .

Il fatto e' dimostrato quando ho tolto i fronti di salita , e premendo il tasto vedevo diverse volte lampeggiare

illed di ricezione nello slave e.........guarda caso al secondo lampeggio eseguiva da bravo bambino le sue operazioni

dovrei crearmi un interrupt a tempo di circa 80 ms , abilitarlo in caso di spedizione pacchetto , e al suo interno

spedire un byte alla volta indicizzando il buffer , l'indice incrementera ogni volta che avro l'interrupt

di byte spedito e alla fine disabilito l'interrupt del timer

si cosi deve funzionare

Link al commento
Condividi su altri siti

Walter ,

Io non userei un interrupt per trasmettere , usando Putc() o printf() il compilatore genera gia' il controllo per sapere se il buffer di uscita e' vuoto.

Avendo pochi byte da mandare fai un loop e lascia che il compilatore faccia il resto.

In ricezione , se non puoi lasciare il pic ad aspettare un dato in riicezione puoi usare l'interrupt.

Io per esempio mandarei un cod di indirizzo , seguito da quandi byte voglio inviare , cosi' nela mia routine aspettero' x byte prima di uscire.

Se ti va bene , possiamo scrivere il prg.

Link al commento
Condividi su altri siti

si dai , scriviamo il programma

io posto quello che ho scirtto fino ad ora

la parte master e quella slave

son poche righe , cosa ne dici ?

anzi , visto che tanto i miei problemi non interessano a nessuno , salvo te , dario e ifach che pero e' al mare B)

ti scrivo in privato le 4 righe

tu le guardi e poi mi dici come faresti tu ?

ok?

p.s. ma il oop che dici tu per trasmettere dove lo piazzo ? nel main lool

per esempio cosi ?

void main ()

{

while(1)

{

if(condizione per trasmettere)

{

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

{

putc(buffer;

}

}

}

}

considera che sarebbe meglio sviluppare qualcosa che possa nel futuro permettere di trasmettere piu di 20 byte come mi servono adesso , senza compromettere il resto dell'automazione

potrebbe capitare di farci qualcosina coi micro , non e' che mi sto sbattendo cosi per divertirmi

anche perche con tutti sti problemi mi diverto ben poco

ok fratello dimmi se sei d'accordo sul fatto che ti spedisco le 4 righe che ho scritto fino ad ora

ciao

Modificato: da walterword
Link al commento
Condividi su altri siti

Io ho sempre usato interrupt sia per RX che per TX, anche perchè i driver li ho sempre scritti in Assembler.

Comunque di seguito riporto il soft funzionante per Modbus (pic 16F876) in "C"

///////////////////////////////////////////////////////////////////////////

/// MDB_Transmit                  ///

///////////////////////////////////////////////////////////////////////////

// Invia un messaggio al dispositivo master

//  length [in]  lunghezza del messaggio da trasmettere

#byte TXSTA = 0x98

#define TRMT 1

void MDB_Transmit(int length)

{

int i;

delay_ms(30);

bit_set(pc,2);            // Setta il line driver 422/485 in Trasmissione

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

putc(tx_buff);

while(bit_test(TXSTA,TRMT)==0)

{

  delay_cycles(1);

}

    delay_ms(1);

bit_clear(pc,2);          // Setta il line driver 422/485 in Ricezione

enable_interrupts(int_rda);      // Riabilita la ricezione

mdb_rx_flg = FALSE;

rx_buff.nbyte = 0;

}

#include <modbtgt.c>

///////////////////////////////////////////////////////////////////////////

/// MDB_Receive            ///

///////////////////////////////////////////////////////////////////////////

int MDB_Receive()

{

long chk_calc,chk_rx;

int res;

if ((rx_buff.data[0]!=mdb_slave_address) && (rx_buff.data[0]!=0))

{

  return 0;

}

chk_rx = (long) (rx_buff.data[(rx_buff.nbyte - 1)]); // MSByte del checksum ricevuto

chk_rx = (chk_rx << 8);                              // MSByte posizionato nella posizione corretta

chk_rx+= (long) (rx_buff.data[(rx_buff.nbyte - 2)]); // LSByte del checksum ricevuto

chk_calc = Checksum(&rx_buff.data[0], (rx_buff.nbyte - 2));

if(chk_calc != chk_rx)

  return ERR_CHECKSUM;

else

{ // dispaccia il messaggio

  switch (rx_buff.data[1])

  {

case MDB_READ_HOLDING_REGISTERS:  // Function 0x03

    res=TMDB_Read_Holding_Registers(rx_buff.data[3], rx_buff.data[5]);

    break;

case MDB_PRESET_MULTIPLE_REGISTERS: // Function 0x10

        res = TMDB_Preset_Multiple_Registers(rx_buff.data[3], rx_buff.data[5]);

    break;

default: // funzione non supportata o non prevista

    res= ERR_MDB_ILLEGAL_FUNCTION;

    break;

  }

}

return res;

}

///////////////////////////////////////////////////////////////////////////

/// Exception            ///

///////////////////////////////////////////////////////////////////////////

// Invia il messaggio di errore al dispositivo master

void Exception(int exc_code)

{

unsigned long chk;

// prepara il messaggio di errore

tx_buff[0] = 0;

tx_buff[1] = rx_buff.data[1] | 0x80; // error mark

tx_buff[2] = exc_code;      // error code

chk = Checksum(&tx_buff[0],3);

tx_buff[3] = (int) chk;

tx_buff[4] = (int) (chk >> 8);

// Transmit Modbus Answer

MDB_Transmit(5);

}

///////////////////////////////////////////////////////////////////////////

/// MAIN                ///

///////////////////////////////////////////////////////////////////////////

main()

{

int err;

unsigned long vadc=0;

disable_interrupts(global);

port_b_pullups(FALSE);  // Inizializzazioni Porte

// Settaggio Porte su In/Out

set_tris_a(0x00);  // PortA - All Pin Out - No one is used

set_tris_b(0x01);  // PortB - PB0 - ADS7844 BUSY - In

    //    - PB1 - ADS7844 SHDN - Out

    //    - PB2 - MOTOR CONTROL- Out

    //    - PB3 - CND_SCALE_B  - Out

    //    - PB4 - CND_SCALE_A  - Out

    //    - PB5 - 24C16 - WP - Out

    //    - PB6 - Not Used  - Out

    //    - PB7 - Not Used    - Out

set_tris_c(0x81);    // PortC - PC0 - 24C16 - SCL  - Out

    //    - PC1 - 24C16 - SDA  - Out

    //    - PC2 - RS485 TX/RX# - Out

    //    - PC3 - ADS7844 - SCK- Out

    //    - PC4 - ADS7844 - SDI- In

    //    - PC5 - ADS7844 - SDO- Out

    //    - PC6 - RS485 TX  - Out

    //    - PC7 - RS485 RX    - In

bit_clear(MDB_TXEN);    // Set RS485 in Receive Mode

// Inizializza la porta SPI per la lettura dei dati dall'ADC

setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);

// inizializza il timer utilizzato per timeout su ricezione messaggi ModBus

setup_timer_1(T1_INTERNAL);

// nessun dato ricevuto

mdb_rx_flg = false;

rx_buff.nbyte=0;

bit_clear(PIR1,TMR1IF);

disable_interrupts(int_timer1);

enable_interrupts(int_rda);

mdb_slave_address= eeprom_read(EE_SND_ADDR);  // Lettura dello Slave Address

bit_clear(MOTOR_CNT);                // Motore Spento

enable_interrupts(global);

// ModBus loop

for (;;)

{

  if (mdb_rx_flg)

  {

// ho ricevuto un messaggio dal master

err=MDB_Receive();

if(err!=0)

    Exception(err);

  }

}

}

Ignora le periferiche che non interessano

Walter il tuo ICD usa la connessione USB2?

Link al commento
Condividi su altri siti

caaaazzzzzzzzzzz

finalmente un po di codice

ciao boss :D

si ho l'icd2 in usb , so solo programmare , debuggare ho provato ma non funziona

ah boss , tutti i file .C che includi sono nel file postato o sono a parte?

per esmpio #include <modbtgt.c> presuppongo sia la libreria dal quale estrai varie funzioni usate nel codice

o no?

ciao

walter

boss ti devo venire a trovare un giorno di questi , porto le mie basette cosi la faccio finita con questa maledetta comunicazione , e'piu di una settimana che sto bestemmiando

Modificato: da walterword
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...