8051 C Programming Bug

Thread Starter

Seehat

Joined Oct 14, 2013
12
Hello Everyone
I'm trying to get a servo motor turn from 0 to 180degree. and back for the same it requires me to send a a different pulse for different positions of the motor. for 0 position it requires 600us and for 180 position requires 2400us approx. and their should be a 20ms gap between two pulses.
For that i have created a 0.1ms timer delay and counting for 200 times before the swithes. so it creates a 20ms gap between pulses.

but it is not working. i had it working perfectly but now it's messed up. and i dont know why.


Rich (BB code):
#ifndef A3_XX_h
#define A3_XX_h

//--------------------------------------------------------------------------------------------------------------------
//                              Global Variables
//--------------------------------------------------------------------------------------------------------------------
sbit PB1 = P1 ^ 0;                           // Pushbutton PB1
sbit PB2 = P1 ^ 1;                           // Pushbutton PB2
sbit PB3 = P1 ^ 2;                           // Pushbutton PB3   
sbit PB4 = P1 ^ 3;                           // Pushbuttom PB4
sbit PB5 = P1 ^ 4;                           // Pushbutton PB5
sbit PB6 = P1 ^ 5;                           // Pushbutton PB6
sbit PB7 = P1 ^ 6;                           // Pushbutton PB7   
sbit PB8 = P1 ^ 7;                           // Pushbuttom PB8

sbit SMODE = P3 ^ 7;                                                // Pushbutton on F120 development board

sbit LD0 = P2 ^ 0;                         // LD0   
sbit LD1 = P2 ^ 1;                         // LD1
sbit LD2 = P2 ^ 2;                         // LD2
sbit LD3 = P2 ^ 3;                         // LD3  
sbit LD4 = P2 ^ 4;                         // LD4   
sbit LD5 = P2 ^ 5;                         // LD5
sbit LD6 = P2 ^ 6;                         // LD6
sbit LD7 = P2 ^ 7;                         // LD7    


sfr     LCD = 0xB0;

sbit DB4     = P3 ^ 0;                                                    // LCD Pins
sbit DB5     = P3 ^ 1;
sbit DB6     = P3 ^ 2;
sbit DB7     = P3 ^ 3;
sbit RS     = P3 ^ 4;
sbit RW     = P3 ^ 5;
sbit E      = P3 ^ 6;
sbit BL     = P3 ^ 7;

sbit USonicTX        = P0 ^ 2;                                            // TX for ultrasonic
sbit USonicRX        = P0 ^ 3;                                            // RX 
sbit Servo_Ctrl = P0 ^ 4;                                            // Servo control pin


//--------------------------------------------------------------------------------------------------------------------
//                              Function prototypes
//--------------------------------------------------------------------------------------------------------------------
void main(void);
void General_Init(void);
void Timer2_Init();
void Interrupts_Init();
void Timer2_ISR (void);
void PCA_Init(void);
void delay(unsigned int);
void Wavegenerator();
void lcd_init();
void toggle();
void sweep();
void delaytimer2();
#endif
Rich (BB code):
#include <c8051f120.h>     // SFR declarations
#include "A3_XX.h"

int angle;
int count;
int k=0;
int i;
int j;
/*--------------------------------------------------------------------------------------------------------------------
        Function:         Main Routine
--------------------------------------------------------------------------------------------------------------------*/
void main(void)
{   
    //USonicTX  = 0xff;
    //P2 = 0xff;
    SFRPAGE   = CONFIG_PAGE;
    //OSCICN    = 0x83;                    // Need a faster clock....24.5MHz selected
    General_Init();
    Timer2_Init();    
    Interrupts_Init();

    while(1)
    {  
      sweep();
     }
}

/*--------------------------------------------------------------------------------------------------------------------
        Function:         General_Init
--------------------------------------------------------------------------------------------------------------------*/
void General_Init()
{
    WDTCN = 0xde;
    WDTCN = 0xad;
    SFRPAGE = CONFIG_PAGE;
    XBR2 = 0x40;
    XBR0 = 0x80;
    XBR1 = 0x03;
    P0MDOUT = 0x10;        // NOTE: Pushpull required for Servo control OTHERWISE TOO WEAK TO DRIVE PROPERLY SINCE ONLY 3.3V!!!!
    P1MDOUT = 0x00;        // Ensure not pushpull outputs....this could damage microcontroller...
    P2MDOUT = 0xff;        // Need to make pushpull outputs to drive LEDs properly


    Servo_Ctrl = 0;    // Initialise servo control pin to 0

    
}

/*--------------------------------------------------------------------------------------------------------------------
        Function:         Timer_Init
--------------------------------------------------------------------------------------------------------------------*/
/*void Timer2_Init()
{   //Timer 2 Initialisation For Servo motor control//
    SFRPAGE   = TMR2_PAGE;
    TMR2CN    = 0x04;
    RCAP2L    = 0x3C;
    RCAP2H    = 0xF6;
    
}*/

/*--------------------------------------------------------------------------------------------------------------------
        Function:         Interrupts_Init
--------------------------------------------------------------------------------------------------------------------*/
void Interrupts_Init()
{
    IE        = 0xA0;
    EIE2      = 0x04;
} 

/*--------------------------------------------------------------------------------------------------------------------
        Function:         Timer2_ISR
--------------------------------------------------------------------------------------------------------------------*/
void Timer2_ISR (void) interrupt 5
{           
 
           unsigned char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page
            
            count++;

                                   if(count==angle)
                                   Servo_Ctrl=0;
                                           
                                if(count==200)
                                  {
                                       Servo_Ctrl=1;
                                       count=0;
                                   }

                              TF2 = 0;    // Reset interrupt flag
                
             SFRPAGE = SFRPAGE_SAVE;
                                                           // Restore SFR page
}

/*--------------------------------------------------------------------------------------------------------------------
        Function:         Delay_0.1s
--------------------------------------------------------------------------------------------------------------------*/
void delay(unsigned int time)
 {
     
   unsigned int y,j;
   for(y=0;y<time;y++)
    for(j=0;j<141;j++);
 }


 /*--------------------------------------------------------------------------------------------------------------------
        Function: Lcd_init
--------------------------------------------------------------------------------------------------------------------*/
/*void lcd_init()
{
RS = 0; RW = 0; DB7 = 0; DB6 = 0; DB5 = 1; DB4 = 0;
toggle();
delay(5);

RS = 0; RW = 0; DB7 = 0; DB6 = 0; DB5 = 1; DB4 = 0;
toggle();
delay(5);

RS = 0; RW = 0; DB7 = 0; DB6 = 0; DB5 = 1; DB4 = 0;
toggle();
delay(5);

RS = 0; RW = 0; DB7 = 0; DB6 = 0; DB5 = 0; DB4 = 0;
toggle();
delay(5);

RS = 0; RW = 0; DB7 = 1; DB6 = 1; DB5 = 1; DB4 = 0;
toggle();
delay(5);

RS = 0; RW = 0; DB7 = 0; DB6 = 0; DB5 = 0; DB4 = 0;
toggle();
delay(5);

RS = 0; RW = 0; DB7 = 0; DB6 = 1; DB5 = 1; DB4 = 0;
toggle();
delay(5);

RS = 1; RW = 0; DB7 = 0; DB6 = 1; DB5 = 0; DB4 = 1;
toggle();
delay(5);

RS = 1; RW = 0; DB7 = 0; DB6 = 0; DB5 = 1; DB4 = 1;
toggle();
delay(5);

}*/

/*--------------------------------------------------------------------------------------------------------------------
        Function: toggleE
--------------------------------------------------------------------------------------------------------------------*/

/*void toggle()
{
 
 if(E==0){
 E=1;}

 else 
 E=0;

}*/

/*--------------------------------------------------------------------------------------------------------------------
        Function: Sweep
--------------------------------------------------------------------------------------------------------------------*/

void sweep()
{           
            int x=6;
            angle=15;
            delaytimer2();
            

         while(1){                  
            
            angle=x;
            delaytimer2();

            x=x+i;

            if(angle==24){
                          i=-1;}
            if(angle==6){
                         i=1;}
                  }
}

/*--------------------------------------------------------------------------------------------------------------------
        Function: Sweep 0.1ms
--------------------------------------------------------------------------------------------------------------------*/

void delaytimer2()
{

TR2 = 1;
while (TF2 == 0);
TR2 = 0;
TF2 = 0;
}
 

tshuck

Joined Oct 18, 2012
3,534
Bump ^ Bump
You are that impatient that you must bump after only 26 minutes?

This is an international forum... The sun isn't even up yet here, yet you expect an answer? Bumping your thread makes some people not want to respond as it seems insistent and demanding of attention.

With that said, how is it messed up? What bug have you made? What have you tried to debug the situation?
 

MrChips

Joined Oct 2, 2009
35,156
but it is not working. i had it working perfectly but now it's messed up. and i dont know why.
You have made changes to your code and now it's messed up. Try to recall what changes you have made.


Rich (BB code):
void delaytimer2()
{
  TR2 = 1;
  while (TF2 == 0);
  TR2 = 0;
  TF2 = 0;
}
This code is not correct. Maybe you made some changes here.
 

Thread Starter

Seehat

Joined Oct 14, 2013
12
Sorry if that bump hit you mate. :D:D

the Sweep() function i have made in this code with an interrupt is not working how i designed it to be. on the hardware it is stuck on the angle 6 position i.e. the to the left most on the servo motor.

can you please have a look on the sweep function coming out of the main and then going into interrupt after each timer overflow.
 

Thread Starter

Seehat

Joined Oct 14, 2013
12
@Mrchips
Yes bro..somewhere here....as i tried to omit the timer delay i messed it up and put in a software delay but as i tried to reverse it into original form i am not able to find the bug i have created.

Lesson learned - don't touch a code that is working. put it as comments and then try something new. :mad:
 

tshuck

Joined Oct 18, 2012
3,534
You are using timer 2 as your interrupt source, yet you disable the timer in delaytimer2().

Does the servo actively stay at the angle corresponding to 6, or does it move there and stop moving?
 

Thread Starter

Seehat

Joined Oct 14, 2013
12
@Mrchips
It's not even working with soft delay mate. Anyway i need to use the timer delay acc. To the requirments of the program.

@tshuck
Hmm.. Does giving a zero value to TR2 bit will disable the interrupt there only in delaytimer2 loop ?
Yeah it goes to angle corresponding to 6 and stop moving. I can feel the motor pushing more towards less than 6 angles.
 

tshuck

Joined Oct 18, 2012
3,534
@Mrchips
It's not even working with soft delay mate. Anyway i need to use the timer delay acc. To the requirments of the program.

@tshuck
Hmm.. Does giving a zero value to TR2 bit will disable the interrupt there only in delaytimer2 loop ?
Yeah it goes to angle corresponding to 6 and stop moving. I can feel the motor pushing more towards less than 6 angles.
According to the datasheet I'm looking at, setting TR2=0 means the counter will not count, so no overflow/interrupt could happen, it shouldn't disable the interrupt, just the interrupt will never come.

So the servo is actively attempting to move beyond mechanical limitations? If so, your controller is sending something, just not a 1-2ms. pulse every 20ms. Do you have an oscilloscope at all? Perhaps you should try one of those sound card based oscilloscope programs to check your signals if you don't have one...
 

Thread Starter

Seehat

Joined Oct 14, 2013
12
Sorry man yes i have an oscilloscope and it is a weird signal with a peak to peak gap of 4.9ms. Yeah you might be correct. But the signal on oscilloscoscope is weird surely
 
Top