#include<p18f4520.h>
#include<delays.h>
#include<system4520.h>
#include<stdio.h>
#include<adc.h>
#define ButA PORTAbits.RA0
#define ButB PORTAbits.RA1
#define IN3 PORTCbits.RC4
#define IN4 PORTCbits.RC7
#define EN2 CCPR2L
#define A PORTAbits.RA5
#define B PORTAbits.RA2
void run_cw(unsigned int speed);
void run_ccw(unsigned int speed);
void stop (unsigned int data);
void motor_run(unsigned int speed, unsigned long degree);
unsigned int initA, initB,end,stopA,stopB;
unsigned long bigdegree;
unsigned long desire_angle;
unsigned long smalldegree;
unsigned int limit;
unsigned int countAB;
unsigned int countover = 0;
unsigned long countstop;
unsigned long gear_ratio;
unsigned int n;
unsigned int error;
char dispAB[16];
char dispOV[16];
char dispER[16];
void main(void)
{
TRISA = 0b11111111; //configure PORTA I/O direction 0b11100111;
TRISB = 0b00000000; //configure PORTB I/O direction
TRISC = 0b00000000;
IN4 = 0;
IN3 = 0;
ADCON1 = 0b00001110; //configure PORTA as digital I/O
CCP2CON = 0b00001110;
PR2 = 0xFF; //PWM Period Setting 244.14Hz
T2CON = 0b00000110; //Timer2 On, prescale 16
PORTBbits.RB1=0;
PORTBbits.RB2=0;
lcd_init();
while(1)
{
if(PORTAbits.RA4==0)
{
motor_run(255,90); //run motor at speed 254 for 360 degree
}
}
}
void motor_run(unsigned int speed, unsigned long degree)
{
desire_angle = degree;
//in this case gear ratio is 1:300
gear_ratio = 300;
//convert the desired agle to the total angle at the rear shaft (multiply gear ratio)
smalldegree = desire_angle *gear_ratio;
//12 count per revolution at the rear shaft
//meaning each count represent 30 degree
//to calculate how many counts needed for the desire angle
//we divide total angle at the rear shaft with 30 degree
limit = smalldegree/30;
error = limit-countover;
clear_screen();
cursor_set(0,7);
n=sprintf (dispER, "%d ",error);
WriteS(dispAB);
countAB=0; //reset the counter
while(countAB < error) //while counter is in the limit
{ //motor will overshoot because it can not sudden stop
initA = A; //get current A value //overshoot depends on load and speed of the motor
initB = B; //get current B value
do
{
run_cw(speed); //run motor in clockwise direction with user defined speed
}while(initA ==A && initB ==B); //continue run until state change
countAB++; //increment counter for each state change
stopA=A; //stopA store the current A value
stopB=B; //stopB store the current B value
}
IN3 = 0;
IN4 = 0;
cursor_set(0,0);
n=sprintf (dispAB, "%d ",countAB);
WriteS(dispAB);
//once program exit the previous while loop
//meaning that the motor has reached the desired angle
//countover=0; //reset overshoot counter
end=0; //reset end function flag
while(end==0) //while the flag is not set
{
do
{
if(countstop>10000) end=1; //set end flag if stop counter >10000
else
stop(0); //brake the motor
countstop++; //stop counter increment by 1
}while(stopA==A && stopB==B && end==0); //loop if states do not change
//if states change,meaning overshoot occur
countover++; //increment overshoot counter
countstop=0; //clear stop counter
stopA=A; //stopA store the current A value
stopB=B; //stopB store the current B value
}
cursor_set(1,0);
n=sprintf (dispOV, "%d ",countover);
WriteS(dispOV);
}
//==================================================
// BASIC MOTOR FUNCTION
//==================================================
void run_cw (unsigned int speed) //run motor in clockwise direction
{
IN3 = 1;
IN4 = 0;
EN2 = speed;
}
void run_ccw (unsigned int speed) //run motor in counter clockwise direction
{
IN3 = 0;
IN4 = 1;
EN2 = speed;
}
void stop (unsigned int data) //brake/stop the motor motion
{
IN3 = 1;
IN4 = 1;
EN2 = 254;
// delay(data);
}
Users browsing this forum: No registered users and 5 guests