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
//****************************************************************************************