Merhabalar, bir proje yapmaya çalışıyorum. Pic16f887 kullanarak bir master, 4 slave olan bir proje bu. Bir klavyedeki tuşlara bastıkça slave'lerdeki ledler yanacak, sönecek (1'e bastığımda 1. slave'in led'i yanacak ve 2'ye bastığımda sönecek; 4'e bastığımda 2. slave'in led'i yanacak, 5'e bastığımda sönecek vs.). Bu proje için Proteus ve MikroC kullanıyorum. Klavye'de sıkıntı yok, fakat galiba slave'lerin kodunda eksiklikler var. Kodumu çalıştırdığımda 1,2 ve 3. slave'lerimde herhangi bir tuşa bastığımda bus collision hatası oluyor, 4. slave'imde ise i/o değişikliği oluyor.
MikroC'deki RS485 kütüphanesindeki kodları (https://download.mikroe.com/documents/compilers/mikroc/pic/help/rs-485_library.htm) deneyerek kodumu yazmaya çalıştım.
Master kodum (klavye ve lcd dahil değil):
char dat[10]; // buffer for receving/sending messages
char i,j;
sbit rs485_rxtx_pin at RC2_bit; // set transcieve pin
sbit rs485_rxtx_pin_direction at TRISC2_bit; // set transcieve pin direction
void Send_From_Master(int TUS, char dat[10]) {
switch(TUS) {
case 9: dat[0] = 0xAA; //klavyede 1'e basılırsa
dat[1] = 0xF0;
dat[2] = 0x0F;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
RS485Master_Send(dat,1,160); break;
case 5: dat[0] = 0; //klavyede 2'ye basılırsa
dat[1] = 0;
dat[2] = 0;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
RS485Master_Send(dat,1,160); break;
case 10: dat[0] = 0xAA; //klavyede 4'e basılırsa
dat[1] = 0xF0;
dat[2] = 0x0F;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
RS485Master_Send(dat,1,161); break;
case 6: dat[0] = 0; //klavyede 5'e basılırsa
dat[1] = 0;
dat[2] = 0;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
RS485Master_Send(dat,1,161); break;
case 11: dat[0] = 0xAA; ////klavyede 7'ye basılırsa
dat[1] = 0xF0;
dat[2] = 0x0F;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
RS485Master_Send(dat,1,162); break;
case 7: dat[0] = 0; ////klavyede 8'e basılırsa
dat[1] = 0;
dat[2] = 0;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
RS485Master_Send(dat,1,162); break;
case 12: dat[0] = 0xAA; ////klavyede *'a basılırsa
dat[1] = 0xF0;
dat[2] = 0x0F;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
RS485Master_Send(dat,1,163); break;
case 8: dat[0] = 0; //klavyede 0'a basılırsa
dat[1] = 0;
dat[2] = 0;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;
RS485Master_Send(dat,1,163); break;
}
if (dat[5]) { // error varsa portd'yi 0xAA yaparak belirt
PORTD = 0xAA; }
}
void main() {
ADC_init(); //Initialize ADC module with default settings
ANSELH = 0; //configure analog pins as I/O pins
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
UART1_Init(9600);
delay_ms(200); //waiting for it to get its act together
RS485Master_Init(); // initialize MCU as Master
OPTION_REG = 0B00000000;
INTCON = 0B11011000;
IOCB = 0B11110000;
RCIE_bit = 1; // enable interrupt on UART1 receive
TXIE_bit = 0; // disable interrupt on UART1 transmit
while(1) //hep açık olsun diye
{
Send_From_Master(TUS,dat[10]);
} }
Slave kodum (her biri aynı, sadece adresleri farklı):
char dat[9]; // buffer for receving/sending messages
char i,j;
sbit rs485_rxtx_pin at RC2_bit; // set transcieve pin
sbit rs485_rxtx_pin_direction at TRISC2_bit; // set transcieve pin direction
void Interrupt() {
RS485Slave_Receive(dat);
if(PIR1bits.RCIF){
PORTB=RCREG; //bu kısımdan hiç emin değilim
PIR1bits.RCIF=0;
}
INTCONbits.GIEH = 1;
INTCONbits.GIEL = 1;
}
void main() {
OSCCON=0x72;
ADC_init(); //Initialize ADC module with default settings
ANSELH = 0; //configure analog pins as I/O pins
INTCON = 0B11010000;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
OPTION_REG = 0B00000000;
TRISB = 0;
PORTB = 0;
UART1_Init(9600);
delay_ms(200);
RS485Slave_Init(164);
RCIE_bit = 1; // enable interrupt on UART1 receive
TXIE_bit = 0; // disable interrupt on UART1 transmit
PEIE_bit = 1;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that message received flag is 0
dat[6] = 0; // ensure that error flag is 0
while (1) { // Endless loop
//Slave_Recieve(trans);
if (dat[5]) { // if an error detected, signal it by
PORTD = 0xAA; // setting portd to 0xAA
dat[5] = 0;
}
if (dat[4]) { // upon completed valid message receive
dat[4] = 0; // data[4] is set to 0xFF
j = dat[3];
for (i = 1; i <= dat[3];i++){
PORTB.RB0 = dat[i-1]; //led B0 pinine bağlı
}}
}
}
Acaba bana yardım edebilecek birisi var mı?
Bağlantınız nasıl? Şema var mı?
(https://i.ibb.co/cY0cP0K/resim-2023-09-08-094028188.png) (https://ibb.co/cY0cP0K)
Projem kalabalık olduğu için sadece bir slave'i çekebildim. Hepsinin bağlantıları aynı, yakacağım ledler slavelerin PORTB'deki B0 pin'lerine bağlı. MAX487'nin RO (reciever output) pini piclerin RX pinine, DI (driver input) pini piclerin TX pinine, RE ve DE pini piclerin RC2 pinine bağladım. B ve A output pinlerini hemcinslerine bağladım (tüm B'ler birbirine bağlı, tüm A'lar birbirine bağlı). paralel olarak aralarına iki tane 120 ohm'luk direnç bağladım, sonra belki pull-up ve pull-down dirençleri (ikisi de 680 ohm) devreyi sabitler diye düşünerek onları da bağladım.
C bilmiyorum ama yazdığın kodda bu satırlar sıra ile işliyor ve köşeli parantezlerin içerisi 6 bytelik dat değişkenine ait ise 1,2,4,5,6 diye gidiyor 3 numaralı byte neden yok.eğer bu bir sorun ise ki asm ve basic te bilinçli yapmadıysan çoğu durumda sorun olur.özellikle "RS485Master_Send(dat,1,160); break" bir kütüphane komutu sanırım dat burada sıra ile gönderiliyor ise.
case 9: dat[0] = 0xAA; //klavyede 1'e basılırsa
dat[1] = 0xF0;
dat[2] = 0x0F;
dat[4] = 0; // ensure that message received flag is 0
dat[5] = 0; // ensure that error flag is 0
dat[6] = 0;