Página 1 de 1

PC (usb)<->conv_usb/PIC/RS485<->RS485/PIC

MensagemEnviado: 04 Mar 2010 10:19
por alexhnunes
Bom dia, pessoal.

Tenho um projeto onde preciso fazer uma comunicação RS485 da forma descrita no "assunto". Na ponta onde está RS485/PIC, estão conectados led's sinalizadores que serão acionados pelo PC e botões que mandam mensagem para o PC e acionam led's tbm. Estou utilizando o CCS e encontrando o seguinte problema: ao fazer a comutação das RS485 (estou fazendo de modo manual, através de um código mandado pelo PC)observamos aqui que a interrupção GLOBAL é desativada, impossibilitando a mudança de estado de transmissão/recepção dos RS485. Estou trabalhando com flags para eliminar todos os comandos indesejáveis de dentro das interrupções (delay e printf). Quando faço a transmissão somente em um sentido, tudo OK. O problema está sendo no retorno, quando há a mudança de estado. Não sei se é problema no CCS, o fato é que não estou encontrando nenhuma solução para isto. Mesmo ativando a GLOBAL depois de onde acontece o erro, ela volta a ser desativada. Peço ajuda a quem tem mais conhecimento, pois é a primeira vez que tento utilizar a RS485 e não estou tendo sucesso...
Abaixo os códigos dos circuitos.

Este é do RS485/PIC
Código: Selecionar todos
#include <16F876A.h>
//#device *=16
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

char srl[6];
int REC=0, ENV=0;

#define RS485_Ctr PIN_C5
#define transmite OUTPUT_HIGH
#define recebe    OUTPUT_LOW

#Int_RDA
void Trata_Serial(){
   gets(srl);

   if((srl[0]=='*')&&(srl[3]=='#')&&(srl[5]=='*')){
      if ((srl[1] == 'S') && (srl[2] == 'L')){
         if(srl[4]=='1') output_high(PIN_B0);
         if(srl[4]=='2') output_high(PIN_B1);
         }   
      if ((srl[1] == 'S') && (srl[2] == 'D')){
         if(srl[4]=='1') output_low(PIN_B0);
         if(srl[4]=='2') output_low(PIN_B1);
         }   
      if((srl[0]=='R')&&(srl[1]=='E')&&(srl[2]=='C')) REC=1;
      if((srl[0]=='E')&&(srl[1]=='N')&&(srl[2]=='V')) ENV=1;
      }
   }   
void main(void){
   output_B(0x00);

   //output_high(PIN_C0);

   Enable_Interrupts(INT_RDA);
   Enable_Interrupts(GLOBAL);

   transmite(RS485_Ctr);  //Habilita a transmissão de dados para a rede

   printf("OK\r");

   Delay_ms(50);

   recebe(RS485_Ctr);

   while(true){
      
      if(!input(PIN_A0)){
         ENV=1;
         output_high(PIN_B3);
         printf("BT\r");
         Delay_ms(50);
         while(!input(PIN_A0)){}
         //REC=1;
         }   
      if(!input(PIN_A1)){
         ENV=1;
         output_high(PIN_B4);
         printf("BT\r");
         Delay_ms(50);
         while(!input(PIN_A1)){}
         }
      if(REC==1){
         recebe(RS485_Ctr);
         Delay_ms(50);
         REC=0;
         }   
      if(ENV==1){
         transmite(RS485_Ctr);
         Delay_ms(50);
         ENV=0;
         }   
         
   
      }   

   }


Este é do conversor USB/PIC/RS485
Código: Selecionar todos
#include <16F876A.h>
//#device *=16
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_B1, rcv=PIN_B0, stream=serial)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=s_usb)

#define RS485_Ctr PIN_B2
#define transmite OUTPUT_HIGH
#define recebe    OUTPUT_LOW

char srl[6], srl2[6];
int SL1=0, SL2=0, SD1=0, SD2=0, OK=0, BT=0, REC=0, ENV=0;

#int_rda
void USB(){
//   transmite(RS485_Ctr);
   fgets(srl2,s_usb);   
   if((srl2[0]=='*')&&(srl2[3]=='#')&&(srl2[5]=='*')){
      if((srl2[1] == 'S')&&(srl2[2] == 'L')){      
         if(srl2[4]=='1') SL1=1;
         if(srl2[4]=='2') SL2=1;
         }   
      if((srl2[1] == 'S')&&(srl2[2] == 'D')){         
         if(srl2[4]=='1') SD1=1;
         if(srl2[4]=='2') SD2=1;
         }
      }
   if((srl2[0]=='E')&&(srl2[1]=='N')&&(srl2[2]=='V')) ENV=1;
   if((srl2[0]=='R')&&(srl2[1]=='E')&&(srl2[2]=='C')) REC=1;
   }   

#int_ext
void RS485(){
   fgets(srl,serial);
   if((srl[0]=='O')&&(srl[1]=='K')) OK=1;
   if((srl[0]=='B')&&(srl[1]=='T')) BT=1;
   }

void main(void){

   //Output_High(PIN_C0);

   ext_int_edge(H_TO_L);

   Enable_interrupts(INT_EXT);
   Enable_Interrupts(INT_RDA);
   Enable_Interrupts(GLOBAL);

   recebe(RS485_Ctr);

   while(true){
      if(SL1==1){
         fprintf(serial,"*SL#1*\r"); //manda para módulo 2
             output_high(PIN_C0);
         SL1=0;
         }   
      if(SL2==1){
         fprintf(serial,"*SL#2*\r"); //manda para módulo 2
         output_high(PIN_C0);
         SL2=0;
         }   
      if(SD1==1){
         fprintf(serial,"*SD#1*\r");
         output_low(PIN_C0);
         SD1=0;
         }   
      if(SD2==1){
         fprintf(serial,"*SD#2*\r");
         output_low(PIN_C0);
         SD2=0;
         }   
      if(OK==1){
          fprintf(s_usb,"OK\r");
         transmite(RS485_Ctr); 
           delay_ms(50);
         OK=0;
         }   
      if(BT==1){
          fprintf(s_usb,"BT\r");
         transmite(RS485_Ctr); 
           delay_ms(50);
         BT=0;
         }   
      if(REC==1){
          fprintf(serial,"ENV\r");
         delay_ms(50);
          fprintf(s_usb,"REC\r");
         recebe(RS485_Ctr); 
           delay_ms(50);
         REC=0;
         }   
      if(ENV==1){
          fprintf(serial,"REC\r");
         delay_ms(50);
          fprintf(s_usb,"ENV\r");
         transmite(RS485_Ctr); 
           delay_ms(50);
         ENV=0;
         }   
      
      }

   }

MensagemEnviado: 04 Mar 2010 10:24
por verd
Em ultimo caso se não conseguir implementar por software compre um conversor serial para usb da FTDI, o ft232, e um conversor serial para 485!

MensagemEnviado: 04 Mar 2010 10:48
por alexhnunes
verd escreveu:Em ultimo caso se não conseguir implementar por software compre um conversor serial para usb da FTDI, o ft232, e um conversor serial para 485!


No caso da USB eu já estou utilizando um conversor da FTDI (justamente o FT232BM), e a RS485 está fazendo a comunicação, meu problema é somente na RS485 quando eu mudo o estado dos pinos que fazem a transmissão/recepção e a interrupção é desativada. Se eu não faço essa mudança, tudo funciona sem problemas...

MensagemEnviado: 08 Mar 2010 07:10
por alexhnunes
UP

MensagemEnviado: 08 Mar 2010 10:21
por RobL
Antes de morrer na praia, verifique se há um resistor pullup de 10K da saída do receptor RX (SN75176) ou similar (pino 1 para o +5Vcc).
Coloque-o lá.

MensagemEnviado: 09 Mar 2010 09:12
por alexhnunes
RobL, coloquei o resistor no pino 01 e refiz os testes, infelizmente continuou na mesma...
Estou pensando seriamente em tentar com outro programa (HiTech), pois não consigo descobrir pq isso está acontecendo no Proteus.