#include <p18f4520.h>
#include <usart.h>
#include <timers.h>
#pragma config OSC = HS
#pragma config PWRT = OFF
#pragma config MCLRE = ON
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config DEBUG = ON
#pragma config PBADEN = OFF
#define SERVO_PULSE_HIGH LATCbits.LATC0 =1
#define SERVO_PULSE_LOW LATCbits.LATC0 =0
#define CONVERT_mS_PULSE 10000.0
void chk_handler (void);
void chk_handler_low (void);
unsigned char val1=0,val2=0,int1=0,int2=0,servo=0,dc=0,state=0,state1=0;
unsigned int timer0=0,t1=0,timer1=0;
unsigned long s=0,d=0;
float t=0,dt=0;
////high priority interrupt
#pragma code interrupt = 0x8
void _interrupt (void)
{
_asm goto chk_handler _endasm
}
///LOW priority interrupt
#pragma code interruptlow = 0x18
void interruptlow (void)
{
_asm goto chk_handler_low _endasm
}
#pragma code
#pragma interruptlow chk_handler_low
void chk_handler_low (void)
{
unsigned char c=0;
/* as timer is included in low priority interrupt so when its interrupt come*/
if (INTCONbits.TMR0IF)
{
///we r deviding the 20ms as///////
//0----->servo on time(ms) for state 0///
//and off time=20-servo on time for state 1----->19////
if(state==0)
{
////for state zero on the on servo///
PORTCbits.RC0=1;
///time devision if less then 50 pressed the its move right but with deviosion will be of 8us/////
if(servo<=50)
{
t=servo*.008+.960;///0-50 the devision will be 8us
}
///if greater than 50 its moves let but devision of 8.68us////
else
{
t=servo*.00868+.960;
}
}
/////servo of for 20-ontime////
else if(state==1)
{
PORTCbits.RC0=0;
////time interrupt will come after 2ms-ontime for making calculation easy for next 18ms
t=2.0-t;
}
else if(state>1&&state<19)
{
PORTCbits.RC0=0;
////1ms timer interrupt
t=1.0;
}
///////put value to timero variable/////
timer0=(unsigned int)(65536-(t*CONVERT_mS_PULSE));//(t*CONVERT_mS_PULSE));
INTCONbits.TMR0IF=0;
T0CONbits.TMR0ON = 1;
////write timer0
WriteTimer0(timer0);
state++;
//////after 20ms state value should be zero for next pulse
if(state>19)
state=0;
}
if (PIR1bits.TMR1IF)
{
if(state1==0)
{
////for state1 zero on the on DC///
PORTCbits.RC1=1;
///time devision if less then 150 pressed the its move right but with deviosion will be of 8us/////
dt=dt*.010;///the devision will be 10us
}
else if(state1==1)
{
PORTCbits.RC1=0;
////time interrupt will come after ontime for making calculation easy for next
dt=1.0-dt;
}
///////put value to timero variable/////
timer1=(unsigned int)(65536-(dt*CONVERT_mS_PULSE));
PIR1bits.TMR1IF=0;
T1CONbits.TMR1ON = 1;
////write timer0
WriteTimer1(timer1);
state1++;
//////after 20ms state value should be zero for next pulse
if(state1>1)
state1=0;
}
if(PIR1bits.RCIF==1)
{
c = ReadUSART();
WriteUSART(c);
////if value is in between then get as data////
if (c >= '0' && c <= '9')
{
///ascii o 0 is 48 and 1 is 48 and so on////
////so subsrtat 48 or getting actual value/////
c=c-48;
val1=val1*10+c;
// PORTD=val1;
}
///////////////enter/////////////
////if enetr pressed then get value///
else if(c==13)
{
val2=val1;
// PORTD=val2;
///is this for servo////
if(val2<100&&val2>=0)
{
servo=val2;
}
////or for dc///
if(val2>=100&&val2<200)
{
////if for dc subtratc from 100 as user is enterring off by 100 for dc///
dc=val2-100;
}
//PORTD=servo;
val1=0;
}
////////back space//////////////
else if(c==8)
{
val1=(val1-(val1%10))/10;
PORTD=val1;
}
c=0;
// PORTD=c;
PIR1bits.RCIF = 0;
}
}
#pragma code
#pragma interrupt chk_handler
void chk_handler (void)
{
if(INTCONbits.INT0IF)////if from portb 1st pin(servo robot)
{
if(servo==0)
{
int1++;
INTCONbits.INT0IF = 0;
INTCONbits.INT0IE = 1;
if(int1==1)//////rising edge
{
PORTCbits.RC0 = 1;
INTCON2bits.INTEDG0 = 0;///set interrupt on falling edge
}
if(int1==2)////falling edge
{
PORTCbits.RC0 = 0;
INTCON2bits.INTEDG0 = 1;///set interrupt on rising edge edge
int1=0;
}
}
else
{
INTCONbits.INT0IF = 0;
INTCONbits.INT0IE = 1;
}
}
if(INTCON3bits.INT1IF)////if from portb 1st pin(servo robot)
{
if(dc==0)
{
int2++;
INTCON3bits.INT1IF = 0;
INTCON3bits.INT1IE = 1;
if(int2==1)//////rising edge
{
PORTCbits.RC1 = 1;
INTCON2bits.INTEDG1 = 0;///set interrupt on falling edge
}
if(int2==2)////falling edge
{
PORTCbits.RC1 = 0;
INTCON2bits.INTEDG1 = 1;///set interrupt on rising edge edge
int2=0;
}
}
else
{
INTCON3bits.INT1IF = 0;
INTCON3bits.INT1IE = 1;
}
}
}
void main (void)
{
INTCONbits.INT0IF = 0;///interrupt0 interrupt flag set to 0
INTCONbits.INT0IE = 1;///interrupt0 enable
INTCON2bits.INTEDG0 = 1;//interrupt on rising edge
TRISCbits.TRISC0 = 0;/////////////////O/p for servo
TRISCbits.TRISC1 = 0;/////////////////O/p for servo
TRISBbits.TRISB0 = 1;/////interrupt i/p
TRISBbits.TRISB1 = 1;/////interrupt i/p
INTCON3bits.INT1IE=1;///EXTERNAL INTERRUPT 1
INTCON3bits.INT1IF=1;///EXTERNAL INTERRUPT FLAG CLEARED
//INTCON3bits.INT2IP=0;
//INTCON3bits.INT1IP=0;
PORTC = 0x00;/////no movement
TRISD = 0;////CHECKING WHETHER IT IS GETTING DATA FROM SERIAL
PORTD=0;
/* 4800 baud for 4 mhz crystal by adjusting value to 64, */
OpenUSART (USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_LOW, 64);
/* Display a prompt to the USART */
putrsUSART ((const far rom char *)"\n\rEnter a digit 0-99 for servo and 100-199 for dc motor!\n\r");
/* Enable interrupt priority */
RCONbits.IPEN = 1;
/* Clear the peripheral interrupt flags */
PIR1 = 0;
//////TIMER0///////////
t=1.0;
dt=0;
OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_1);
/*timer0 interrupt priority low*/
INTCON2bits.TMR0IP=0;
////timer interrupt calculation ///
timer0=(unsigned int)(65536-(t*CONVERT_mS_PULSE));//(t*CONVERT_mS_PULSE));
WriteTimer0(timer0);
///TIMER1/////////
///interrupt priority low//
IPR1bits.TMR1IP=0;
OpenTimer1(TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_1 & T1_OSC1EN_OFF);
T1CONbits.TMR1CS = 0; //Timer 1Clock internal source
timer1=(unsigned int)(65536-(dt*CONVERT_mS_PULSE));//(t*CONVERT_mS_PULSE));
WriteTimer1(timer1);
/* Make receive interrupt high priority */
IPR1bits.RCIP = 0;
/* Enable all high priority interrupts */
INTCONbits.GIEH = 1;
/* Enable all low priority interrupts */
INTCONbits.GIEL = 1;
/* Loop forever */
while (1)
{
if(servo>0)/////ON
{
//PORTDbits.RD3=~PORTDbits.RD3;
T0CONbits.TMR0ON = 1;
}
else//////////OFF
{
T0CONbits.TMR0ON = 0;
}
if(dc>0)
{
T1CONbits.TMR1ON = 1;
}
else
{
T1CONbits.TMR1ON = 0;
}
}
}