Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Interrupt Problems - i need some help about my code

Status
Not open for further replies.

adalah

Newbie level 6
Joined
Mar 2, 2009
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,368
www.ermirco.com/blog

hi all..
i need some help about my code.
hope all the members can help me to solve the problems..
i'm using :

MikroC,
PIC16F877A,
3 servomotor.


#define leftsensor porta.f0
#define rightsensor porta.f2
#define start porta.f4
#define reset porta.f5
#define servo1 portb.f0
#define servo2 portb.f2
#define servo3 portb.f4


int i, cnt ;

void interrupt(void)
{
cnt++;
if ( cnt == 200)
{
cnt = 0;
portb = 0xff;
}

INTCON = 0x20;
}

void LCDfoward();
void walkfoward();
void servo1pos3();
void servo3pos1();


// main program...

void main(){
TRISA=0Xff;
TRISC=0;
PORTA=0;
PORTC=0;

while(1){
if(start == 0){
walkfoward();
}

}
//return;
}



void walkfoward(void)
{

LCDfoward();
servo1pos3();
delay_ms(1000);
servo3pos1();
delay_ms(1000);
}




char *text = "move";
void LCDfoward(void){
TRISC = 0;
Lcd_Init(&PORTC);
Lcd_Cmd (Lcd_CLEAR);
Lcd_Cmd (Lcd_CURSOR_OFF);
Lcd_Out (1, 6, text);
Lcd_Out (2, 5, "foward");
}//~!



void servo1pos3(void)
{
OPTION_REG = 0b10000000; // Assign prescaler to TMR0
TRISB = 0; // PORTB is output
PORTB = 0XFF; // Initialize PORTB
INTCON = 0xA0; // Enable TMRO interrupt
cnt = 0; // Initialize cnt

do
{
if (cnt == 20){
PORTB.f0 = 0;
cnt = 0;
delay_ms(1000); // Toggle PORTB LEDs
}
} while(1);
}//~!



void servo3pos1(void)
{
OPTION_REG = 0b10000000; // Assign prescaler to TMR0
TRISB = 0; // PORTB is output
PORTB = 0XFF; // Initialize PORTB
INTCON = 0xA0; // Enable TMRO interrupt
cnt = 0; // Initialize cnt

do
{
if (cnt == 10){
PORTB.f4 = 0; // Toggle PORTB LEDs
cnt = 0;
delay_ms(1000);
}
} while(1);
}//~!


my problems is:

the command for servo1pos3() is working,
but the program is not move to the next step which is command for servo3pos1().

this my attachment about the circuit and programming.
 

ermicro/blog

Hi adalah,

I guess, you never leave this while


----------------------------------------------------------
void servo1pos3(void)
{
OPTION_REG = 0b10000000; // Assign prescaler to TMR0
TRISB = 0; // PORTB is output
PORTB = 0XFF; // Initialize PORTB
INTCON = 0xA0; // Enable TMRO interrupt
cnt = 0; // Initialize cnt

do
{
if (cnt == 20){
PORTB.f0 = 0;
cnt = 0;
delay_ms(1000); // Toggle PORTB LEDs
}
} while(1); <<<<<<<<<<<<<========================!!!!!!!!!!!!!!!!!!!!!!!!!!!
}//~!
-------------------------------------------------



Gomez

ps.
there is a lot of bad coding style
 

what to comand mikroc change to servo motor

Thanks Gomez..

Can you help me to repair the coding..
i'm new about this.
just try & error..
 

Re: Interrupt Problems

No is not my job ;-))
It was just a friendly hint to review your code again.
Best practice is to study code from another programmer.

Good luck!
Gomez
 

Re: Interrupt Problems

anyone else..
plz help me..

is there any solution to create an angle of servomotor..?
in my problem,
i used 3 servomotor.
each servo will have 3 angle.

now,
i had try using the interrupt,
but it can't run properly..
 

Re: Interrupt Problems

Try this

-----------------------------------------------
unsigned char angle2time_u8(unsigned char angle_u8);

static unsigned char Servo1Angle_u8 = 0;
static unsigned char Servo2Angle_u8 = 0;
static unsigned char Servo3Angle_u8 = 0;

void timerirq_100us_v(void)
{
static unsigned char Timer_u8 = 200;
static unsigned char Servo1_High_u8 = 0;
static unsigned char Servo2_High_u8 = 0;
static unsigned char Servo3_High_u8 = 0;

if(++Timer_u8 >= 200) // 20ms
{
Timer_u8 = 0;

Servo1_High_u8 = angle2time_u8(Servo1Angle_u8);
Servo2_High_u8 = angle2time_u8(Servo2Angle_u8);
Servo3_High_u8 = angle2time_u8(Servo3Angle_u8);
Servo1_Portpin = 1;
Servo2_Portpin = 1;
Servo3_Portpin = 1;
}
else if(Timer_u8 >= Servo1_High_u8)
{
Servo1_Portpin = 0;
}
else if(Timer_u8 >= Servo2_High_u8)
{
Servo2_Portpin = 0;
}
else if(Timer_u8 >= Servo3_High_u8)
{
Servo3_Portpin = 0;
}

}


unsigned char angle2time_u8(unsigned char angle_u8)
{
// function to convert your servo angle to pwm high time
}

void main(void)
{
init_v(); // init ports and timer

while(1)
{
// get your angle and set ServoXAngle_u8
}

}
----------------------------------

Gomez
 

Re: Interrupt Problems

Is this command for CCS..?
Basically,
I use mikroC..

sorry if don't mention it before..
now,
I just try to change it to mikroC command.
 

Re: Interrupt Problems

That's ANSI-C and your compiler shouldn't any problems with. You has just to define your port pins.

#define Servo3_Portpin portb.f0
.....



Gomez
 

Re: Interrupt Problems

I already define the port.
but now,
there are problems at this point:

init_v();

what command should i put.?
sorry for my question..
 

Re: Interrupt Problems

init_v() ist a placeholder for the part which inits your system. But I forgot to insert a prototype for this function.

Add simply
void init_v(void);
at the beginning and fill up this function with your suitably init code

void init_v(void)
{
OPTION_REG = 0b10000000; // Assign prescaler to TMR0
TRISB = 0; // PORTB is output
PORTB = 0XFF; // Initialize PORTB
INTCON = 0xA0; // Enable TMRO interrupt
}

but that's more controller specific and not ANSI.


Gomez
 

Re: Interrupt Problems

And it works? ;-)


Gomez
 

Re: Interrupt Problems

Thanks Gomez..
i'm so sorry that i not respond to your post before.
i had a problem with my computer..

I will try it & inform to you later..
thanks..:D

Added after 13 minutes:

sorry gomez,
i really confused & no idea how to write it.
this is code that I try.

#define servo1 portb.f1
#define servo2 portb.f2
#define servo3 portb.f3



unsigned char angle2time_u8(unsigned char angle_u8);

static unsigned char Servo1Angle_u8 = 0;
static unsigned char Servo2Angle_u8 = 0;
static unsigned char Servo3Angle_u8 = 0;

void timerirq_100us_v(void)
{
static unsigned char Timer_u8 = 200;
static unsigned char Servo1_High_u8 = 0;
static unsigned char Servo2_High_u8 = 0;
static unsigned char Servo3_High_u8 = 0;

if(++Timer_u8 >= 200) // 20ms
{
Timer_u8 = 0;

Servo1_High_u8 = angle2time_u8(Servo1Angle_u8);
Servo2_High_u8 = angle2time_u8(Servo2Angle_u8);
Servo3_High_u8 = angle2time_u8(Servo3Angle_u8);
servo1 = 1;
servo2 = 1;
servo3 = 1;
}
else if(Timer_u8 >= Servo1_High_u8)
{
servo1 = 0;
}
else if(Timer_u8 >= Servo2_High_u8)
{
servo2 = 0;
}
else if(Timer_u8 >= Servo3_High_u8)
{
servo3 = 0;
}

}
void init_v(void)
{

OPTION_REG = 0b10000000; // Assign prescaler to TMR0
TRISB = 0; // PORTB is output
PORTB = 0XFF; // Initialize PORTB
INTCON = 0xA0; // Enable TMRO interrupt

}

unsigned char angle2time_u8(unsigned char angle_u8)
{
// function to convert your servo angle to pwm high time
}

void main(void)
{
init_v(); // init ports and timer

while(1)
{
// get your angle and set ServoXAngle_u8
}

}
[/quote]
 

Re: Interrupt Problems

I didn't make all the work for you.
Some parts are to fill up with your own code, because I don't know your requirements.

1. The function void init_v(void) is to fill up with code to initialize your controller.
- clock
- ports
- uart
- interrupts
- timer with 100µs!
etc.

It depends from type of controller Microchip, Atmel, Renesas, what ever....


2. The function void unsigned char angle2time_u8(unsigned char angle_u8) is to fill up with code to calculate high time of your servo pwm.
http://www.ermicro.com/blog/?p=771 means
0.7ms to 1ms PWM high time turns CW
1.7ms to 2ms PWM high time turns CCW
1.5ms PWM high time turns to center
So you need a transfer function to calculate high time because

high time = f(servo angle)
for 90°=center =>
0-180° => 0.7-2ms => 7-20

0 <= angle_u8 <= 180
7 <= angle2time() <= 20


3.
while(1)
{
// get your angle and set ServoXAngle_u8
}
I guess you want change servo angle at runtime. Anyhow you has to transmit the new servo angle to your controller (UART, SPI, DIP-Switches, ADC what ever). In this while you take the new angles and set ServoXAngle_u8 (X=1|2|3). You has to add some own code to read in new angle values.

Gomez
 

Re: Interrupt Problems

sorry my friends because don't reply this topic.
actually,
this problems related with my previous post.



what i want to do is to create 3 angles for 1 servo motor,
which are -90,0,90.
in my project,
there are 3 servo motor.


for example,
servo1 will turn 90,
servo3 will turn -90,
servo1 will turn -90,
servo2 will turn 90,


i had try to use the interrupts,
but still can't success.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top