asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
interrupt driven RS-232 for PIC16 w/o EUSART hardware |
Posted: Wed Mar 04, 2015 3:00 pm |
|
|
Code: | // this is an interrupt driven routine that enhances the soft
// RS-232 EUSART function of the CCS compiler. In this example
// using 4.9152mhz external clock for zero error baud division
// NB: max safe baud rate 9600 using 9.83 mhz clock up to 19200
// MY received CTL PACKET IS ONLY 10 CHARS LONG
// SO USING BUFFER OF 16 in this example
// timer0 used to insure incoming packets are complete
// before attempting a reply - to avoid char distortion and loss
// due to interruption caused by the receive service,
// while transmitting. do not transmit unless
// you are clear of incoming characters
// NB: transmitting is NEVER safe in this mode
// if ANY ints are enabled. suggest disabling int_ext before
// a transmit attempt
#include <16f818.h>
#include <stdlib.h>
#Fuses EC_IO,NOWDT,PUT, MCLR,BROWNOUT,NOLVP,CPD,NOCPD,WRT,NODEBUG,CCPB3,NOPROTECT
#use delay( clock=4915200)
#use rs232(baud=9600 , xmit=PIN_B1, rcv=PIN_B0, sample_early)
#use fast_io(A)
#use fast_io(B)
#bit T0IF = 0x0B.2 // flag in INTCON reg
#define BUFFER_SIZE 16
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0,next_out = 0;
#define bkbhit (next_in!=next_out)
byte bgetc(void) {
byte q; q=buffer[next_out++]; // NOTE : using GLObal return char variable
if (BUFFER_SIZE==next_out) next_out=0;
return(q);
}
#int_ext
void serial_isr() {
static int t;
// NOTE: CCS getc() in this mode reads portB and clears the port INT
buffer[next_in]=getc(); t=next_in++;
if (BUFFER_SIZE==next_in) next_in=0;
if(next_in==next_out) next_in=t; // Buffer full !!
}
//===================================
void main()
{
char v; char t,z; unsigned int8 a,b;
setup_oscillator ( 4915200 ); //
output_a (0); output_b (0); set_tris_a (0xFF); // - all INPUT
setup_timer_0( RTCC_DIV_64); // set for rollovers ~12 ms holdoff later
set_tris_b (0b00000001); output_b (0);
clear_interrupt( int_ext );
EXT_INT_EDGE(H_TO_L);
enable_interrupts(int_ext);
enable_interrupts(global);
printf ("*Hello*\r"); // just check output
delay_ms(2000); // delay to let me send a packet in
while (1) { // now how to getc AND send at same time..
a=next_in; // get mark of RX buffer 'in' position
T0IF = 0; b=4; // clear t0if and do 4x12 MS ~ 50 msecs +/-
while(b){ // TIMER0 just rolls over endlessly
if ( T0IF ) { // not using INTS - just watching timer
--b; T0IF=0;
if (!b && a==next_in ){ // unload IF no NU chars R caught
// insert your (safer) xmit routine here
while (bkbhit){ z=bgetc();} //simple test
} // Implied ELSE - keep waiting
} // END : IF t0if
} // END : WHILE B
} // END : while 1
}
//******
|
|
|