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 support@ccsinfo.com

PIC C

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



Joined: 23 Nov 2005
Posts: 2
Location: uk

View user's profile Send private message Yahoo Messenger MSN Messenger

PIC C
PostPosted: Mon Nov 28, 2005 9:48 am     Reply with quote

CAN SOMEONE HELP ME TO AMEND THIS CODE
ITS MET TO BE DOING
PIC C programme that will echo back every ASCII character received on the ER400TRS connected to the PICRadio PCB



#include <16F876.h>
//#device 16F876 ICD=TRUE
#use delay(clock=4000000)
#fuses XT,NOWDT, NOPROTECT, NOPUT, NOBROWNOUT
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, PARITY=N)


void main()
{
unsigned char c;

while(TRUE) // do forever
{
// host is ready
// receive byte
if(!(input(PIN_C4)))
{
c=getc();

output_high(PIN_C3);

putc(c);

delay_ms(1000); // send characters every 1 sec

output_high(PIN_C2);

delay_ms(1000); // send characters every 1 sec

}
}
}
_________________
erefaaco
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Nov 28, 2005 10:11 am     Reply with quote

If your serial source ever sends more than one character every two seconds this this code will lockup assuming you have used the HW UART (I haven't checked)

ER400TRS sends a character to the PIC. PIC echos character and does nothing for two seconds. Meanwhile ERS400TRS sends another character, and another... now the PIC serial port locks up because of an over run error. The PIC will not receive anymore characters from the serial interface.

You can get the compiler to solve the lockup problem by adding the keyword ERRORS to the #use RS232 directive.

This type of function should really be implemented using a serial Rx interrupt handler queuing received characters to a ring buffer. I personally believe that, unless there is insufficient free ram to implement a ring buffer or you cannot use interrupts, ALL receive serial communications should be implemented with a Rx interrupt handler.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
ikeme



Joined: 23 Nov 2005
Posts: 2
Location: uk

View user's profile Send private message Yahoo Messenger MSN Messenger

PostPosted: Mon Nov 28, 2005 11:20 am     Reply with quote

how is Rx INTERUPT USED in this situation
so what do i need to do to the code now


This type of function should really be implemented using a serial Rx interrupt handler queuing received characters to a ring buffer. I personally believe that, unless there is insufficient free ram to implement a ring buffer or you cannot use interrupts, ALL receive serial communications should be implemented with a Rx interrupt handler.
_________________
erefaaco
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Nov 28, 2005 6:15 pm     Reply with quote

Here is a proforma serial interrupt handler with sample code.

Code:
#define XTAL_FREQ 40000000
#use delay(clock=XTAL_FREQ,RESTART_WDT)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,errors, restart_wdt)


   // Serial Ring Buffer and control registers
#define   CCRSize   64      // Command Construction Buffer size
byte   CntCmdC;      // number of characters in the console command construction buffer
byte   CCRC[CCRSize];   // Console command construction register

   // Console Rx Ring Buffer control
byte   RxHeadC;      // Console Ring Buffer Head pointer
byte   RxTailC;      // Console Ring Buffer Tail pointer

   // allocate communications buffer memory
#define RxCQsize   64      // Console Rx buffer size
byte   RxBaseC[RxCQsize];   #locate Rx_BaseC = 0x0500   // Console Rx Buffer location

Boolean DEBUG;

   // Tell compiler where to find serial control registers and bits for PIC18Fxxx
#byte   RCREG = 0x0FAE
#byte   RCSTA = 0x0FAB
#define   OERR    1
#define   CREN   4


#int_RDA
void serial_isr()
   {
   // ; test for overrun error
   if (bit_test(RCSTA, OERR))
      {
      bit_clear(RCSTA, CREN);      // clear continous receive bit
      bit_set(RCSTA, CREN);      // set continous receive bit
      }

   RxBaseC[RxHeadC++]=getc();
   RxHeadC %= RxCQsize;
   }



void SrvCmd(char *source)
///////////////////////////////////////////////////////////////////////////
//
// SrvCmd
//
//   Parses commamds past in the source string
//   RESET         Reset LIA
//
// On Exit:
//
// Calls:
//
///////////////////////////////////////////////////////////////////////////
   {
   char const MRESET[] = "RESET";
   char const INIT[] = "INIT";
   char const MDEBUG[] = "DEBUG";
   char const MUNDEBUG[] = "UNDEBUG";
   byte x,y;
   char *ptr;
   int8   Response;

   // strip leading spaces
   ptr = source;
   while (*ptr == ' ')
      ptr++;

   for (x=0, y=5; (x < y) && (MRESET[x] == toupper(ptr[x])) && ptr[x]; x++)
      ;
   if (x == y)
      {
      printf("RESET command received\r\n");
      delay_ms(100);
      reset_cpu();
      return;
      }


   for (x=0, y=5; (x < y) && (MDEBUG[x] == toupper(ptr[x])) && ptr[x]; x++)
      ;
   if (x == y)
      {
      printf("Enabling DEBUG mode\r\n");
      DEBUG = true;
      return;
      }
   //......

   //.......
   }



char getc_QConsole()
///////////////////////////////////////////////////////////////////////////
//
// getc_QConsole
//
//   Routine to read (remove) a byte from the Console receive buffer
//
// On Entry:
//   Rx_TailC   points to next byte to be read from the logger receive buffer
//
// On Exit:
//   Rx_TailC   points to the next position in the buffer
//
//
// Calls:
//
///////////////////////////////////////////////////////////////////////////
   {
   Char RxChar;

   RxChar = RxBaseC[RxTailC++];
   RxTailC %= RxCQSize;
   return(RxChar);
   }


void ServiceRxQConsole()
///////////////////////////////////////////////////////////////////////////
//
// ServiceRxQConsole
//
//   Basic polled Console Rx Q service subroutine (NON BLOCKING)
//   Receives a byte from the Console Rx buffer and queues it to the
//   console command buffer.
//
//  Once a <CR> has been detected SrvPCSMessage is invoked.
//
// On Exit:
//   RxTailC = RxHeadC   (Console buffer emptied)
//
// Calls:
//   putc_QModem
//
///////////////////////////////////////////////////////////////////////////
   {
   char LastC;

   while (RxTailC != RxHeadC)
      {
      LastC = getc_QConsole();

      switch (LastC)
         {
         case 0x0d:      // <CR>
            CCRC[CntCmdC] = 0;      // terminate the string with a NULL
            SrvCmd(CCRC);         // go service the command
            CntCmdC = 0;         // initialise number of characters in the command buffer
            break;

         case 0x0a:       // <LF>
            break;

         default :
            CCRC[CntCmdC] = LastC;   // put into the command construction register
            CntCmdC = (CntCmdC + 1) % CCRSize;   // ensure command register does not overflow
            break;
         }
      }
   }




void main ()
   {
   int i;

   disable_interrupts(global);
//   setup_wdt(WDT_ON);
   restart_wdt();

   // initialise Console receive buffer pointers
   RxHeadC = 0;
   RxTailC = 0;

   // initilise Console flow control status and timer
   CntCmdC = 0;      // initialise number of characters in the command buffer

   // initialise the console receive USART status
   i = RCREG;
   i = RCREG;
   if (Bit_test(RCSTA,OERR))
      {
      // here on overrun error - need to reset the USART
      bit_clear(RCSTA,CREN);      // clear continous receive bit
      bit_set(RCSTA,CREN);      // set continous receive bit
      }

   // disable UART Rx interrupt
   clear_interrupt(INT_RDA);      // clear interrupt flag
   enable_interrupts(INT_RDA);      // enable the interrupt
   enable_interrupts(global);


   for (;;)
      {

      // ....

      // service the Console Rx Q
      ServiceRxQConsole();

      // ....

      }
   }


_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
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