CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

UART 1 doesnt work if UART 2 is used

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
asdf85



Joined: 03 Jan 2011
Posts: 34

View user's profile Send private message

UART 1 doesnt work if UART 2 is used
PostPosted: Mon Nov 14, 2011 3:23 am     Reply with quote

Hi,

I've having difficulities getting the 2 UARTS to work. What happens is, if I remove the '#USE RS232(UART1 ....' line, the rx/tx of UART2 works. If i dont remove it, it wont work. I havent really programmed anything for UART1 yet, but i need to use it.

My compiler version is 4.093, and im using pic18f26j11

Here is my code. I didnt post some of the functions coz its too long , and unescessary coz im sure thats not where the problem lies.

Could someone tell me whats causing this problem? Thanks

Code:

#include "18F26j11.h"
#include <stdio.h>
#fuses HS,NOPROTECT,NOWDT,NODEBUG
#use delay(clock=20000000)
#pin_select RX2=pin_c5
#pin_select TX2=pin_c4
//#use RS232(UART1,baud=9600,parity=n,stream=disp,enable=pin_a5,xmit=PIN_C6,rcv=PIN_C7)
#use RS232(UART2,baud=9600,parity=n,stream=plc,ERRORS)
//===============================


//==================================CRC Variables=================================================================

int16 gencrc(int16 *msg,int msglen);   //function to generate CRC; pointer has to be used to send array.
int16 r[12]={0x01};         //bytes received placed in this array
int16 r2[12]={0x00};
int16 s[26];      //bytes to send stored in this array
int16 *rPtr= r;      //pointer to array 'r', used to call crc generation function
int16 *sPtr= s;      //pointer to array 's', used to call crc generation function
int16 hexs=0xFFFF;
int k;
//=============================================REGISTERS=================================================
int16 inputreg=0b1100101011110000;
//int16 holdreg[16]={0x0007,0x0008,0x0009,0x00AA,0x00BB};      //now its directly stored in eeprom 30-61
int16 coilreg=0;   //eeprom MSB=21, LSB=22
//int1 coilreg1[16]={0x01};
//int1 coilreg2[8]={0x01};

//================================================MODBUS Functions===================================================
void fc1();
void fc2();
void fc3();
void fc4();
void fc5();
void fc6();
void fc15();
void fc16();
void exceptioncode(int ec);
void csa();    //change slave address
//==============================================General Variables=============
int channel[512]={0};
int16 counter=0;
int slaveadd=0x01;
int j;int crc1=0; int crc2=0;
int16 regadd=0;int16 noofadd=0;int16 regdata=0;
//=============================================RDA interrupt variables==========
int idl=0;   //incoming data length
int1 readyplc=0;
int1 readydisp=0;
int16 x=0;int y=0;
int1 packetend=0;
int1 incomingdata=0;
int biggesty=0;
//=====================================MAIN PROGRAM========================

int temp=0;

void main()
{   clear_interrupt(int_rda2);
   enable_interrupts(int_rda2);
//   clear_interrupt(int_rda);
//   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);




   output_high(pin_c2);
   output_low(pin_c3);

   while(1)
   {   
       if(readyplc==1)
      {   readyplc=0;
      //   output_toggle(pin_c2);
   //      for(temp=0;temp<idl;temp++)
   //      {   fputc(r[temp],disp);
   //      }
         
         
         if(r[0]==slaveadd)
         {   output_toggle(pin_c2);
            gencrc(&*rPtr,idl-2);   
            crc1=make8(hexs,0);
            crc2=make8(hexs,1);
            if(crc1==r[idl-2]&&crc2==r[idl-1])//check the 2 CRC bytes to make sure its correct with the one calculated
            {   
               if(r[1]==1)            //function code 1 - read coil status
               {   exceptioncode(1);
                  //fc1();
               }
            //   else if(r[1]==2)      //function code 2 - read input status
            //   {   fc2();
            //   }
               else if(r[1]==3)      //function code 3 - read holding registers
               {   fc3();
               }
            //   else if(r[1]==5)      //function code 5 - force single coil
            //   {   fc5();
            //   }   
               else if(r[1]==6)      //function code 6 - preset single register
               {
                  fc6();
               }
            //   else if(r[1]==0x0F)      //function code 15 - force multiple coils
            //   {   fc15();
            //   }
               else if(r[1]==0x10)      //function code 16 - preset multiple registers
               {   
                  fc16();
               }
               else
               {
                  exceptioncode(1);   //   illegal function
               }

               output_high(pin_b0);
               delay_ms(100);
               output_low(pin_b0);
            }
            else
            {   exceptioncode(7);      //negative acknowledge (wrong CRC)
            }
         
         }
         else if(r[0]==0)
         {   
            gencrc(&*rPtr,idl-2);   
            crc1=make8(hexs,0);
            crc2=make8(hexs,1);
            if(crc1==r[idl-2]&&crc2==r[idl-1])//check the 2 CRC bytes to make sure its correct with the one calculated
            {   
               csa();
            }
         }
      }
   }
   
}
//====================================================Interrupts==============================


#INT_RDA2
void RDA2_isr()
{   r[y]=fgetc(plc);

   y++;
   

   x=0;
   while(x<1500&&kbhit()==0)      
   {   x++;
      if(kbhit()==1)
      {break;
      }
   }
   if(kbhit()==0)
   {   idl=y;
      y=0;
      readyplc=1;
   }   
      
 }
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Mon Nov 14, 2011 5:20 am     Reply with quote

I don't see that your interrupt is ever going to work properly.
When the interrupt triggers, it says 'one character is waiting'. Nothing more.
A second character will take just over 1mSec to arrive - some 4000 instruction times.
Now your interrupt reads the character, clearing the character waiting flag, and then sets x to 0. So, on your 'while' test, x is _always_ going to be less than 1500, and kbhit, is always going to be 0, and characters are only going to be put into the first location in the array...
Perhaps some rethinking of what you are trying to do is needed?.
Then, why on earth use an int16 array to store characters received?. Wasteful of space, and time.
Then, you can't just 'clear' an RDA interrupt. You _must_ read the character, or it'll reset immediately. Like a lot of hardware interrupts (INT_RB for example), the hardware event that is triggering the interrupt, has to be cleared first.

Best Wishes
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Nov 14, 2011 5:30 am     Reply with quote

Possibly as you've specified an enable pin in UART1 it has implemented it as a software UART. The hardware doesn't support an enable. It may also give you a software UART because you've specified the tx & rx pins.

I'm not 100% sure why this matters, but looking at your code, I see your kbhit() in your isr calls don't specify which stream. They will default to UART1 if that use rs232 line is in. I think you'll need to change them to kbhit(plc).

One more thing, I see why you need an enable: you are implementing MODBUS. CCS provides MODBUS support in modbus.c. There's an example ex_modbus.c. Take a look, it could save you a lot of time and effort. It did for me.Very Happy

RF Developer
asdf85



Joined: 03 Jan 2011
Posts: 34

View user's profile Send private message

PostPosted: Wed Nov 16, 2011 7:55 pm     Reply with quote

Thanks.

I got it working finally.
Initially the problem was with the kbhit() not having the stream name mentioned. But after that there was the problem with the timing due to the delays in the int_rda. I only did that too determine if there's a next byte within the next few milliseconds, but now I removed all delays and used timer interrupts and I got it working.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group