Hallo, Ik wil meerdere pic 16f628 aan mijn rs485 (pc) interfacekaart koppelen.
Wil de SN75176 gebruiken.
Wie kan mij wat op weg helpen?
Kan ik de sourcecode (asm) van bv een rs232 programma gebruiken?
En de Max232 vervangen door een SN75176.
Data moet bidirectioneel zijn.
Heb al wat over DMX gevonden maar deze leest geen data uit de pic, alleen schrijven.
Wil van dit (dmx) schema uitgaan, wat moet ik aanpassen voor data lezen uit 16f628?
thanks voor jullie hulp.
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Bij RS485 is geen protocol vastgelegd, enkel de manier waarop je bits en bytes over en weer kan gooien. Dus je zal zelf een protocol moeten opstellen.
Doorgaans komt het neer op het volgende (elk [] is een byte):
[Adres][eventueel lengte van het pakket][instructie][eventueel data]
Adres is duidelijk, zodat geweten is tegen wie gesproken wordt (doorgaans wordt 0 genomen als broadcast, waar ze allemaal op reageren, voor een algemene reset bijvoorbeeld). Door de lengte van het pakket mee te geven, maak je het gemakkelijker om te ontvangen (en voorkom je dat de data als adres opgevangen wordt door andere module's). Instructie's lijkt me duidelijk, bijvoorbeeld de ASCII code voor "R" als reset, "V" om een spanning in te stellen,...
Je zal dus voor jezelf ff een boomstructuurtje moeten maken, vanuit het adres, wat dan kan volgen, en zo volledig opensplitsen. Alles wat daarbuiten valt, moeten je PIC's niet op reageren (en gewoon klaarstaan voor volgende communicatie), anders kunnen storingen je spel doen vastlopen, das niet de bedoeling. Maak het zo gek je maar wil.
Het gemakkelijkste is het ook als je de PC als master gebruikt, en de PIC's slave laat zijn, dus er enkel door de PIC's iets verzonden wordt wanneer dit aangevraagd werd door de PC. Dan kan je geen collision's enzo krijgen.
Voor het verzenden/ontvangen gebruik je gewoon de USART, exact hetzelfde als wanneer er via seriële poort zou gecommuniceerd worden, maar dan met ipv een MAX232-achtige een MAX489-achtige.
Op 7 september 2006 11:55:33 schreef Videomodulator:
Voor het verzenden/ontvangen gebruik je gewoon de USART, exact hetzelfde als wanneer er via seriële poort zou gecommuniceerd worden, maar dan met ipv een MAX232-achtige een MAX489-achtige.
Ok mooi, in mijn pc zit een rs485 kaart welke ik als master gebruik, gebruik gewone rs232 routines.
Werkt prima. Dus het komt er op neer dat "gewoon" een pic rs232 project als voorbeeld zou kunnen gebruiken?
Alleen de Max232 vervangen door een max489-achtige? De pic's worden slave ja. Ik neem dus bv 2 of meer pics met een rs232/485 asm programma dat continu de rs485 line leest. De data bepaalt of het voor de juiste pic is?
Zeg adres [01] is voor pic 1 en zal dus reageren? Dit bouw ik in mijn source?
Ik ga eens wat uitwerken. thanks en gr
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Op 7 september 2006 13:31:22 schreef Descartes:
[...]
Ok mooi, in mijn pc zit een rs485 kaart welke ik als master gebruik, gebruik gewone rs232 routines.
Werkt prima. Dus het komt er op neer dat "gewoon" een pic rs232 project als voorbeeld zou kunnen gebruiken?
Alleen de Max232 vervangen door een max489-achtige? De pic's worden slave ja. Ik neem dus bv 2 of meer pics met een rs232/485 asm programma dat continu de rs485 line leest. De data bepaalt of het voor de juiste pic is?
Zeg adres [01] is voor pic 1 en zal dus reageren? Dit bouw ik in mijn source?Ik ga eens wat uitwerken. thanks en gr
Inderdaad, zo werkt het. Continu de RS485 line lezen is niet nodig, doordat je de USART gebruikt zit er een buffer van 2 byte's op, je hebt wat tijd om tussenin iets anders te doen.
Kan iemand mij een beetje verder helpen met het aansluiten van de Max489
overige pinnen en of naar de RS485 aan de pc kant?
thanks...
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Ik heb voor mijn eindwerk dit schema gebruikt:
Andere schema's kan je a volonté vinden met de search of met google.
sven
pointers don't kill programs, programmers kill programs
het enige wat je moet aanpassen:
De DE & /RE bepalen of je 485-transceiver in ontvangst of zend-mode staat. Je hebt dus een extra output nodig op je PIC, dewelke je schakelt wanneer je een transmit doet. De /RE is dan hoog en de DE hoog.
Als je /RE laag is (Receive Enable invers) ontvang je data, dus zo met deze staan als je PIC niets moet antwoorden
Prima, ik kan nu verder.
Kon trouwens weinig vinden (schema's)over max489.
Maar ik denk dat het nu moet lukken.
Morgen de ic's halen.
thanks en gr.
Op 7 september 2006 18:07:13 schreef sven:
het enige wat je moet aanpassen:De DE & /RE bepalen of je 485-transceiver in ontvangst of zend-mode staat. Je hebt dus een extra output nodig op je PIC, dewelke je schakelt wanneer je een transmit doet. De /RE is dan hoog en de DE hoog.
Als je /RE laag is (Receive Enable invers) ontvang je data, dus zo met deze staan als je PIC niets moet antwoorden
Ok, vraagje. A en Y aan elkaar, B en Z ook en deze naar de PC RS485 Master? RE en DE worden gestuurd door de PIC.
De Master in de PC stuurd/ontvangt dus alleen data en gebruikt deze RE en DE niet?
bedankt en gr
sven
pointers don't kill programs, programmers kill programs
ik ken je interface kaart in de PC niet, maar deze schakelt waarschijnlijk automatisch om (zonder dat je er zelf iets voor moet doen)
Waarom gebruik je trouwens geen MAX485 ? Deze is gemaakt voor RS485, die MAX489 lijkt gemaakt te zijn voor RS422. Dit zal waarschijnlijk wel werken zoals jij hebt aangesloten, maar is niet nodig. MAX485 is simpeler. En daarvan vind je waarschijnlijk hopen schema's
Op 7 september 2006 20:21:42 schreef sven:
ik ken je interface kaart in de PC niet, maar deze schakelt waarschijnlijk automatisch om (zonder dat je er zelf iets voor moet doen)
Waarom gebruik je trouwens geen MAX485 ? Deze is gemaakt voor RS485, die MAX489 lijkt gemaakt te zijn voor RS422. Dit zal waarschijnlijk wel werken zoals jij hebt aangesloten, maar is niet nodig. MAX485 is simpeler. En daarvan vind je waarschijnlijk hopen schema's
Dan zou het zo moeten werken?
[edit] Iemand wel eens een stukje asm source tegen gekomen om van de pic een RS485 slave te maken?
Heel de nacht zitten googele, maar nog niet echt wat gevonden. Veel rs232 maar dit gaat net ff anders denk ik?
gr...
[Bericht gewijzigd door Descartes op ]
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Op dat pinnetje na (dat schakelt tussen zenden en ontvangen) is er geen verschil tussen RS232 en RS485 voor je µC, als je als slave werkt. Al wat je moet doen is de convertor (MAX485) op ontvangen zetten, en regelmatig checken of er nog geen data toegekomen is. Eenmaal toegekomen, moet je ze ontvangen en overeenkomstige actie's ondernemen (adres checken,...). Als je hierbij toestemming krijgt om iets te verzenden, zet je de max op verzenden, verzend je je data en zet em daarna weer op ontvangen.
Verder: neem een groot blad papier, en schrijf uit wat je wil heen en weer kunnen verzenden. Stel er een protocol voor op (volgorde van de byte's, eerst adres, dan......).
Voor het testen begin je met adres en een byte, die byte zet je gewoon op een uitgangspoort. Zenden met juiste adres (neem een adres dat in de ASCII tabel een gemakkelijk teken heeft, bijvoorbeeld 'A', die kan je gewoon in hyperterminal invullen) moet de uitgangspoort instellen met de 2e byte. Als dit werkt, ben je vertrokken toch?
Ik heb nog een lap code, mss ben je er iets mee:
mainlus
banksel RCSTA
bsf RCSTA,CREN ; constant receiven
banksel PIR1
btfsc PIR1,RCIF ; staat er een ontvangen byte klaar?
goto receive ; dan er iets mee doen
goto mainlus
receive
movlw .79 ;ASCII voor O
movwf S2
movlw .75 ;ASCII voor K
movwf S3
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .76 ; ASCII voor L(lengte)
subwf a,w ;ontvangen byte = gewenste byte?
btfss STATUS,Z
goto mainlus ; dan error en reset
lengtebyte
usart ; de volgende byte ontvangen, en deze in w en a steken
movwf L ; opslaan als lengte van de string.
decf L,f ;er zijn al
decfsz L,f ; 2 bytes aangekomen.
goto adreschar
adreschar
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .65 ; ASCII voor A(adres)
subwf a,w ;ontvangen byte = gewenste byte?
btfss STATUS,Z
goto mainlus
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
;adresbyte
usart ; de volgende byte ontvangen, en deze in w en a steken
movfw a
btfsc STATUS,Z
goto broadcast
subwf adres,w ; mijn adres?
btfss STATUS,Z
goto mainlus
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
;channel, reset, relais of xtra I2C connector
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .63 ; ASCII voor ?(welke channels aanwezig?)
subwf a,w ;ontvangen byte = gewenste byte?
btfss STATUS,Z
goto $+3
bsf adres,7 ; bitje zetten
goto niereset ;uitvoeren
movlw .82 ; ASCII voor R(reset)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto reset ;uitvoeren
movlw .83 ; ASCII voor S(set relais)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto relay ;uitvoeren
movlw .73 ; ASCII voor I(xtra I²C connector)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto I2C ;uitvoeren
movlw .82 ; ASCII voor C(channel)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto channel ;uitvoeren
goto receivedone
channel
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
usart ; de volgende byte ontvangen, en deze in w en a steken
; het kanaal juist instellen, voor de rest van de communicatie
bcf PORTA,C0 ; 4 bits goed zetten om naar analoogprint te
btfsc a,C0 ; controleren op reactie
bsf PORTA,C0
bcf PORTA,C1 ; 4 bits goed zetten om naar analoogprint te
btfsc a,C1 ; controleren op reactie
bsf PORTA,C1
bcf PORTA,C2 ; 4 bits goed zetten om naar analoogprint te
btfsc a,C2 ; controleren op reactie
bsf PORTA,C2
bcf PORTA,C3 ; 4 bits goed zetten om naar analoogprint te
btfsc a,C3 ; controleren op reactie
bsf PORTA,C3
;/
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .85 ; ASCII voor U(spanning)
subwf a,w ;ontvangen byte = gewenste byte?
btfss STATUS,Z
goto spanning ;uitvoeren
movlw .82 ; ASCII voor R(reset)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto resetsub ;uitvoeren
movlw .73 ; ASCII voor I(stroom)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto stroom ;uitvoeren
movlw .80 ; ASCII voor P(PWM vragen)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto PWM ;uitvoeren
movlw .68 ; ASCII voor D(DiSEqC)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto diseqc ;uitvoeren
movlw .84 ; ASCII voor T(Toon)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto toon ;uitvoeren
goto receivedone
spanning
movlw .85 ;ASCI voor U
movwf S2 ;instellen voor verzenden
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .63 ; ASCII voor ?(spanning meten)
subwf a,w ;ontvangen byte = gewenste byte?
btfss STATUS,Z
goto Umeet ;uitvoeren
movlw .83 ; ASCII voor S(set)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto Uset ;uitvoeren
goto receivedone
Umeet
movlw .2
movwf I2C0
LOAD_ADDR_8 .2 ;8bits adres van analoogprint inladen.
I2C_WR .1,I2C0 ; 1 byte zenden, vanaf i2c0
banksel PORTB
btfsc _Txmt_Success ; gelukt?
goto errd ; niet gelukt: error zenden
LOAD_ADDR_8 .2 ;8bits adres van analoogprint inladen.
I2C_READ2 .2,I2C0
movfw I2C1
movwf S3
goto send
Uset
movlw .7 ;instructie voor instellen
movwf I2C0
goto Idatasend
Udatasend
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
usart ; de volgende byte ontvangen, en deze in w en a steken
movwf I2C1
I2C_WR .2,I2C0 ; 2 bytes zenden, vanaf i2c0
banksel PORTB
btfss _Txmt_Success ; gelukt?
goto receivedone
goto errd
stroom
movlw .73 ;ASCI voor I
movwf S2 ;instellen voor verzenden
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .63 ; ASCII voor ?(stroom meten)
subwf a,w ;ontvangen byte = gewenste byte?
btfss STATUS,Z
goto Imeet ;uitvoeren
movlw .76 ; ASCII voor L(limiet instellen)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto Ilim ;uitvoeren
movlw .83 ; ASCII voor S(set)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto Iset ;uitvoeren
goto receivedone
Imeet
movlw .1
movwf I2C0
LOAD_ADDR_8 .2 ;8bits adres van analoogprint inladen.
I2C_WR .1,I2C0 ; 2 bytes zenden, vanaf i2c0
banksel PORTB
btfsc _Txmt_Success ; gelukt?
goto errd ; niet gelukt: error zenden
LOAD_ADDR_8 .2 ;8bits adres van analoogprint inladen.
I2C_READ2 .2,I2C0
movfw I2C1
movwf S3
goto send
Iset
movlw .6 ;instructie voor instellen
movwf I2C0
goto Idatasend
Ilim
movlw .8 ;instructie voor limiet
movwf I2C0
Idatasend
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
usart ; de volgende byte ontvangen, en deze in w en a steken
movwf I2C1
I2C_WR .2,I2C0 ; 2 bytes zenden, vanaf i2c0
banksel PORTB
btfss _Txmt_Success ; gelukt?
goto receivedone
errd
movlw .69 ; asci voor E(error)
movwf S2
movlw .68 ; asci voor D(comm met Diseqcmodule)
movwf S3
goto send
resetsub
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
PWM
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
diseqc
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
toon
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
I2C
usart ; de volgende byte ontvangen, en deze in w en a steken
LOAD_ADDR_8 a ;8bits adres van analoogprint inladen.
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivefout
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .87 ; ASCII voor W(write)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto write
movlw .82 ; ASCII voor R(read)
subwf a,w ;ontvangen byte = gewenste byte?
btfsc STATUS,Z
goto read
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivefout
write
call TxmtStartBit
bcf _Slave_RW ;write
call Txmt_Slave_Addr ;gelukt, dan is bit _Txmt_Succes '1'
btfsc _Txmt_Success
goto $+6
movlw .69 ;ASCII voor E (error)
movwf S2
movlw .65 ;ASCII voor A (ack I²C)
movwf S3
goto send
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
;nu begint de data aan te komen, lusje maken
writelus
usart ; de volgende byte ontvangen, en deze in w en a steken
movwf DataByte
I2C_WR .1,I2C0
read
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
INVULLEN
broadcast
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .82 ; ASCII voor R(reset)
subwf a,w ;ontvangen byte = gewenste byte?
btfss STATUS,Z
goto receivefout ; dan error en reset
reset
call anyone_thereset
niereset
call anyone_there
movfw aanwezig1 ;eventueel antwoord klaarzetten
movwf S2
movfw aanwezig0 ;eventueel antwoord klaarzetten
movwf S3
btfss adres,7
goto $+3
bcf adres,7
goto send
decfsz L,f ; aantal bytes ontvangen?
goto $+2 ;volgende overslaan
goto receivedone
;wordt een antwoord gevraagd op broadcast???
usart ; de volgende byte ontvangen, en deze in w en a steken
movlw .63 ; ASCII voor ?(antwoorden aub)
subwf a,w ;ontvangen byte = gewenste byte?
btfss STATUS,Z
goto receivefout ; dan error en reset
goto send
; decfsz L,f ; aantal bytes ontvangen?
; goto $+2 ;volgende overslaan
goto receivedone
receivedone
goto send
goto mainlus[Bericht gewijzigd door Videomodulator op ]
Op 8 september 2006 10:02:55 schreef Videomodulator:
Op dat pinnetje na (dat schakelt tussen zenden en ontvangen) is er geen verschil tussen RS232 en RS485 voor je µC, als je als slave werkt. Al wat je moet doen is de convertor (MAX485) op ontvangen zetten, en regelmatig checken of er nog geen data toegekomen is. Eenmaal toegekomen, moet je ze ontvangen en overeenkomstige actie's ondernemen (adres checken,...). Als je hierbij toestemming krijgt om iets te verzenden, zet je de max op verzenden, verzend je je data en zet em daarna weer op ontvangen.Verder: neem een groot blad papier, en schrijf uit wat je wil heen en weer kunnen verzenden. Stel er een protocol voor op (volgorde van de byte's, eerst adres, dan......).
Voor het testen begin je met adres en een byte, die byte zet je gewoon op een uitgangspoort. Zenden met juiste adres (neem een adres dat in de ASCII tabel een gemakkelijk teken heeft, bijvoorbeeld 'A', die kan je gewoon in hyperterminal invullen) moet de uitgangspoort instellen met de 2e byte. Als dit werkt, ben je vertrokken toch?
Bedankt, ik zit dus op de goede weg.
Ga het protocol op papier uitwerken.
bv 3 bytes: [device-adress][command][data].
Ga je voorbeeld code uitprinten en bestuderen.
gr.
sven
pointers don't kill programs, programmers kill programs
Op 8 september 2006 03:12:02 schreef Descartes:
[...]Dan zou het zo moeten werken?
[edit] Iemand wel eens een stukje asm source tegen gekomen om van de pic een RS485 slave te maken?
Heel de nacht zitten googele, maar nog niet echt wat gevonden. Veel rs232 maar dit gaat net ff anders denk ik?gr...
enkele aanvullingen op de post van videomodulator
Dat moet wel werk denk ik. Pin 2&3 van de MAX485 mag je aan mekaar knopen, zo heb je maar 1 pin op je PIC nodig. Laag is ontvangen, hoog zenden.
Dus in het begin van je zend-sub zet de pin hoog, erna terug laag.
ook niet te snel reageren, als je data hebt ontvangen niet onmiddelijk data terugsturen, je moet even wachten, ik dacht ongeveer de tijd dewelke je normaal nodig zou hebben om 28bits te verzenden. Als je dit niet doet kan het zijn dat je "master" nog niet volledig is omgeschakeld van zenden naar ontvangen. Heb dit ooit eens gelezen in een profibus-beschrijving (=RS485) en zelf uitgetest. zonder die delay kan je de eerste bits kwijtspelen
edit: m'n testverslag gevonden:
volgens profibus moet er tussen ontvangen en zenden een pauze zijn van 33bits:
getest bij 19200 is dit goed (delay van 1,72msec)
delay van 1msec is acceptabel maar geeft fouten
getest bij 9600 ook goed (delay van 3,44msec)
--> 33 bits pauze is een goede minimum richtlijn!!
[Bericht gewijzigd door sven op ]
Op 8 september 2006 16:43:53 schreef sven:
[...]
enkele aanvullingen op de post van videomodulatorDat moet wel werk denk ik. Pin 2&3 van de MAX485 mag je aan mekaar knopen, zo heb je maar 1 pin op je PIC nodig. Laag is ontvangen, hoog zenden.
Dus in het begin van je zend-sub zet de pin hoog, erna terug laag.ook niet te snel reageren, als je data hebt ontvangen niet onmiddelijk data terugsturen, je moet even wachten, ik dacht ongeveer de tijd dewelke je normaal nodig zou hebben om 28bits te verzenden. Als je dit niet doet kan het zijn dat je "master" nog niet volledig is omgeschakeld van zenden naar ontvangen. Heb dit ooit eens gelezen in een profibus-beschrijving (=RS485) en zelf uitgetest. zonder die delay kan je de eerste bits kwijtspelen
edit: m'n testverslag gevonden:
volgens profibus moet er tussen ontvangen en zenden een pauze zijn van 33bits:
getest bij 19200 is dit goed (delay van 1,72msec)
delay van 1msec is acceptabel maar geeft fouten
getest bij 9600 ook goed (delay van 3,44msec)
--> 33 bits pauze is een goede minimum richtlijn!!
Oke sven, aangepast pin 2 en 3.
Ga nu aan de code werken.
Zal de delay inbouwen.
ps: heb net de nieuwe (Sep) elektuur gekocht, staat stukje over usb/dmx in. Ga eens kijken naar de de (asm) code.
Zij gebruiken de DS75176BM met de pic 16C745.
thanks en gr.
sven
pointers don't kill programs, programmers kill programs
euhm, nog 1 opmerking, maar wist je misschien zelf: Die Rt hoort alleen maar op het begin en op het einde van de bus thuis
Op 8 september 2006 19:08:44 schreef sven:
euhm, nog 1 opmerking, maar wist je misschien zelf: Die Rt hoort alleen maar op het begin en op het einde van de bus thuis
Klopt ja, is de afsluitweerstand.
Zal hem weghalen, staat vreemd.
gr..
Ik ben wat (pic asm) code aan het aanpassen voor mijn rs485/16f628 interface. de (test)basiscode was voor een 16f877.
Wie zou er (als je wat tijd en zin hebt
) eens naar kunnen kijken?
Shema:
en de code:
http://home.hetnet.nl/~descartes/slave01.txt
of:
;*****************************************************************************
;
; Module: slave01.asm
;
; Version: 1.0 22/01/06
; 1.1 08-09-2006 modify for 16F628
;
;*****************************************************************************
;
; The circuit used is based on a PIC 16F628 running at 4.0 MHz
;
; PortB.0 is an output for enabling the RS485 transmitter
; PortB.1 is configured as the async serial output on the bus
; PortB.2 is configured as the async serial input on the bus
; PortB.3 is an output to drive a status LED, LED0
; PortB.4 is an output to drive a status LED, LED1
; PortA.0 is an input
list p=16f628, st=OFF, x=OFF, n=0
errorlevel -302
errorlevel -306
#include <p16f628.inc>
__config 0x3f32
; Define variable definitions and general constants
;-------------------------------------------------------------------------
XTAL_FREQ EQU D'4000000' ; The frequency of our crystal
BAUD_19200 EQU (XTAL_FREQ/(D'16' * D'19200')) + 1
BAUD_CONSTANT EQU BAUD_19200 ; The speed we will actually run at
TIMER1_1MS_VAL EQU 0xFFFF - (XTAL_FREQ/(8 * 4 * D'1000'))
MASTER_ADDRESS EQU 0x01 ; RS485 address (when slave addresses master)
SLAVE_1_ADDRESS EQU 0x02 ; RS485 address
SLAVE_2_ADDRESS EQU 0x03 ; RS485 address
SLAVE_1_LED_BIT EQU 0 ; PORTB.0 is LED for SLAVE_1
SLAVE_2_LED_BIT EQU 4 ; PORTB.1 is LED for SLAVE_1
TX_ENABLE_BIT EQU 3 ; PORTB.3 is tx enable control
; The following are a list of 'commands' supported by the link
; As this is a demonstration of how to use the system, we only implement
; a single command, READ_DATA_COMMAND, to read a slaves port
READ_DATA_COMMAND EQU 0x01
SLAVE_READ_TIMEOUT EQU D'100' ; Allow up to 100ms for a response
; Bank 0 RAM
sPORTA EQU 0x20 ; Shadow of PORTB output register
sPORTB EQU 0x21 ; Shadow of PORTC output register
deviceReadOK EQU 0x22 ; return status from getSlaveData
deviceData EQU 0x23 ; return value from getSlaveData
timer1msCount EQU 0x24 ; The applications 1ms resolution timer
delay1 EQU 0x25 ; delay routine use only.
PCLATH_TEMP EQU 0x7d ; Exists in all banks
STATUS_TEMP EQU 0x7e ; Exists in all banks
W_TEMP EQU 0x7f ; Exists in all banks
; DEFINE THE SLAVE ADDRESS HERE
SLAVE_ADDRESS EQU SLAVE_2_ADDRESS
;-----------------------------------------------------------------------------
;*****************************************************************************
;
; Function : Reset vector
; Hardware entry point to the code
; When the processor powers up, this is always the first
; location executed.
;
; Input: None.
;
; Output: N/A
;
;*****************************************************************************
ORG 0
RESET GOTO Main
;*****************************************************************************
;
; Function : Interrupt vector
; Hardware entry point for interrupts
; This address, location 4, is the address that is called when
; an interrupt occurs.
; You do of course have to enable interrupts if you want this
; routine to be executed.
;
; Input: None.
;
; Output: None.
;
;*****************************************************************************
ORG 4
INTERRUPT
movwf W_TEMP
swapf STATUS, W
clrf STATUS
movwf STATUS_TEMP
movfw PCLATH
movwf PCLATH_TEMP
clrf PCLATH
; A timer interrupt occurred. Update the timer value
movlw LOW TIMER1_1MS_VAL
movwf TMR1L
movlw HIGH TIMER1_1MS_VAL
movwf TMR1H ; Restart the timer
; If the application timer has not expired ( reached 0 ) then decrement it
movfw timer1msCount
btfss STATUS, Z
decf timer1msCount, F
bcf PIR1, TMR1IF ; Must clear interrupt flag
movfw PCLATH_TEMP
movwf PCLATH
swapf STATUS_TEMP, W
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP, W
retfie
;*****************************************************************************
;
; Function : initHardware
; This function configures the initial hardware features of the
; processor. To be more specific it changes only the features that
; have not already been configured by the power on reset.
;
;*****************************************************************************
initHardware
; The status of RAM following a reset is undefined.
; So set them to a known value.
movlw 0x20
movwf FSR
clrMem
clrf INDF
incf FSR, F
btfss FSR, 7 ; Have we reached 0x80?
goto clrMem ; - No, so continue with clear
clrf sPORTA ; Shadow value of PORTA output settings
clrf sPORTB ; Shadow value of PORTB output settings
; Port A 0..3 are input 4..7 unused so set to outputs, low level
bsf STATUS, RP0
movlw b'00001111'
clrf TRISA
bcf STATUS, RP0
; Port B: RB0 output for status LED's
; RB.1 is an input
; Initial state of status LED's is off.
; The rest are unused, so set to outputs
bsf STATUS, RP0
movlw b'00000010'
movwf TRISB
bcf OPTION_REG, NOT_RBPU
bcf STATUS, RP0
; Configure the Async serial port:
; 9 bit data ( 9th bit is used to indicate an address byte )
bsf STATUS, RP0
movlw BAUD_CONSTANT ;set baud rate
movwf SPBRG
bsf TXSTA, BRGH ;baud rate high speed option
bsf TXSTA, TX9 ; 9 bit data transfer
bsf TXSTA, TXEN ;enable transmission
bcf STATUS,RP0
bsf RCSTA, CREN ;enable reception
bsf RCSTA, RX9
bsf RCSTA, SPEN ;enable serial port
; Configure timer1 to give us a 1ms tick interval
movlw 0x35 ; Timer on, int clock, 1:8 prescale
movwf T1CON
bsf STATUS, RP0
bsf PIE1, TMR1IE
bcf STATUS, RP0
; Enable global interrupts, so that the timer
; interrupt routine will get called
clrf INTCON
bsf INTCON, PEIE
bsf INTCON, GIE
return
;*****************************************************************************
;
; Function : uiWait10ms
; delays for a multiple of 10ms
;
; Input: multiple in W
;
;*****************************************************************************
uiWait10ms
movwf delay1
uiw000
; Load the interrupt routines timer for 10ms
movlw D'10'
movwf timer1msCount
uiw001
; Keep reading the timer value, and quit
; when it has reached zero.
movfw timer1msCount
btfss STATUS, Z
goto uiw001
decfsz delay1, F
goto uiw000
return
;*****************************************************************************
;
; Function : handleMessages
; Waits for an incoming message from the master, and if it is
; 'READ_DATA_COMMAND', return a message with the data in it.
;
; Input: None
;
; Output: None, although a message may have been sent.
;
;*****************************************************************************
handleMessages
btfss PIR1,RCIF ; check if data received interrupt from usart
goto handleMessages ; wait until new data
; Is the byte an address?
btfsc RCSTA, RX9D
goto hm001 ; Yes, so go get it
; No, so read the byte and go back to waiting for an address
movfw RCREG
goto handleMessages
hm001
; Is the address byte addressing us?
movfw RCREG
sublw SLAVE_ADDRESS
btfss STATUS,Z
goto handleMessages ; No, so loop back waiting
; now we wait for the command byte
hm002
btfss PIR1,RCIF ; check if data received
goto hm002 ; wait until new data
; Is the byte a data byte?
btfss RCSTA, RX9D
goto hm003 ; Yes, so go get it
; no, so read it and loop back to beginning
; This is some kind of protocol error
movfw RCREG
goto handleMessages
hm003
; Is the data byte a supported command?
movfw RCREG
sublw READ_DATA_COMMAND
btfss STATUS, Z
goto handleMessages ; Not acommand, so ignore it
; Handle the message
; get the status of the input pin
clrf deviceData
btfsc PORTB,1
incf deviceData, F
; Wait for 2ms to allow the master to return to receive mode
movlw D'2'
movwf timer1msCount
movfw timer1msCount
btfss STATUS, Z
goto $-2
call RS485TXEnabled
; Send response to the Master
btfss PIR1,TXIF ;check that buffer is empty
goto $-1
bsf STATUS, RP0
bsf TXSTA, TX9D
bcf STATUS, RP0
movlw MASTER_ADDRESS
movwf TXREG
; Send out the portvalue data byte (ie, clear the 9th bit)
btfss PIR1,TXIF ;check that buffer is empty
goto $-1
bsf STATUS, RP0
bcf TXSTA, TX9D
bcf STATUS, RP0
movfw deviceData
movwf TXREG
; Wait for 2ms to allow data to be sent
movlw D'2'
movwf timer1msCount
movfw timer1msCount
btfss STATUS, Z
goto $-2
call RS485TXDisabled
return
;*****************************************************************************
;
; Function : Various LED control function.
; These function are used to turn the status leds on or off
; Although they have a very simple job, they have been given
; their own functions to make the code easier to read.
;
; Input: None
;
; Output: LED changed; PORTB shadow variable sPORTB updated
;
;*****************************************************************************
slave1LEDOff
bcf sPORTB, SLAVE_1_LED_BIT
movfw sPORTB
movwf PORTB
return
slave1LEDOn
bsf sPORTB, SLAVE_1_LED_BIT
movfw sPORTB
movwf PORTB
return
;*****************************************************************************
;
; Function : RS485TXEnabled, RS485TXDisabled
; These functions are used to turn the RS485 transmitter in the
; interface IC on or off.
; Although they have a very simple job, they have been given
; their own functions to make the code easier to read.
;
; Input: None
;
; Output: Transmitter driver enabled or disabled
; PORTB shadow variable sPORTB updated
;
;*****************************************************************************
RS485TXEnabled
bsf sPORTB, TX_ENABLE_BIT
movfw sPORTB
movwf PORTB
return
RS485TXDisabled
bcf sPORTB, TX_ENABLE_BIT
movfw sPORTB
movwf PORTB
return
;*****************************************************************************
;
; Function : Main
; Main application loop
;
; Input: None.
;
; Output: N/A
;
;*****************************************************************************
Main
clrf STATUS ; Select bank 0
clrf INTCON ; No interrupts enabled, at start-up
clrf PCLATH ; Our code starts in first bank
call initHardware
; light the leds during startup,
; to show the thing works
call slave1LEDOn
; time 1 seconds for the LED's to stay on.
movlw D'100'
call uiWait10ms
; Leds off
call slave1LEDOff
; Run the test continuously
mainloop
call handleMessages
; toggle the LED just to give some feedback that
; something is happening
call slave1LEDOn
call slave1LEDOff
goto mainloop
END ; End of program
Ik heb de ic's nog niet in huis dus kan het nog niet testen.
Maar misschien ziet iemand al grove fouten of wel kleine foutjes?
al vast bedankt.
ps: moderator, is de lange code tekst hinderlijk?
haal ik het weg.
Dear Friends ; ? need dmx512 sender/transmmitter Code .how can i send dmx data to first 4 channel ? i use 16f628A and sn75176A. i have dmx512 receiver card and i want to make master interface for dmx data send i want to send data to receiver ,for example if i want to send data like this to dmx channels
1 chan = 120
2 chan = 160
3 chan = 200
4 chan = 230
How can i send it is there any example dmx data sender code ?
Jordi
Bier zonder alcohol is als een beha aan een waslijn: het beste is er uit!
Topic hyjacking isn't quite polite
[Bericht gewijzigd door Jordi op (11%)]