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.

8051 motor controller (C programming)

Status
Not open for further replies.

Opel_Corsa

Member level 1
Joined
Nov 13, 2005
Messages
41
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,614
predefined functions in p89v51rd2.h in c

Good day,

I am working on a project, a 'bot, that has 2 wheels, each connected to an encoder rotary.
- encoder 1 is connected to P0_0, P0_1, P0_2/encoder 2 to P1_1, P1_2, P1_3 (P0_1 and P1_2 are grounds).
- each motor is connected to an H-bridge, as expected. the corresponding bridge for motor 1 is connected to pins P3_2 and P3_4 while that of motor 2 is connected to pins P3_3 and P3_5.
- as you may imagine PWM (and a PI controller) is used to make the motors rotate at the same speed.

Now, here's the C code that I have so far: (implemented by taking pieces of code from different places)

UPDATED: THE NEW CODE IS IN THE NEXT MESSAGE!

I would appreciate any help that would get the 'bot moving straight. By the way I don't understand why I can't use interrupt 5 (i.e. Timer 2 overflow) eventhough I have set TR2 = 1 and ET2 = 1. the other 2 interrupts work (1 and 3, for Timers 0 and 1).

P.S> the main() funxn above is just to test the encoders (which, like I said doesn't work when interrupt 5 is used for any of them. so that's why SquareWave() is using it -or not using it!).
 

8051 timer0

Opel_Corsa said:
By the way I don't understand why I can't use interrupt 5 (i.e. Timer 2 overflow) eventhough I have set TR2 = 1 and ET2 = 1. the other 2 interrupts work (1 and 3, for Timers 0 and 1).

The TF2 flag must be cleared by software at the end of ISR. Obvious if you want ISR to be executed every time when timer2 overflows.
You don't have to take this precaution for TF0 and TF1. They are both cleared by hardware when processor vectors to ISR.

So, use this very cleaver embedded C code : TF2 = 0; at the end of SquareWave function.
 

pi controller c code

Thanks for your reply. I decided to use only 2 interrupts and it worked (combined the 2 Quadratures) -I did that before seeing your reply to my posting. Here's the code:

Code:
#include <stdio.h>
#include <stdlib.h>

#ifdef SDCC_mcs51
#include <8051.h>
#include <p89v51rd2.h>

// ------------------------- All variables ---------------
...variables here...

// Initialization
unsigned char _sdcc_external_startup(void)
{
   TR0 = 0;         // stop timer 0
   TR1 = 0;         // stop timer 1
   TMOD = 0X22;      // 8 bit auto-reload for both timers
   PCON |= 0x80;
   TH1 = TL1 = 0xff;    //115200 baud with a 22MHz crystal
   TH0 = 0x100-184;    //About 0.1 ms at 22.1184MHz
   TR0 = 1;         // start timer 0
   TR1 = 1;         // start timer 1
   SCON=0x52;

   EA =1;            // Enable global interrupts
   ET0=1;         // enable timer 0 interrupt
   ET1=1;            // enable timer 1 interrupt
   
   P0_0=1; // Make this pin an input (Quad 1)
   P0_1=0; // Ground for the encoder (Quad 1)
   P0_2=1; // Make this pin an input (Quad 1)
   P1_1=1; // Make this pin an input (Quad 2)
   P1_2=0; // Ground for the encoder (Quad 2)
   P1_3=1; // Make this pin an input (Quad 2)

   return 0;
}

char getchar(void)
{ ...definition for getchar... }

void putchar(char c)
{ ...definition for putchar... }
#endif

// ------------------------- PWM -------------------------
void SquareWave (void) interrupt 1 using 1
{ ...generates square waves on P3_2 and P3_3... }

// ------------------------- Quadrature ------------------
void QuadratureCounter (void) interrupt 3 using 1
{ ...reads the values from both encoders...
   PIcontrol(); // the controller is called at the end
}

// ------------------------- PI control ------------------
void PIcontrol (void)
{ ...the controller for the motors, making them rotate at the same speed... }

void main (void)
{   
   while(1)
   {
   ... nothing really happening here...
   }
}
Now my problem is to make the 'bot stop. I created the following function:
Code:
void stop (void)
{ pwm0=0; pwm1=0; return; }
and then called it in main() by:
Code:
if (mycounter0 > 20 || mycounter1 > 20) { stop(); }
// mycounters are the counters for the encoders. 20 is just some arbitrary value
but didnt work. Also tried the following:
Code:
void stop (void)
{ P3_2=0; P3_3=0; return; }
again nothing...

So I think it's because the interrupts keep getting executed, and overwrite the stop() conditions. What's the solution to this? (I have tried disabling global interrupts as well as corresponding interrupts for both timers within main() AND within both interrupt functions, but no luck)

Your help is appreciated.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top