Pic modbus rtu hazır kod, Fultek'den

fultek_salih

Fultek Temsilcisi
Katılım
2 Nis 2008
Mesajlar
315
Puanları
8
Yaş
48
Umarım işinize yarar. Bu code ile hatasız ve son derece hızlı haberleşme sağlayabilirsiniz. Modbus software ürünlerimizle yaptığımız testlerde pic 20 mhz’de saniyede 30 bilgi hatasız olarak alınabiliyor. Programınızı start bloğuna yazın. Bu code 50 registers (100 byt)’lık bir data alanındaki tüm verileri okuyup yazmanız için geliştirildi.Pic 18f452’nin seri portunu kullanarak RS232 ve RS485 olarak çalışabilir.

device 18f452
XTAL = 20
DEFINE LOADER_USED 1
ADCON1 = 7
DECLARE ADIN_RES 10
DECLARE ADIN_TAD FRC
DECLARE ADIN_STIME 50
DECLARE HSERIAL_RCSTA = %10010000
DECLARE HSERIAL_TXSTA = %00100000
DECLARE HSERIAL_BAUD = 38400
DECLARE HSERIAL_CLEAR = On
SYMBOL RS485AKT = PORTB.1
'standart variable
dim RCV_BYTE AS byte
dim SR_BYTE_CNT AS BYTE
dim SEND_BYTE_CNT AS WORD
DIM START_ADRESS AS WORD
DIM TIME AS byte
DIM SR_STR[110] AS BYTE
DIM IQ_TABLE[100] AS BYTE
Dim V1 As BYTE
Dim V2 As BYTE
Dim V3 As WORD
DIM CRC_16 AS WORD
'Demo variable
dim sayac as byte
dim sayac2 as byte
CLEAR
'INTERRUPT
intcon = %11100000
t0con = %11000001
PIE1.5 = 1
DELAYmS 1000
on interrupt goto INT_LOOP
enable
LOW RS485AKT
IQ_TABLE[1] = EREAD 0 'STATION ADRESS
;********************** START ***********************************
start:
inc sayac
if sayac = 0 then inc sayac2
IQ_TABLE[5] = sayac2
if sayac2.1 = 1 then inc IQ_TABLE[5]
if sayac2.2 = 1 then inc IQ_TABLE[7]

IF PIE1.4 = 0 AND PIE1.5 = 0 AND TIME > 5 THEN LOW RS485AKT : TIME = 0 : PIE1.5 = 1
GOTO START
;-------------------------------------------------------------------
;*********************** INTERRUPT *********************************
INT_LOOP: disable
'IF RECEIVE BUFFER NOT EMPTY
if PIE1.5 = 1 then
if PIR1.5 = 1 then
IF TIME > 4 THEN SR_BYTE_CNT = 0
TIME = 0
hserin [RCV_BYTE]
SR_STR[SR_BYTE_CNT] = RCV_BYTE
SR_BYTE_CNT = SR_BYTE_CNT + 1
GOTO CIKIS
endif
endif
'IF OUTPUT BUFFER EMPTY SEND NEXT
if PIE1.4 = 1 then
if PIR1.4 = 1 then
TIME = 0
IF SR_BYTE_CNT > SEND_BYTE_CNT - 1 THEN
PIE1.4 = 0 : SR_BYTE_CNT = 0 : goto CIKIS
endif
HSEROUT [SR_STR[SR_BYTE_CNT]]
SR_BYTE_CNT = SR_BYTE_CNT + 1
GOTO CIKIS
ENDIF
endif
if intcon.2 = 1 then
intcon.2 = 0
inc TIME
if TIME > 6 then
TIME = 0
gosub modbus
ENDIF
endif
CIKIS:
RESUME
ENABLE
;
;******************* MODBUS QUERY ANALYSIS ******************
MODBUS:
IF PIE1.5 = 0 THEN return
IF SR_BYTE_CNT < 8 THEN return
PIE1.5 = 0 'RCV INTERRUPT CLOSE
'RECEIVE COMPLETE
IF SR_STR[0] = IQ_TABLE[1] THEN 'ADRESS CHECK
GOSUB CRC16 'CRC16 CALCULATE
IF CRC_16.BYTE0 = SR_STR[SR_BYTE_CNT-2] THEN
IF CRC_16.BYTE1 = SR_STR[SR_BYTE_CNT-1] THEN
HIGH RS485AKT
START_ADRESS = ((SR_STR[2]*256) + SR_STR[3]) * 2
'FUNCTION CODE 3-4
IF SR_STR[1] = 3 or SR_STR[1] = 4 THEN
SEND_BYTE_CNT = (((SR_STR[4]*256) + SR_STR[5])* 2) + 5
'REQUEST ADRESS REGISTERS ADRESS CHECK
if START_ADRESS + SEND_BYTE_CNT - 5 > 102 then GOTO REG_ADR
'SEND STRING BUILDING
SR_STR[2] = SEND_BYTE_CNT - 5
FOR V1 = START_ADRESS TO START_ADRESS + SEND_BYTE_CNT
SR_STR[V1-START_ADRESS + 3] = IQ_TABLE[V1]
NEXT
GOSUB SEND_CRC16
RETURN
ENDIF
'FUNCTION CODE 6 SINGLE VARIABLE
IF SR_STR[1] = 6 THEN
'REQUEST ADRESS REGISTERS ADRESS CHECK
if START_ADRESS > 100 then GOTO REG_ADR
'VALUE LIMIT CHECK
IF START_ADRESS < 21 THEN
IF (SR_STR[4]*256) + SR_STR[5] > 1023 THEN GOTO LIMIT_OUT
ENDIF
IF START_ADRESS > 20 THEN
IF START_ADRESS < 35 THEN
IF (SR_STR[4]*256) + SR_STR[5] = 0 THEN GOTO LIMIT_OUT
IF (SR_STR[4]*256) + SR_STR[5] > 255 THEN GOTO LIMIT_OUT
ENDIF
ENDIF
IQ_TABLE[START_ADRESS] = SR_STR[4]
IQ_TABLE[START_ADRESS + 1] = SR_STR[5]
GOSUB KAYIT
'SEND STRING BUILDING
SEND_BYTE_CNT = 8
GOSUB SEND_CRC16
RETURN
ENDIF
'FUNCTION CODE 16
IF SR_STR[1] = 16 THEN
SEND_BYTE_CNT = SR_STR[6] + 5 'SEND DATA BYTE COUNT
'REQUEST ADRESS REGISTERS ADRESS CHECK
if START_ADRESS + SEND_BYTE_CNT - 5 > 102 then GOTO REG_ADR
'RECEIVE STRING LENGTH CHECK
IF SEND_BYTE_CNT + 4 <> SR_BYTE_CNT then GOTO REG_ADR
FOR V1 = START_ADRESS TO START_ADRESS + SEND_BYTE_CNT - 6
'VALUE LIMIT CHECK
IF V1.0 = 0 THEN 'LIMIT CHECK ONLY FIRST BYTE RUNING
V3 = SR_STR[V1 - START_ADRESS + 7] * 256
V3 = V3 + SR_STR[V1 - START_ADRESS + 8] 'VALUE
IF START_ADRESS < 21 THEN
IF v3 > 1023 THEN GOTO LIMIT_OUT
ENDIF
IF V1 > 20 THEN
IF V1 < 35 THEN
IF V3 = 0 THEN GOTO LIMIT_OUT
IF V3 > 255 THEN GOTO LIMIT_OUT
ENDIF
ENDIF
ENDIF
IQ_TABLE[V1] = SR_STR[V1 - START_ADRESS + 7]
NEXT
GOSUB KAYIT
'SEND STRING BUILDING
SEND_BYTE_CNT = 8
GOSUB SEND_CRC16
RETURN
ENDIF
'INVALID FUNCTION CODE
SEND_BYTE_CNT = 5
SR_STR[2] = 1
GOSUB SEND_CRC16
RETURN
ENDIF
ENDIF
ENDIF
SR_BYTE_CNT = 0
RETURN
'REGISTIRS ADRESS OUT OFF LIMIT
REG_ADR:
SEND_BYTE_CNT = 5
SR_STR[2] = 2
GOSUB SEND_CRC16
return
'VALUE OUT OFF LIMIT
LIMIT_OUT:
SEND_BYTE_CNT = 5
SR_STR[2] = 3
GOSUB SEND_CRC16
RETURN
;
;************************** SEND QUERY BUILDING ****************
SEND_CRC16:
SR_BYTE_CNT = SEND_BYTE_CNT
GOSUB CRC16
SR_STR[SEND_BYTE_CNT - 2] = CRC_16.BYTE0
SR_STR[SEND_BYTE_CNT - 1] = CRC_16.BYTE1
SR_BYTE_CNT = 0
PIE1.4 = 1 'SEND INTERRUPT CLOSE
RETURN
;
;************************** CALCULATE CRC-16 *************************
CRC16:
V1 = 0
V2 = 0
V3 = 0
CRC_16 = 65535
For V1 = 0 To SR_BYTE_CNT - 3
V3 = CRC_16
CRC_16.BYTE0 = V3.BYTE0 ^ SR_STR[V1]
For V2 = 0 To 7
If CRC_16.0 = 1 Then
CRC_16 = CRC_16 >> 1
CRC_16 = CRC_16 ^ 40961
ELSE
CRC_16 = CRC_16 >> 1
End If
Next V2
Next V1
RETURN
;
;************************* VARIABLE SAVE ***************
KAYIT:
IF IQ_TABLE[1] <> EREAD 0 THEN EWrite 0,[IQ_TABLE[1]]
return
;
;################################################################
 

FANUC

Üye
Katılım
14 Eki 2007
Mesajlar
20
Puanları
1
Yaş
35
Merhaba, çok başarılı bir paylaşım

Size izin verirseniz sorum şu

18F452 devreresi minimum konfigurasyonu ile mi kurulmalıdır. Haberleşme için max232 kullanılmamlı mı. Birde kodu hangi derleyici ile yazdınız ?
 

eyupbakan

Üye
Katılım
7 Ara 2007
Mesajlar
244
Puanları
3
Sn Fanuc;
Yazılım proton ile yapılmışa benziyor okurken cevaplayayım dedim yazandan önce.Paylaşım mükemmel bir yıldız benden.
 

red673

Üye
Katılım
1 Ara 2007
Mesajlar
7
Puanları
1
Yaş
35
Mrb arkadaş bsizden biraz bilgi almak istiyırum bu konuyla ilgili ben pic le oluşturulmuş 30 kanal network kurmak istiyorum rs 485 bunun için standart bir modbus kullanmam şarmı bilgiyi neye gönderecegim rs 485 haberleşmede
 

feyzo2

Üye
Katılım
16 Kas 2011
Mesajlar
22
Puanları
1
Merhabe benim 2 tane 16f877 'in haberleşmesini RS 485 ile yapmam lazım yapmak istediğim projeyi İSİS te çizip çalıştırmam lazım
Devrenin nasıl çalışacağını anlatayım... 1. picden 1 butonla bir sinyal yollayıp 2. pıcten bunu algılayıp LCD ekranda bu sinyalin geldiğini göstermem lazım.. Yani 1. picten gelen sinyal ile 2. picten ekrana "led yandı" yazmasını gerekiyor bununla ilgili araştırma yapıp duruyorum ama 485 i nasıl programlıcam nerden ayarlıcam hiç bilmiyorum :( bununla ilgili yardımcı olursanız çok sevinirim

Bu devreyi isis te çizip yollayabilecek varsa bu da olabilir hatta daha iyi olur YARDIMLARINI BEKLİYORUM.. Şimdiden teşekkürler
 

prodowns

Üye
Katılım
5 Eki 2010
Mesajlar
1
Puanları
1
Merhabe benim 2 tane 16f877 'in haberleşmesini RS 485 ile yapmam lazım yapmak istediğim projeyi İSİS te çizip çalıştırmam lazım
Devrenin nasıl çalışacağını anlatayım... 1. picden 1 butonla bir sinyal yollayıp 2. pıcten bunu algılayıp LCD ekranda bu sinyalin geldiğini göstermem lazım.. Yani 1. picten gelen sinyal ile 2. picten ekrana "led yandı" yazmasını gerekiyor bununla ilgili araştırma yapıp duruyorum ama 485 i nasıl programlıcam nerden ayarlıcam hiç bilmiyorum :( bununla ilgili yardımcı olursanız çok sevinirim

Bu devreyi isis te çizip yollayabilecek varsa bu da olabilir hatta daha iyi olur YARDIMLARINI BEKLİYORUM.. Şimdiden teşekkürler
sadece 2 pic i haberleştireceksen rs485 kafanı karıştırmasın. sen kodu ve sistemi rs232, daha doğrusu piclerin tx-rx seri portu uartlarına göre yaz. daha sonra tx rx çıkışlarının önüne max485,sn75176 gibi bir 485 çevirici koy ve bunları birbirine bağla, 1. pice bağlı 485 çeviricinin enable pinine 0 diğerine 1 verirsen sistem çalışır.

örnek bi isis çizimi gönderiyorum, devre aşağı yukarı bu mantıkta olacak.

 

feyzo2

Üye
Katılım
16 Kas 2011
Mesajlar
22
Puanları
1
sadece 2 pic i haberleştireceksen rs485 kafanı karıştırmasın. sen kodu ve sistemi rs232, daha doğrusu piclerin tx-rx seri portu uartlarına göre yaz. daha sonra tx rx çıkışlarının önüne max485,sn75176 gibi bir 485 çevirici koy ve bunları birbirine bağla, 1. pice bağlı 485 çeviricinin enable pinine 0 diğerine 1 verirsen sistem çalışır.

örnek bi isis çizimi gönderiyorum, devre aşağı yukarı bu mantıkta olacak.

çok teşekkür ederim bunun pıc kodlarını yazmakta bana kaldı artık :) örnek şeömayı çizdiğin için sağol :) eğer pıc kodunu yazamazsam yine yardım isterim
 

feyzo2

Üye
Katılım
16 Kas 2011
Mesajlar
22
Puanları
1
sen bu hazır rtu verdin ya kardeşim şimdi ben bunu rs 485 e nasıl ayarlıcam anlamış değilim hangi programla ayarlıcam?
 

mikrocan

Üye
Katılım
8 Ağu 2006
Mesajlar
33
Puanları
3
Yaş
35
Fultek_Salih bey, harika bir paylaşım olmuş,ellerinize sağlık. En kısa zamanda deneyeceğim çalışmayı.
 

Sponsor Bağlantı

Forum istatistikleri

Konular
105,147
Mesajlar
740,471
Kullanıcılar
390,910
Son üye
Mustafa Yeşilli

Çevrimiçi üyeler

Üst