|
|
View previous topic :: View next topic |
Author |
Message |
ikeme
Joined: 23 Nov 2005 Posts: 2 Location: uk
|
PIC C |
Posted: Mon Nov 28, 2005 9:48 am |
|
|
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: 1635 Location: Perth, Australia
|
|
Posted: Mon Nov 28, 2005 10:11 am |
|
|
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
|
|
Posted: Mon Nov 28, 2005 11:20 am |
|
|
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: 1635 Location: Perth, Australia
|
|
Posted: Mon Nov 28, 2005 6:15 pm |
|
|
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!! |
|
|
|
|
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
|