Pic 16f887 ile rs485'de yardım alabilir miyim?

Başlatan deta, 06 Eylül 2023, 16:48:25

deta

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ı 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ı?

mehmet

Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

deta




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.

alikeskinkilic

#3
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;
Hep meraktan