wer180m Inserito: 7 febbraio 2009 Segnala Inserito: 7 febbraio 2009 (modificato) Salve a tutti, è da un pò che studio i pic, ma non da abbastanza per fare questo che sto cercando di fare senza chiedere alcune cose:L'obiettivo sarebbe costruire una periferica con interfaccia rs485 che legga dei registri da una slave e in base a questi, mandi i comandi all'altra slave.Vi chiedevo se esiste un simulatore via pc in modo da vedere se la periferica manda correttamente o riceve correttamente i comandi, purtroppo dispongo solo di prese usb, esiste un modo per farlo? il programmatore è un pckit2 ho letto che è un debugger, ha qualche funzione di questo tipo?il circuito sarà un pic16f628 con le usart collegate al max485, ma...per precisione logicamente metto un quarzo, ma che quarzo usare? da 4 o da 20?come linguaggio uso il mikrocPS: complimenti è un bellissimo forum questo!Massimo Modificato: 7 febbraio 2009 da wer180m
wer180m Inserita: 7 febbraio 2009 Autore Segnala Inserita: 7 febbraio 2009 (modificato) aggiungo altre informazioni:il dispositivo è un TISYSTEM della Bticino, e in particolare il M7TIC/CM che legge valori di corrente e tensioni, io devo leggere questi registri:Indirizzo _____________Dimensione____________Descrizione____________Unità di misura____________Funzione1000h_________________Long____________________tensione nella fase 1 ®______mV_________________________03h1002h_________________Long____________________tensione nella fase 2 (S)_____mV_________________________03h1004h_________________Long____________________tensione nella fase 3 (T)_____mV_________________________03h1026h_________________Word____________________frequenza trifase__________1/10Hz______________________03he se questi non vanno bene, devo mandare il comando all'altro slave che è il M7TIC/IO sempre bticinoPS: oltre al 16f628, ho questi altri pic se sono più indicati non saprei:PIC16f874APIC16F877APIC16F873APIC12F675e aggiungo che la periferica è ad uso amatoriale quindi la vorrei ridurre al minimo, basta che funzioni Modificato: 7 febbraio 2009 da wer180m
mf2hd Inserita: 8 febbraio 2009 Segnala Inserita: 8 febbraio 2009 Se intendi un programma che simula il master ce ne sono di freeware, come questo:_http://www.modbus.pl/Modbus_Tester.htmlE' solo per modo binario, altrimenti ce ne sono anche altri commerciali o no.Dove? Se e' sul PC non e' un problema, esistono degli adattatori USB->RS232 fanno egregiamente il loro lavoro e non costano neanche tanto (10/12 Euro).Per testare delle apparecchiature e alcuni software ho realizzato solo "slave", ma non dovrebbe essere difficile convertire il software in "master": invece di fornire degli indici dovra' leggerli.Rispetto a quanto chiedi pero' ho seguito altre strade e tutto dipende da quante elaborazioni davono essere fatte dopo aver letto/fornito gli indici.In particolare:- Non ho usato l' uart interno ma due pin qualsiasi del micro.- Come core puo' andare bene qualsiasi PIC. Il primo che ho realizzato era con il 16F84, poi sono passato al 16F876 perche' mi servivano gli ADC.- Le routine modbus richiedono un bel po' di memoria programma.Ad esempio la versione con il PIC16F84 usato come slave per 3 indici a 2 byte ciascuno si prendeva circa 550 words di flash.C'e' da dire che per produrre alcuni indici ho usato dei pin come "finto ADC" per leggere un potenziometro con il trucchetto della carica/scarica condensatore e questo procedura si porta via molta istruzioni.- Quasi tutte le versioni usano un quarzo da 4MHz, tranne una con un 8MHz perche' non avevo piu' quarzi del primo tipo.- Tutto il programma e' scritto in basic (picbasic) e quindi dovrai convertirlo perche' di C conosco poco niente.E' probabile pero' che il compilatore per quest' ultimo tipo di linguaggio ti crei un codice piu' snello.- Il protocollo implementato e' molto spartano e non e' possibile leggere dallo slave piu' indici contemporaneamente con una sola richiesta.In pratica la risposta e' sempre di 8 byte, tranne il caso in qui il micro non riconosca la richiesta e allora risponde con 5byte simulando una "Illegal request" (funzione aumentata di 128).Per darti un' idea della complessita' dello slave ho recuperatoquesto schema che avevo fatto a suo tempo:Non ho trovato il codice relativo, forse e' in qualche backup.Come codice abbastanza commentato ho trovato questo per un PIC16F876, usa 3 indici per le funzioni "03" o "04", di cui uno fa capo al convertitore mentre le altre 2 forniscono solo dei valori fissi.Tengo precisare che deriva da parti di codice lette anni fa in un forum estero (mi pare francese), soprattutto la parte per il calcolo del CRC. '-----------------------------------' Protocollo modbus per PIC16F876A '-----------------------------------''Indirizzi EEPROM interna:'00= Indirizzo del dispositivo $01-$FF (1-255) '01= BaudRate: '19200 = 32 = $20'9600 = 84 = $54'4800 =188 = $BC''Gli altri valori per la comunicazione seriale sono fissi:'Parita' = nessuna'Dati= 8 bit 'Stop = 1 bit '----------------------------DEFINE OSC 4 ' clock a 4MHz'Variabili per parte seriale e ModBusCRC_Ok VAR BIT ' controllo del CRC : 0=OK, 1=ERRATOBRx_Ok VAR BIT ' controllo del buffer RXi VAR BYTE ' genericaj VAR BYTE ' genericaIndirizzo VAR BYTE 'Address del dispositivo BR VAR BYTE ' BaudRate della comunicazioneNbr VAR BYTE ' Numero di byte da ricevere/trasmettere CRCL VAR BYTE ' Byte Low CRCCRCH VAR BYTE ' Byte High CRCCRC16 VAR WORD ' Valore CRCBufRx VAR BYTE[8] 'Buffer RXBufTx VAR BYTE[8] 'Buffer TXRS485 VAR PORTB.0 ' Commutazione transciever RS485 0=RX 1=TXInOut VAR PORTB.1 ' Pin RX/TX su RS485Val_AD VAR BYTE 'Valore convertitore ADled VAR PORTB.7 'Led sur PORTB.7'resist var PORTB.6INCLUDE "modedefs.bas"EEPROM 0,[1,84] ' Imposta i valori di default in EEPROM ' Address=1 e BaudRate=9600 ' Per altri valori cambiarli nell'editor del programma ' utilizzato per caricare il micro (campo EEPROM) prima della ' scrittura. ' Inizializzazione al avvio (power on, reset)' ----- Inizio ----- Inizio:Low RS485 ' Porta RS485 in ricezioneFor i=0 to 7 'Inizializza i buffer RX e TX (tutti i byte=0)BufRx=0BufTx=0Next iRead 1,Indirizzo 'Legge da eeprom interna l' indirizzo dispositivoRead 2,BR 'Legge da eeprom interna la velocita' di comunicazioneGoTo Principale'----- Programma principale -----Principale:Nbr=8 ' imposta il numero di byte SerIn2 InOut,BR,5,Principale,[sTR BufRx\Nbr] 'legge 8 byte -> buffer RX' il timeout e' di 5 msec, se non riceve niente entro questo tempo torna alla' label "Principale". IF (BufRx[0]=Indirizzo) Then ' Verifica se l' indirizzo richiesto = dispositivo ' se il dispositivo e' questo For i=0 to 7 BufTx=BufRx 'copia nel buffer TX i byte del buffer RX Next i BRx_Ok=1 GoSub Calcolo_CRC16 ' passa alla calcolo del CRC16-modbus 'Verifica se il CRC calcolato corrisponde IF (CRC16.LowByte<>BufRx[6]) OR (CRC16.HighByte<>BufRx[7]) Then CRC_Ok=1 ' CRC = ERRATO!!! Else CRC_Ok=0 'CRC = CORRETTO 'high led EndIF 'Verifica se c'e' una richiesta di lettura (3 o 4) IF (BufRx[1]=3)OR (BufRx[1]=4) Then 'Err pas traité (BufRx[2]<>0) AND (BufRx[4]<>0) ' high led '------------------------- 'Valori di risposta (Dati) '------------------------- if bufrx[3]=1 then 'indice 40002 pot PORTB.6,50,VAl_AD nbr=7 BufTx[2]= 2 BufTx[3]= VAl_AD BufTx[4]= 0 goto invia endif if bufrx[3]=3 then 'indice 40004 nbr=7 BufTx[2]= 2 BufTx[3]= $22 BufTx[4]= $44 goto invia endif if bufrx[3]=5 then 'indice 40006 nbr=7 BufTx[2]= 2 BufTx[3]= $33 BufTx[4]= $55 goto invia endif '.....Inserire qui eventuali altri indici..... ' 40008 ' 40010 ' ... EndIF '----- Risposta di ERRORE ----- 'Viene fornita la risposta che il master interpreta come "ILLEGAL REQUEST" 'Formata da 5 byte totali:ADD,FNC,NBYTE,CRCL,CRCH 'La Function in richiesta viene trasmessa aumentata di 128 IF (BRx_Ok=1) Then 'Toute autre valeur de 'BufRx[1] #3,4,6 Nbr=5 ' BufTx[1]=BufRx[1]+128 BufTx[2]=1 EndIF'invia: IF (CRC_OK=0) Then 'Risposta CRC=OK'----- Trsmissione della risposta -----Invia: High RS485 'transciever RS485 in trasmissione GoSub Calcolo_CRC16 ' Calcola il CRC CRCL=Nbr-2 'CRCL = penultimo byte CRCH=Nbr-1 'CRCH = ultimo byte BufTx[CRCL]=CRC16.LowByte 'Prepara il CRC nel buffer BufTx[CRCH]=CRC16.HighByte SerOut2 InOut,BR,[sTR BufTx\Nbr] 'Trasmissione risposta 'High led 'Inzializza il buffer RX (byte=0) per cancellare ev. vecchi valori For i=0 to 7 BufRx=0 Next i Low RS485 ' Riporta in ricezione RS485 EndIFEndIFGoTo Principale ' Ripete la routine "Principale"'----- SubRoutine per il calcolo del CRC16 formato modbus -----'nota: viene effettuato solo sui byte del buffer TXCalcolo_CRC16:CRC16=$FFFF 'inizializza registroFor i=0 to Nbr-3 'ciclo di controllo sui byte escluso CRCCRC16=CRC16^BufTx ' xor For j=1 to 8 IF CRC16.Bit0=1 Then CRC16=$A001^(CRC16>>1) 'xor con $A001=polinomio dopo shift a dx di uno Else CRC16=CRC16>>1 'shift a dx di uno EndIF Next jNext iReturnEnd
wer180m Inserita: 8 febbraio 2009 Autore Segnala Inserita: 8 febbraio 2009 Grazie mf2hd sei stato molto molto gentile! Mi studio bene il tuo circuito e il tuo software...Ti volevo chiedere dato che hai già avuto esperienze, se il modo in cui vorrei muovermi col il software potrebbe andare bene dato che avevo iniziato ad abbozzarlo:1. Da master inviare questo comando:1h 03h 1000h 0003h CRC1h___________indirizzo di M7TIC/CM (Slave)03h__________comando di lettura1000h________primo registro di lettura0003h________lettura dei 3 registri contiguiCRC_________controllo errori2. Attesa. se non mi arriva risposta risposta rimando il comando,3. Altrimenti mi arriva la risposta in questo formato:1h 03h 0Ah VR VS VT CRC1h___________Indirizzo di M7TIC/CM (slave, mmi dice che è lui)03h__________Operazione effettuata0Ah__________numero di byte campo datiVR VS VT_____Dati che abbiamo chiesto, ovvero tensioni delle linee (come specificato in post numero 2)CRC__________controllo errori4.Controllo il crc, se è tutto ok mi prendo le mie 3 variabili VR VS e VT e me le gestisco via software.potrebbe andare?ah...grazie ancora per avermi dedicato il tuo tempo mf2hd
mf2hd Inserita: 10 febbraio 2009 Segnala Inserita: 10 febbraio 2009 Scusa se non ho risposto ma non ho avuto molto tempo per seguire il forum e tentare delle prove che volevo fare: un pic come master non l' ho mai usato. La sequenza del programma "master" la vedrei piu' o meno cosi' :- Preparazione della stringa di richiesta (address, funzione, indici, crc, ecc.). Nel caso la richiesta sia sempre la stessa puoi prepararla "fissa" e corretta, saltando la parte di controllo su questa (crc).- Interrogazione dello "slave", con un time out (es. 10msec) - Se non riceve niente dopo un po' di tentativi (es. 5) con timeout, significa che c'e' qualcosa che non va = errore di comunicazione.- C'e' risposta:. Verifica se CRC=OK. Verifica se la funzione e' la stessa di quella richiesta, se aumentata di 128d (80h)= richiesta illegale, ovvero stai tentando un' operazione di lettura che lo "slave" non conosce.. Se le verifiche sono OK passa all' estrazione dei byte che ti interessano.- Operazioni in base ai byte (misure) estratti : conversione, visualizza, comanda, ecc.- Ripeti il ciclo.Nota: Studiati bene come vengono gestite le chiamate al dispostivo slave nella documentazione del costruttore:La risposta potrebbe seguire anche altri formati, come ad esempio inserire, prima dei byte della misura, altri byte aggiuntivi per confermare che quella che segue e' valida.Cosi' come l' inversione dei byte (H>L o L>H).Da quello che ho capito le misure sono analogiche (tensioni?), se i byte forniti sono il valore in floating point e un po' complicato da fare con un PIC, almeno con quelli "piccoli". Appena trovo il tempo faccio delle prove con un PIC e un regolatore che usa questo protocollo.La cosa mi ha molto incuriosito, non mi servira' a niente... ma tanto per imparare qualcosa in piu'...
wer180m Inserita: 11 febbraio 2009 Autore Segnala Inserita: 11 febbraio 2009 (modificato) Mitico mf2hd!ti ho risposto anche nell'altra conversazione, ma se la cosa diventa pallosa per te dato che sto incasinando le cose, non vorrei affatto essere di disturbo, apprezzo molto l'aiuto che mi hai dato (e già a questo punto, direi che ti devo una birra )Ma adesso ho il dubbio: ma io li posso mandare in esadecimale i valori, oppure no per via dei bit di parità e di stop? (questa funzione la potrei prendere pure dalle librerie?)esempio:1h 03h 1000h 0003h CRCbit___bit___word____word_____crc01___03___10 00___00 03___bit bitche con i tempi sarebbe (t1>3,5; t2<1,5):t1 01 t2 03 t2 10 t2 00 t2 00 t2 03 t2 bit t2 bit t1La cosa è molto incasinata...ah mf2hd anche io lo faccio per imparare, questa periferica serve ad un mio amico che ha comprato queste 2 apparecchiature e solo dopo ha scoperto che non se ne poteva fare niente senza il master...Massimo Modificato: 11 febbraio 2009 da wer180m
wer180m Inserita: 11 febbraio 2009 Autore Segnala Inserita: 11 febbraio 2009 Ho trovato questo codice su un sito per leggere da un registro:Program modbus include crcDim RESULT as byte dim MACH96_TX_Buffer as byte[8] dim MACH96_RX_Buffer as byte[9] '============================================================================== 'REQUEST FROM MACH96'============================================================================== Sub procedure MACH96_Send MACH96_TX_Buffer[0]=$21 'address MACH96_TX_Buffer[1]=$03 'This function reads one or more memory adjacent locations, MACH96_TX_Buffer[2]=$00 'data start register High MACH96_TX_Buffer[3]=$69 'data start register Low MACH96_TX_Buffer[4]=$00 'data of # High MACH96_TX_Buffer[5]=$02 'data of # Low '-------------------------------------------------------------------------------- CRC_TX(MACH96_TX_Buffer,MACH96_TX_Buffer[6], MACH96_TX_Buffer[7]) '-------------------------------------------------------------------------------- Setbit(Portc,2) 'RS485 CHIP TX MODE Usart_write(MACH96_TX_Buffer[0]) Usart_write(MACH96_TX_Buffer[1]) Usart_write(MACH96_TX_Buffer[2]) Usart_write(MACH96_TX_Buffer[3]) Usart_write(MACH96_TX_Buffer[4]) Usart_write(MACH96_TX_Buffer[5]) Usart_write(MACH96_TX_Buffer[6]) Usart_write(MACH96_TX_Buffer[7]) Clearbit(Portc,2) End Sub main: TRISC = %00111011 TRISD = %00000000 PORTD = 0 PortC.2 = 0 '============================================================================== 'USART INIT '==============================================================================USART_INIT(9600) while true result = RCREG ' read value off top of RX register stack If Testbit(RCSTA, 1) = 1 Then ' if there was an overrun error on the stack RCSTA.4 = 0 ' clear continuous receive RCSTA.4 = 1 ' reset continuous receive End If ' overrun error is now cleared MACH96_Send '======================================================================== 'REPLY FROM MACH96 '======================================================================== i=0 while i < 10 If Usart_Data_Ready = 1 then MACH96_RX_Buffer[i-1]=usart_read Inc(i) end if wend '======================================================================= End. e per il crc: Module CRC dim i,j as short dim acc,tmp as word Sub procedure CRC_TX(Dim byref data as byte[6],Dim BYREF C1 as byte, Dim BYREF C2 as byte) acc=$FFFF for i = 0 to 5 acc=acc Xor data for j = 1 to 8 tmp = acc and $0001 acc = acc >> 1 if tmp = 1 then acc = acc Xor $A001 end if next j next i C1 = acc and $FF C2 = word((acc and $FF00) >> 8 ) end sub Sub procedure CRC_RX(Dim byref data as byte[7],Dim BYREF C1 as byte, Dim BYREF C2 as byte) acc=$FFFF for i = 0 to 6 acc=acc Xor data for j = 1 to 8 tmp = acc and $0001 acc = acc >> 1 if tmp = 1 then acc = acc Xor $A001 end if next j next i C1 = acc and $FF C2 = word((acc and $FF00) >> 8 ) end sub end. Ma io con il basic non ci vado molto daccordo e non riesco a capire la parte sulla risposta dallo slave , più tardi studierò bene il codice, adesso per me è ora di andare a dormire...
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora