Microchip pic 18f452 interrupt rx (recieve) test
less or zero eorr overflow errors
11059200 quartz crystal x 4 (bit overclocked 40mhz pic)
115200 baud 8n1 xon /xoff flowcontrol

Low quality movie of stepper driven xy table with this source


// Copyright 2004 Luberth monkeytail quicknet.nl
// THIS PROGRAM IS OPENSOURCE BUT NOT PUBLIC DOMAIN
// DO NOT PUBLISCH OR PUT IT ON THE WEB
// Copyright 2004 Luberth monkeytail quicknet.nl
// Http://www.luberth.com
// Http://cstep.luberth.com
// Http://pstep.luberth.com

// C program FOR PIC18F452 MICROCHIP MCC18-MPLAB
// PStep      
// Pic18f452 serial 3 axis stepper
// 24 bit 3 axis linear interpolation

// 110592Mhz quartz x4 pll  = overclocked 40mhz pic
// BAUDRATE 115200 see/try if i can use Xon/Xoff flowcontrol
// portb 7, 5, 3 are connected to steppuls wires for x, y, z axis
// portb 6, 4, 2 are connected to direction wires for x, y, z axis
   

#include <p18F452.h>   // for TRISB and PORTB declarations
#include <xlcd.h>
#include <delays.h>
#include <stddef.h>
#include <stdlib.h>
#include <usart.h>



// c:\mcc18\bin>mcc18 --help-config -p=18f452
// Configuration settings available for processor 18F452

//#pragma config OSC = LP            //Oscillator Selection:LP
//#pragma config OSC = XT            //Oscillator Selection:XT
//#pragma config OSC = HS            //Oscillator Selection:HS
//#pragma config OSC = RC            //Oscillator Selection:RC
//#pragma config OSC = EC            //Oscillator Selection:EC-OSC2 as Clock Out
//#pragma config OSC = ECIO          //Oscillator Selection:EC-OSC2 as RA6
#pragma config OSC = HSPLL         //Oscillator Selection:HS-PLL Enabled
//#pragma config OSC = RCIO          //Oscillator Selection:RC-OSC2 as RA6
               
#pragma config OSCS = OFF           //Osc. Switch On Off

#pragma config    PWRT = ON              //Power Up Timer
 
#pragma config BOR = ON               //Brown Out Reset:
  
#pragma config BORV = 45               //Brown Out Voltage:4.5V
// #pragma config BORV = 42         //Brown Out Voltage:4.2V
// #pragma config BORV = 27         //Brown Out Voltage:2.7V
// #pragma config BORV = 25         //Brown Out Voltage:2.5V

 
#pragma config WDT = OFF             // Watchdog Timer
 
//#pragma config WDTPS = 1               //Watchdog Postscaler:1:1
//#pragma config WDTPS = 2               //Watchdog Postscaler:1:2
//#pragma config WDTPS = 4               //Watchdog Postscaler:1:4
//#pragma config WDTPS = 8               //Watchdog Postscaler:1:8
//#pragma config WDTPS = 16              //Watchdog Postscaler:1:16
//#pragma config WDTPS = 32              //Watchdog Postscaler:1:32
//#pragma config WDTPS = 64              //Watchdog Postscaler:1:64
//#pragma config WDTPS = 128             //Watchdog Postscaler:1:128

#pragma config CCP2MUX = OFF           //CCP2 Mux:Disable (RB3)

#pragma config STVR = OFF              //Stack Overflow Reset:Disabled
    
#pragma config LVP = OFF               //Low Voltage ICSP:Disabled
       
#pragma config DEBUG = OFF             //Background Debugger Enable:Disabled
   
#pragma config CP0 = OFF               //Code Protection Block 0:Disabled
#pragma config CP1 = OFF               //Code Protection Block 1:Disabled
#pragma config CP2 = OFF               //Code Protection Block 2:Disabled
#pragma config CP3 = OFF               //Code Protection Block 3:Disabled
#pragma config CPB = OFF               //Boot Block Code Protection:Disabled
#pragma config CPD = OFF               //Data EEPROM Code Protection:Disabled
#pragma config WRT0 = OFF              //Write Protection Block 0:Disabled
#pragma config WRT1 = OFF              //Write Protection Block 1:Disabled
#pragma config WRT2 = OFF              //Write Protection Block 2:Disabled
#pragma config WRT3 = OFF              //Write Protection Block 3:Disabled
#pragma config WRTB = OFF              //Boot Block Write Protection:Disabled  
#pragma config WRTC = OFF              //Configuration Register Write Protection:Disabled
#pragma config WRTD = OFF              //Data EEPROM Write Protection:Disabled
#pragma config EBTR0 = OFF             //Table Read Protection Block 0:Disabled
#pragma config EBTR1 = OFF             //Table Read Protection Block 1:Disabled
#pragma config EBTR2 = OFF             //Table Read Protection Block 2:Disabled
#pragma config EBTR3 = OFF             //Table Read Protection Block 3:Disabled
#pragma config EBTRB = OFF             //Boot Block Table Read Protection:Disabled
// end c:\mcc18\bin>mcc18 --help-config -p=18f452
// end Configuration settings available for processor 18F452


// find maximum of a and b   used in line3d
#define MAX(a,b) (((a)>(b))?(a):(b))

// absolute value of a used in line3d
#define ABS(a) (((a)<0) ? -(a) : (a))

// take sign of a, either -1, 0, or 1 used in line3d
#define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)

#define SL signed short long  // Save some ink when printing ;-)
                              // signed short long is 24 bit
                              // -8,388,608 to 8,388,607
                              // 4000steps a rotation 3mm spindel
                              // 8milion/4000 = 2997 spindle rotations
                              // x3mm = -6291mm to +6291mm,
                              // Hmmmm, my table is only 500mm
                              // So 24 bit is more the enough

 
void point3d(SL x, SL y, SL z);
void line3d(SL x1, SL y1, SL z1, signed long x2, signed long y2, signed long z2);   
void main(void);
void DoCommand(void);                    // Processes command input strings
void Setup(void);
void puutch(unsigned char byyte);                        // Configures peripherals and variables
void clear_inpbuf(void);

const rom char ready[] = "*";
const rom char badcmd[] = "\n\rERROR!\n\r";

SL         x=0,                   // SL = Signed short Long = 24bits
        y=0,
        z=0,
         oldX=0,
        oldY=0, 
        oldZ=0,
        t=0,
stepcount;

signed char sx=0,             // sx can be -1 or 0 or 1
            sy=0,
            sz=0;              // 8bit= -127 to 128      
                           
char     inpbuf[8],                        // Input command buffer
         parameters,
        udata,                             // Received character from USART
        temp_string[15];
                                         // Index to profile data
unsigned char     i,
                byyte,                        // index to ASCII buffer
                comcount,                // index to input string                               
                segnum;                    // Current executing segment
int     ivar,
        jvar,
        period,
        f,
        oerrcount=0;

signed long x2,
            y2,
            z2;

float stepdelay=0;

long     startdelay=0,
         enddelay=40;
            
  void usartRx(void);

#pragma code HIGH_INTERRUPT_VECTOR=0x8

void high_ISR(void){
if(PIR1bits.RCIF==1){ //An rx usart interrupt
_asm
goto usartRx
_endasm
}
}
#pragma code
#pragma interrupt usartRx

void usartRx(void){
TXREG=(0x13); //xoff
while(PIR1bits.RCIF){
udata=ReadUSART(); //Read usart
}
switch(udata)
    {       
            case 0x11:  SetCGRamAddr( 0x00 );
                        SetDDRamAddr( 0x00 );
                        putrsXLCD( "0x11     " );
                           break;   
            case 0x13:  SetCGRamAddr( 0x00 );
                        SetDDRamAddr( 0x00 );
                        putrsXLCD( "0x13     " );
                           break;               
            case 'D':   //SetCGRamAddr( 0x00 );
                        //SetDDRamAddr( 0x00 );
                        //putrsXLCD( "PenDown       " );
                        PORTBbits.RB0=0;    //penup pendown solenoid inverted
                        PORTBbits.RB1=1;    //penup pendown solenoid
                           break;
            case 'R':   //SetCGRamAddr( 0x00 );
                        //SetDDRamAddr( 0x00 );
                        //putrsXLCD( "PenRelative   " );
                           break;
            case 'U':   //SetCGRamAddr( 0x00 );
                        //SetDDRamAddr( 0x00 );
                        //putrsXLCD( "PenUp         " );
                        PORTBbits.RB0=1;    //penup pendown solenoid inverted
                        PORTBbits.RB1=0;    //penup pendown solenoid
                           break;
       
              case ',':    parameters=',';
                        DoCommand();                // process the string
                        clear_inpbuf();
                        i = 0;                    // clear the buffer index
                           break;
                         
                     
              case ';':   parameters=';';
                        DoCommand();            //Carriage return (ASCII 0x0D)     "\\r"
                        clear_inpbuf();                        // process the string
                          i = 0;                    // clear the buffer index
                           break;

        case '-':
        case '+':
        case '0':
        case '1':
        case '2':     // should be another way to do this
        case '3':   // MOET ANDER KUNNEN MAAR WEET NIET HOE
        case '4':   // something like / IETS VAN CASE [0..9]:
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':    
                    inpbuf[i] = udata;        // get received char
                    i++;                    // increment buffer index
                    //if(i > 7)i = 0;            // If more than 8 chars
                    break;                    // received before getting
                                                 // the buffer index
                                        
                         
                         
                                     
      
                       

        default:    //putrsUSART("\r\n default");
                    SetDDRamAddr( 0x00 );
                    putrsXLCD( "def1" );
                    break;

   

        }                 // end switch(udata)
   
TXREG=(0x11);  //xon


}

 void enableHighInterrupts(void){
//RCONbits.IPEN=1;
//INTCONbits.GIEH=1;
/* Enable interrupt priority */
RCONbits.IPEN = 1;
/* Make receive interrupt high priority */
IPR1bits.RCIP = 1;
/* Enable all high priority interrupts */
INTCONbits.GIEH = 1;
}

//char X, Y, Z;

/********************************************************************/
void setup(void)
{

//    TRISA = 0b00000000; 
//    PORTA = 0;                      // Turn Port A to Digital Outputs
   //    ADCON1 = 0b00000111;

    TRISB = 0;                        // configure PORTB for output
    PORTB = 0;                          // clear PORTB   
 // EnablePullups();                   // Enable PORTB pullups
   
    //TRISC = 0b00000000;                // 0xdb;    // db=1101 1011 ff=1111 1111
//    PORTC = 0;                        // Clear PORTC

    TRISD = 0;                         // PORTD all outputs.
    PORTD = 0;                        // Clear PORTD

    TRISE = 0;
    PORTE = 0;                        // Clear PORTE



    i = 0;                            // Receive buffer index
    comcount = 0;                    // Input command index
    udata = 0;                        // Holds USART received data
    parameters=' ';


//    ; Baud Values with BRGH = 0
//    ; ((20000000/desiredspeed)/64)-1
//    ; Baud Values with BRGH = 1
//    ; ((20000000/desiredspeed)/16)-1

//SPBRG = 129;       // 19200 BRGH=0 40Mhz
// SPBRG = 64;        // 9600  BRGH=0 40Mhz                        
//SPBRG = 20;        // 21.7 115200  BRGH=1 40Mhz
//TXSTA=0b00100100;          // setup USART transmit
//        *        = TXEN=1
//           *     = BRGH=
//RCSTA=0b10010000;           // setup USART receive
//      *          = SPEN=1 
//         *       = CREN=1 
OpenUSART(    
            USART_TX_INT_OFF &
            USART_RX_INT_ON &      //recieve interrupt on
            USART_ASYNCH_MODE &
            USART_EIGHT_BIT &
            USART_CONT_RX &
            USART_BRGH_HIGH,
            23 );    //quartz 11059200   x4 pll  baud115200
//Interrupt on Transmission:
//USART_TX_INT_ON Transmit interrupt ON
//USART_TX_INT_OFF Transmit interrupt OFF
//Interrupt on Receipt:
//USART_RX_INT_ON Receive interrupt ON
//USART_RX_INT_OFF Receive interrupt OFF
//USART Mode:
//USART_ASYNCH_MODE Asynchronous Mode
//USART_SYNCH_MODE Synchronous Mode
//Transmission Width:
//USART_EIGHT_BIT 8-bit transmit/receive
//USART_NINE_BIT 9-bit transmit/receive
//Slave/Master Select*:
//USART_SYNC_SLAVE Synchronous Slave mode
//USART_SYNC_MASTER Synchronous Master mode
//Reception mode:
//USART_SINGLE_RX Single reception
//USART_CONT_RX Continuous reception
//Baud rate:
//USART_BRGH_HIGH High baud rate
//USART_BRGH_LOW Low baud rate
}

//**********************
void clear_inpbuf(void)
{
    inpbuf[0]='\0';
    inpbuf[1]='\0';
    inpbuf[2]='\0';
    inpbuf[3]='\0';        //CLEAR INPBUF
    inpbuf[4]='\0';          // MOET MAKKELIJKER KUNNEN
    inpbuf[5]='\0';       // must be an easier way to clear inpbuf
    inpbuf[6]='\0';
    inpbuf[7]='\0';
}







//*****************************************************
void main(void)
{   
    int t;
    char mybuff [32];
char cgaddr = 0x1F;
char ddaddr = 0x40;

    setup();                 //    configure port and baudrate
 enableHighInterrupts();   

// configure external LCD

//putrsXLCD("Hello World");
//WriteDataXLCD("data"); //write to LCD


//for(t=1; t<=30; t++) putrsUSART("\r\n_");    // blank terminal screen with "_"

//putrsUSART("\r\nBlink LED!");
i=0;
while(i <= 5){   
    for(t=1; t<=20000; t++)PORTDbits.RD3 =1;
    for(t=1; t<=20000; t++)PORTDbits.RD3 =0;
    i++;
}
//putrsUSART("\r\nBlink LED => Done!");

//putrsUSART("\r\nPIC18F452 3axis Serial Stepper");
//putrsUSART(ready);     // ready text is defined at start of this c source const ready
putrsUSART("Ready to recieve a file");

   
OpenXLCD(FOUR_BIT & LINES_5X7);//EIGHT_BIT & LINES_5X7

while( BusyXLCD() );
//WriteCmdXLCD(1);  //Clear display
SetCGRamAddr( 0x00 );
SetDDRamAddr( 0x00 );
WriteCmdXLCD( CURSOR_OFF );
//putrsXLCD( "Hello World" );
putrsXLCD( "PStep" );
SetCGRamAddr( 0x40 );
SetDDRamAddr( 0x40 );
//putrsXLCD( "How are U today?" );
putrsXLCD( "                " );

//WriteCmdXLCD(1);  //Clear display
while(1)                            // Loop forever
{

if(RCSTAbits.FERR){
    SetCGRamAddr( 0x40 );
    SetDDRamAddr( 0x40 );
    putrsXLCD( "FERR error  " );
}
if(RCSTAbits.OERR)
{    oerrcount=oerrcount+1;
    SetCGRamAddr( 0x00 );
    SetDDRamAddr( 0x00 );
    putrsXLCD( "OERR error  " );
    putsXLCD((itoa(oerrcount, temp_string)));
    SetCGRamAddr( 0x40 );
    SetDDRamAddr( 0x40 );
    putrsXLCD("Overflow Counter ");
RCSTAbits.CREN=0;
RCSTAbits.CREN=1;
}   

   
//TXREG=(0x11);            // 0x11 17 xon       
//while(!PIR1bits.RCIF){} // wait loop for sometingh to recieve (main hang loop)//Nop();
//Nop();
//TXREG=(0x13);            // 0x13 19 xoff
//udata = RCREG;            // move rcreg int udata
/*
    switch(udata)
    {       
            case 0x11:  SetCGRamAddr( 0x00 );
                        SetDDRamAddr( 0x00 );
                        putrsXLCD( "0x11     " );
                           break;   
            case 0x13:  SetCGRamAddr( 0x00 );
                        SetDDRamAddr( 0x00 );
                        putrsXLCD( "0x13     " );
                           break;               
            case 'D':   //SetCGRamAddr( 0x00 );
                        //SetDDRamAddr( 0x00 );
                        //putrsXLCD( "PenDown       " );
                        PORTBbits.RB0=0;    //penup pendown solenoid inverted
                        PORTBbits.RB1=1;    //penup pendown solenoid
                           break;
            case 'R':   //SetCGRamAddr( 0x00 );
                        //SetDDRamAddr( 0x00 );
                        //putrsXLCD( "PenRelative   " );
                           break;
            case 'U':   //SetCGRamAddr( 0x00 );
                        //SetDDRamAddr( 0x00 );
                        //putrsXLCD( "PenUp         " );
                        PORTBbits.RB0=1;    //penup pendown solenoid inverted
                        PORTBbits.RB1=0;    //penup pendown solenoid
                           break;
       
              case ',':    parameters=',';
                        DoCommand();                // process the string
                        clear_inpbuf();
                        i = 0;                    // clear the buffer index
                           break;
                         
                     
              case ';':   parameters=';';
                        DoCommand();            //Carriage return (ASCII 0x0D)     "\\r"
                        clear_inpbuf();                        // process the string
                          i = 0;                    // clear the buffer index
                           break;

        case '-':
        case '+':
        case '0':
        case '1':
        case '2':     // should be another way to do this
        case '3':   // MOET ANDER KUNNEN MAAR WEET NIET HOE
        case '4':   // something like / IETS VAN CASE [0..9]:
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':    
                    inpbuf[i] = udata;        // get received char
                    i++;                    // increment buffer index
                    //if(i > 7)i = 0;            // If more than 8 chars
                    break;                    // received before getting
                                                 // the buffer index
                                        
                         
                         
                                     
      
                       

        default:    //putrsUSART("\r\n default");
                    SetDDRamAddr( 0x00 );
                    putrsXLCD( "default" );
                    break;

   

        }                 // end switch(udata)
   
TXREG=(0x11);  //xon
*/
  }                      // end while(1) loop forever

} //end main








void DelayFor18TCY( void )
{
Delay1KTCYx(5); // Delay of 15ms

// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (15ms * 16MHz) / 4
// Cycles = 60,000
return;
}
void DelayPORXLCD (void)
{
Delay1KTCYx(250); // Delay of 15ms

// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (15ms * 16MHz) / 4
// Cycles = 60,000
return;
}
void DelayXLCD (void)
{
Delay1KTCYx(250); // Delay of 5ms

// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (5ms * 16MHz) / 4
// Cycles = 20,000
return;
}









//-------------------------------------------------------------------
// DoCommand()      Processes incoming USART data.
//-------------------------------------------------------------------

void DoCommand(void)
{

    switch(parameters)                                   
        {

        case ',':   x2 = atol(inpbuf);               
                    break;

        case ';':   y2 = atol(inpbuf);           
                   
                        //putsUSART((ltoa(x2, temp_string)));
                   
                    //putsUSART((ltoa(y2, temp_string)));
                   
                    stepdelay=60;
                    //enddelay=45;
                    //SetCGRamAddr( 0x40 );
                    //SetDDRamAddr( 0x40 );
                    //putrsXLCD("X");
                    //putsXLCD((ltoa(x2, temp_string)));
                    //putrsXLCD(" Y");
                    //putsXLCD((ltoa(y2, temp_string)));
                    //putrsXLCD("            ");        
                    line3d(0,0,0,x2,y2,0);  // do a move from     x1 y1 z1  to   x2 y2 z2
                    break;
       
        default:    //putsUSART("\r\n at line 656 \r\n");
                    //putsUSART(ready);
                    break;
         }//switch
   

    //parameters=' ';          //CLEAR PARAMETER


               
}









/******************************/
void point3d(SL x, SL y, SL z)
{

    // Author of line3d.c wrote => output the point as you see fit */
    // Ok, stepoutput to stepperdrives gets here
    // portb 7, 5, 3 are connected to steppuls wires for x, y, z axis
    // portb 6, 4, 2 are connected to direction wires for x, y, z axis
   
    // result -1 or 0 counterclockwise  and  1 clockwise
    if(x-oldX==1) PORTBbits.RB6 = 1;else PORTBbits.RB6 = 0;  // set direction on outputs
    if(y-oldY==1) PORTBbits.RB4 = 1;else PORTBbits.RB4 = 0;  // set direction on outputs
    if(z-oldZ==1) PORTBbits.RB2 = 1;else PORTBbits.RB2 = 0;  // set direction on outputs

    _asm NOP _endasm        //a short pulsdelay
               // 1 or -1   ( || means or)
    if(x-oldX==1 || x-oldX==-1) PORTBbits.RB7 = 1;  // set steppuls if needed
    if(y-oldY==1 || y-oldY==-1) PORTBbits.RB5 = 1;  // set steppuls if needed
    if(z-oldZ==1 || z-oldZ==-1) PORTBbits.RB3 = 1;  // set steppuls if needed

    _asm NOP _endasm        //a short pulsdelay

     PORTBbits.RB7 =0;                                // clear portb 0 steppuls 
    PORTBbits.RB5 =0;                                // clear portb 2 steppuls
    PORTBbits.RB3 =0;                               // clear portb 4 steppuls


    stepcount=stepcount+1; 
    //SetCGRamAddr( 0x00 );
    //SetDDRamAddr( 0x00 );
    //putsXLCD((ltoa(stepcount, temp_string)));              
       
    for(t=stepdelay; t>0; t--);
    //for(t=enddelay; t>0; t--)   
   
    if (stepdelay<4){
        stepdelay=4;
    }else{
        stepdelay=stepdelay-.03;
    }

    oldX = x;
    oldY = y;
    oldZ = z;

}







//**********************************************************
void line3d(SL  x1, SL  y1, SL  z1, signed long  x2, signed  long  y2, signed  long  z2)
  
{   
    SL  x, y, z;
    SL  xd, yd, zd;
    SL  ax, ay, az;
    SL  dx, dy, dz;

    dx = x2 - x1;
    dy = y2 - y1;
    dz = 0;//z2 - z1;

    ax = ABS(dx) << 1;
    ay = ABS(dy) << 1;
    az = 0;//ABS(dz) << 1;

    sx = ZSGN(dx);
    sy = ZSGN(dy);
    //sz = ZSGN(dz);

    x = x1;
    y = y1;
    z = z1;
    stepcount=0;

    if (ax >= MAX(ay, az))            /* x dominant */
    {
        yd = ay - (ax >> 1);
        //zd = az - (ax >> 1);
        for (;;)
        {
            point3d(x,y,z);
            if (x == x2)
            {
                return ;
            }

            if (yd >= 0)
            {
                y += sy;
                yd -= ax;
            }

            //if (zd >= 0)
            //{
            //    z += sz;
            //    zd -= ax;
            //}

            x += sx;
            yd += ay;
            //zd += az;
        }
    }
    else if (ay >= MAX(ax, az))            /* y dominant */
    {
        xd = ax - (ay >> 1);
        //zd = az - (ay >> 1);
        for (;;)
        {
            point3d(x,y,z);
            if (y == y2)
            {
                return ;
            }

            if (xd >= 0)
            {
                x += sx;
                xd -= ay;
            }

            //if (zd >= 0)
            //{
            //    z += sz;
            //    zd -= ay;
            //}

            y += sy;
            xd += ax;
            //zd += az;
        }
    }
    /*else if (az >= MAX(ax, ay))            /* z dominant */
    /*{
        xd = ax - (az >> 1);
        yd = ay - (az >> 1);
        for (;;)
        {
            point3d(x,y,z);
            if (z == z2)
            {
                return ;
            }

            if (xd >= 0)
            {
                x += sx;
                xd -= az;
            }

            if (yd >= 0)
            {
               y += sy;
                yd -= az;
            }

            z += sz;
            xd += ax;
            yd += ay;
        }
    }*/
}









//****************************************************************************************
// end of c program
//****************************************************************************************