18F4550 Yazılımsal UART sorunu

Başlatan eeris43, 11 Temmuz 2016, 19:46:22

eeris43

Merhaba arkadaşlar ben 18F4550de yazılımsal uart kullanmak istiyorum ama C6-C7 pinleri dışında tanımlama yaptığımda çalıştıramadım acaba sorun ne olabilir.

#include <18F4550.h> 
#device adc=8 
#fuses HS, NOWDT, BROWNOUT, PUT, NOLVP 

#use delay(clock=20000000) 

#use rs232(baud=19200, xmit=PIN_C4, rcv=PIN_C2, stream=PC,errors,FORCE_SW) 
#define MODBUS_TYPE MODBUS_TYPE_MASTER
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 38400
#define MODBUS_SERIAL_RX_PIN PIN_C7
#define MODBUS_SERIAL_TX_PIN PIN_C6
#define MODBUS_SERIAL_ENABLE_PIN PIN_C5
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA

#include <modbus.c>
#define MODBUS_SLAVE_ADDRESS1 29
#define MODBUS_SLAVE_ADDRESS2 30
#define alarmsicaklik 60

float sicaklilar[25];
float gerilimler[25];

void read_all_holding( void );
void sicakliklarioku(int badres);
void gerilimlerioku(int badres);
void telemetrigonder(void);
unsigned int8 coils[4]={120,50,4,18},i=0;
unsigned tmdurum=0;
void main()
{ 
  modbus_init();
   delay_ms(500);

   while(true)
   {

      read_all_holding();
      telemetrigonder();
      
      modbus_write_multiple_coils(MODBUS_SLAVE_ADDRESS1,0,15,&coils); 
      { 
         for(i=0;i<(modbus_rx.len);++i) 
         { 
         } 
      } 
      delay_ms(500);
   }
  
}

void read_all_holding()
{ 
   if(!(modbus_read_holding_registers(MODBUS_SLAVE_ADDRESS1,0,2))){ 
         sicakliklarioku(0);
        // gerilimlerioku(0);
         tmdurum=1;
      }
   else
         fprintf(PC, "Hata: %d\r\n", modbus_rx.error);

   delay_ms(500);
   if(!(modbus_read_holding_registers(MODBUS_SLAVE_ADDRESS2,0,2))){ 
         sicakliklarioku(4);
         gerilimlerioku(4);
         tmdurum=1;
      }
   else
      fprintf(PC, "Hata: %d\r\n", modbus_rx.error);
  
}

void sicakliklarioku(int badres){
      
      sicaklilar[badres]=modbus_rx.data[1]+(modbus_rx.data[2]*0.01);
      sicaklilar[badres+1]=modbus_rx.data[3]+(modbus_rx.data[4]*0.01);
      sicaklilar[badres+2]=modbus_rx.data[5]+(modbus_rx.data[6]*0.01);
      sicaklilar[badres+3]=modbus_rx.data[7]+(modbus_rx.data[8]*0.01);
}

void gerilimlerioku(int badres){
      
      gerilimler[badres]=modbus_rx.data[9]+(modbus_rx.data[10]*0.01);
      gerilimler[badres+1]=modbus_rx.data[11]+(modbus_rx.data[12]*0.01);
      gerilimler[badres+2]=modbus_rx.data[13]+(modbus_rx.data[14]*0.01);
      gerilimler[badres+3]=modbus_rx.data[15]+(modbus_rx.data[16]*0.01);
}

void telemetrigonder(){
      if(tmdurum==1){
      fprintf(PC, "$RF,DS,1,");
      fprintf(PC, "%f,", sicaklilar[0]);
      fprintf(PC, "%f,", sicaklilar[1]);
      fprintf(PC, "%f,", sicaklilar[2]);
      fprintf(PC, "%f,", sicaklilar[3]);
      fprintf(PC, "%f,", gerilimler[0]);
      fprintf(PC, "%f,", gerilimler[1]);
      fprintf(PC, "%f,", gerilimler[2]);
      fprintf(PC, "%f,", gerilimler[3]);
      fprintf(PC, "END\r\n");
      delay_ms(700);
      fprintf(PC, "$RF,DS,2,");
      fprintf(PC, "%f,", sicaklilar[4]);
      fprintf(PC, "%f,", sicaklilar[5]);
      fprintf(PC, "%f,", sicaklilar[6]);
      fprintf(PC, "%f,", sicaklilar[7]);
      fprintf(PC, "%f,", gerilimler[4]);
      fprintf(PC, "%f,", gerilimler[5]);
      fprintf(PC, "%f,", gerilimler[6]);
      fprintf(PC, "%f,", gerilimler[7]);
      fprintf(PC, "END\r\n");
      delay_ms(700);
      tmdurum=0;
      }
}

t2

#1
Zaten donanımsal olarak mevcut iken, yazılımsal uart kullanmanızın avantajı nedir?
18F4550 ,  c6,c7 pinlerine baktığımızda bu pinlerin donanımsal uart olduğu anlaşılmaktadır. galiba bu kodlar   donanımsal uart için. bu yüzden sadece  c6,c7 pinlerinden çalışıyor.

eeris43

c5-c6-c7 rs485 için kullanıyorum

SysTick

Size tavsiyem yazılımsal uartın rx bacağı için exti kurup bu bacaklardan birini kullanmanız, böylece data alırken bir interrupt oluşuturup rahat rahat data alabilirsiniz, data yollama işi biraz sıkıntılı, eğer o esnada başka bir interrupt olur ise data düzgün gitmez..
son olarak ise 18f46k22 ye bi bakın derim,ucuzdur aynı zamanda :) 

Murat Mert

#4
S.A.
geçen yıl bende uğraşmıştım.
https://www.picproje.org/index.php/topic,58908.msg455168.html#msg455168

mesaj birleştirme:: 12 Temmuz 2016, 10:33:31

rf kullanacaksın galiba
mert07

eeris43

Alıntı yapılan: Murat Mert - 12 Temmuz 2016, 10:29:59
S.A.
geçen yıl bende uğraşmıştım.
https://www.picproje.org/index.php/topic,58908.msg455168.html#msg455168

mesaj birleştirme:: 13 Temmuz 2016, 00:33:31

rf kullanacaksın galiba
aynen senin örneği gördüm.Ama çalıştıramadım.16f877a yapıcam ama yeterli ram rom hafızası yok çözebilirsem işim çok kolaylaştıracak.Evet UDA nın rf modullerini kullanarak veri yolluyacağım

Murat Mert

Çift uartlı pic kullan:
18f45k22, 46k22 gibi
bende rf kullandım sıkıntı çıkmamıştı. Alma verme kesme içinde çalıştı bir yerde atladığınız bir şey vardır.
mert07

Faruk53

https://www.picproje.org/index.php/topic,61284.0.html

bende senin yaşadığın problemi yaşamıştım bir ara. Ama daha sonra hallettim.
yukarıdaki linkteki problem rs232 tanımlamasında ikici uartın ismini belirlememiş olmamdı. yani;

#use rs232(baud=9600,xmit=PIN_C5,rcv=PIN_B0,parity=N,stop=1,stream=USART2,FORCE_SW,ERRORS)// Bu kısma Stream tanımlaması yapmamıştım.


programda harici kesme ile seri port rx kesmesi yapmıştım.

yanlız murat mert hocama katılıyorum. kesinlikle çift uartı olan bir işlemci seçmeni öneririm. Yüksek hızlarda çalışıldığı zaman veri alımlarında sıkıntılıar çıkıyordu. yazılımsal uart biraz problemli. benim de tavsiyem 2 uartlı bir işlemci kullanman. kolay gelsin