CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC16f877A and timer0
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PIC16f877A and timer0
PostPosted: Wed Dec 29, 2010 9:07 am     Reply with quote

I am using pic16f877a and timer0 to control the output to servo motor from ldr.
Code:
#include <16F877A.h>
#device adc=8
#include <math.h>
#include <stdlib.h>
#use delay(clock=4000000)
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOCPD                    //No EE protection
#FUSES NOPUT                    //No Power Up Timer

#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#bit  ADFM_BIT = 0x9F.7 
#define A0 PIN_a0
#define A1 PIN_a2
#define C1 PIN_C2

unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;


void isr(VOID) 
{
  if(INT_TIMER0) {               // TIMER0 Interrupt Flag
    pulse_max++;            // Pulse Max Increment
    pulse_top++;            // Pulse Top Increment

    /* MAX_VALUE=200 turn off the pulse */
    if (pulse_max >= MAX_VALUE) {
      pulse_max=0;
      pulse_top=0;
      output_low(C1);                // Turn off RC1
    }
 
    if (pulse_top == top_value) {
      output_high(C1);                // Turn On RC2
    }

    set_timer0(48) ;             // Initial Value for 0.1ms Interrupt
    clear_interrupt(int_timer0);          // Clear TIMER0 interrupt flag
  }
}

void main(void)
{
  unsigned char ldr_left;
  unsigned char ldr_right;
  int ldr_diff;

  /* Initial Port Used */
   setup_adc_ports(ALL_ANALOG);     // SETTING ADC CHANNEL // A0 A1 A2 A3 A5 E0 E1 E2 Ref=Vdd
   setup_adc(ADC_CLOCK_DIV_2);

     output_C (0x00);
  /* Init Servo Pulse */
  pulse_max=0;
  pulse_top=0;
  top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop

  /* Init TIMER0: Period: Fosc/4 x Prescaler x TMR0*/
     
set_timer0(0) ;

 while(1)
    /* Read the ADC here */
   set_adc_channel(0);

   while ( input(A0) ) {

   delay_ms( 400 );

   ldr_left=read_adc();

   set_adc_channel(1);

   while ( input(A1) ) {

   delay_ms( 400 );

   ldr_right=read_adc();
    /* Get the different */
    ldr_diff=ldr_left - ldr_right;   

    if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE)) {
      top_value = MAX_VALUE;     // Stop the Servo Motor
    } else {
      if (ldr_diff > THRESHOLD_VALUE) {
        top_value = CCW_ROTATION;  // Counterclockwise Rotation
      } else {
        top_value = CW_ROTATION;   // Clockwise Rotation
      }
    }
   }
}
}

This is the code that I have. I already try to search the code in this forum and correct the mistake that I made before. But the code is not functioning in my circuit.

Port AN0 and AN1 is the input for the ldr.
Port RC1 is the output to the servo motor.
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Wed Dec 29, 2010 10:52 am     Reply with quote

Without looking very hard:
Nowhere are you enabling the timer0 interrupt.
Nowhere are you telling the compiler that you 'isr' is for the timer0 interrupt.
If input(PIN_A0), and input(PIN_A2) both are false, the code will drop off the end.
Nowhere are you specifying the oscillator for your clock (XT? if you are using a crystal).
Your first 'while' statement will continuously execute the next line, selecting the adc channel, and never proceed to the latter code....

It is not going to work...

Learn to make your code 'tidy' - indent, and some of these faults will become 'self showing'...

Best Wishes
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Thu Dec 30, 2010 1:31 pm     Reply with quote

thanx you Smile
I manage to change the code and the error that you told me.
Code:

#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=4000000)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#bit  ADFM_BIT = 0x9F.7 
#define A0 PIN_a0
#define A1 PIN_a2
#define C1 PIN_C2

unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
unsigned int8 ldr_left;
unsigned int8 ldr_right;
unsigned int ldr_diff;

#int_TIMER0
void  TIMER0_isr(void)
{
if(INT_TIMER0) {               // TIMER0 Interrupt Flag
    pulse_max++;            // Pulse Max Increment
    pulse_top++;            // Pulse Top Increment

    /* MAX_VALUE=200 turn off the pulse */
  if (pulse_max >= MAX_VALUE) {
    pulse_max=0;
    pulse_top=0;
    output_low(C1);                // Turn off RC1
    }

 
  if (pulse_top == top_value) {
    output_high(C1);                // Turn On RC2
    }

    set_timer0(48) ;             // Initial Value for 0.1ms Interrupt
    clear_interrupt(int_timer0);          // Clear TIMER0 interrupt flag
  }
}

void main()
{

   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   
  /* Init Servo Pulse */
  pulse_max=0;
  pulse_top=0;
  top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop

  /* Init TIMER0: Period: Fosc/4 x Prescaler x TMR0*/
     
set_timer0(206) ;

 while(1)
    /* Read the ADC here */
   set_adc_channel(0);

if ( input(A0) ) {

   delay_ms( 400 );

   ldr_left=read_adc();

   set_adc_channel(1);

if ( input(A1) ) {

   delay_ms( 400 );

   ldr_right=read_adc();
{
    /* Get the different */
    ldr_diff=ldr_left - ldr_right;   

    if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE)) {
      top_value = MAX_VALUE;     // Stop the Servo Motor
    } else {
        if (ldr_diff > THRESHOLD_VALUE) {
        top_value = CCW_ROTATION;  // Counterclockwise Rotation
      } else {
        top_value = CW_ROTATION;   // Clockwise Rotation
      }
    }
   }
}
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Thu Dec 30, 2010 4:34 pm     Reply with quote

So, you have a 4MHz crystal attached?.
Is 'HS' the right oscillator for this?.

You have not corrected the while statement.
Code:


   while(1)
     statement()

   code


executes 'statement' continuously, and will _never_ get to 'code'....

Best Wishes
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Thu Dec 30, 2010 10:36 pm     Reply with quote

Code:

#include <16F877A.h>
#device adc=8


#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=4000000)
  #include <math.h>
  #include <stdio.h>
  #include <stdlib.h>
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#bit  ADFM_BIT = 0x9F.7 
#define A0 PIN_a0
#define A1 PIN_a2
#define B1 PIN_B1
#define ADFM = 0;      //1 for ADC result to be right-justified, 0 for left-justified
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
unsigned int8 ldr_left;
unsigned int8 ldr_right;
unsigned int ldr_diff;

#int_TIMER0
void  TIMER0_isr(void)
{
if(INT_TIMER0) {               // TIMER0 Interrupt Flag
    pulse_max++;            // Pulse Max Increment
    pulse_top++;            // Pulse Top Increment

    /* MAX_VALUE=200 turn off the pulse */
  if (pulse_max >= MAX_VALUE) {
    pulse_max=0;
    pulse_top=0;
    output_low(B1);                // Turn off RC1
    }

 
  if (pulse_top == top_value) {
    output_high(B1);                // Turn On RC2
    }

    set_timer0(206) ;             // Initial Value for 0.1ms Interrupt
    clear_interrupt(int_timer0);          // Clear TIMER0 interrupt flag
  }
}
void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   /* Init Servo Pulse */
  pulse_max=0;
  pulse_top=0;
  top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop

  /* Init TIMER0: Period: Fosc/4 x Prescaler x TMR0*/
     
set_timer0(206) ; //interrupt every 0.1ms

while(1){
    /* Read the ADC here */
   

if ( input(A0) ) {
  set_adc_channel(0);
   delay_ms( 400 );

   ldr_left=read_adc();

   

if ( input(A1) ) {
   set_adc_channel(1);

   delay_ms( 400 );

   ldr_right=read_adc();
{
    /* Get the different */
    ldr_diff=ldr_left - ldr_right;   

    if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE)) {
      top_value = MAX_VALUE;     // Stop the Servo Motor
    } else {
        if (ldr_diff > THRESHOLD_VALUE) {
        top_value = CCW_ROTATION;  // Counterclockwise Rotation
      } else {
        top_value = CW_ROTATION;   // Clockwise Rotation
      }
    }
   }
}
}
}

}

This is the code with a { after the while, is this correct?
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Fri Dec 31, 2010 2:35 am     Reply with quote

Btw, do I need to initialize port A and C first?
How do I initialize to the value that I want? Thanks.
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Fri Dec 31, 2010 9:47 am     Reply with quote

Ttelmah wrote:
So, you have a 4MHz crystal attached?.
Is 'HS' the right oscillator for this?.

You have not corrected the while statement.
Code:


   while(1)
     statement()

   code


executes 'statement' continuously, and will _never_ get to 'code'....

Best Wishes

regarding the amendment of the code.is it still ok?as i stil get condition is always true in the warning bar.


i really in this help urgently :(
thanx a lot
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Fri Dec 31, 2010 10:27 am     Reply with quote

Here is a quick look at an attempt to 'clean up' your code. It makes it easier to read and easier to see problems.

Code:
void main()
{

   setup_adc_ports(NO_ANALOGS);  // Why would you setup NO analogs if you're going to be reading analogs?
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // Init Servo Pulse
   pulse_max=0;
   pulse_top=0;
   top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop

   // Init TIMER0: Period: Fosc/4 x Prescaler x TMR0
   set_timer0(206) ; //interrupt every 0.1ms
   
   // No ADC Clock?

   while(true)
   {
      // Read the ADC here
      if ( input(A0) )
      {
         set_adc_channel(0);
         delay_ms( 400 );  // I forget what the delay time required is, but 400mS sounds too long.
         ldr_left=read_adc();
      }
   
      if ( input(A1) )
      {
         set_adc_channel(1);
         delay_ms( 400 );
         ldr_right=read_adc();
      }
     
      // Get the different
      ldr_diff = ldr_left - ldr_right;   

      if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE))
      {
         top_value = MAX_VALUE;     // Stop the Servo Motor
      }
      else
      {
         if (ldr_diff > THRESHOLD_VALUE)
         {
            top_value = CCW_ROTATION;  // Counterclockwise Rotation
         }
         else
         {
            top_value = CW_ROTATION;   // Clockwise Rotation
         }
      }
   }
}



Read up on how to configure and read ADC values. There's got to be plenty of threads with the details.

You change back and forth on pins and clock fuse settings between your posted code.

What specific problems are you having? Won't compile? Run time results not what expected?
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Fri Dec 31, 2010 11:40 am     Reply with quote

Quote:
#include <16F877A.h>
#device adc=8


#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected

#use delay(clock=4000000)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#bit ADFM_BIT = 0x9F.7
#define A0 PIN_a0
#define A1 PIN_a2
#define B1 PIN_B1
#define ADFM = 0; //1 for ADC result to be right-justified, 0 for left-justified
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
unsigned int8 ldr_left;
unsigned int8 ldr_right;
unsigned int ldr_diff;

#int_TIMER0
static void TIMER0_isr(void)
{

if(INT_TIMER0)// TIMER0 Interrupt Flag
{
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment

/* MAX_VALUE=200 turn off the pulse */
if (pulse_max >= MAX_VALUE) {
pulse_max=0;
pulse_top=0;
output_low(B1); // Turn off RB1
}


else if (pulse_top == top_value) {
output_high(B1); // Turn On RB1
}

set_timer0(206) ; // Initial Value for 0.1ms Interrupt
clear_interrupt(int_timer0); // Clear TIMER0 interrupt flag
}
}
void main()
{

setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

// Init Servo Pulse
pulse_max=0;
pulse_top=0;
top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop

// Init TIMER0: Period: Fosc/4 x Prescaler x TMR0
set_timer0(206) ; //interrupt every 0.1ms
enable_interrupts(int_timer1);
enable_interrupts(GLOBAL);

setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_2);


while(true)
{
// Read the ADC here
if ( input(A0) )
{
set_adc_channel(0);
delay_us( 0.5 );
ldr_left=read_adc();
}

if ( input(A1) )
{
set_adc_channel(1);
delay_us( 0.5 );
ldr_right=read_adc();
}

// Get the different
ldr_diff = ldr_left - ldr_right;

if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE))
{
top_value = MAX_VALUE; // Stop the Servo Motor
}
else
{
if (ldr_diff > THRESHOLD_VALUE)
{
top_value = CCW_ROTATION; // Counterclockwise Rotation
}
else
{
top_value = CW_ROTATION; // Clockwise Rotation
}
}
}
}


thanx for replying,
my problems
one of the line in red have a warning that say the condition is always true :(

besides this,the code is not functioning.i m not sure if there is anything wrong from the code

for the TOSC herehttp://pic-c.ccsinfo.com/forum/viewtopic.php?t=44181&highlight=adc

the delay should be 500ns
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Fri Dec 31, 2010 12:15 pm     Reply with quote

You don't need to check for the interrupt bit in the ISR. That bit is what triggers the ISR in the first place. So, of course, it will always be true.

You don't need to clear the interrupt flag in the ISR, the compiler handles that with the ISR call.

Code:
#int_TIMER0
void  TIMER0_isr(void)
{
  pulse_max++;            // Pulse Max Increment
  pulse_top++;            // Pulse Top Increment

  // MAX_VALUE=200 turn off the pulse
  if (pulse_max >= MAX_VALUE)
  {
    pulse_max=0;
    pulse_top=0;
    output_low(B1);                // Turn off RC1
  }
   
  if (pulse_top == top_value)
  {
    output_high(B1);                // Turn On RC2
  }
 
  set_timer0(206) ;             // Initial Value for 0.1ms Interrupt
 
}



I would suggest getting parts of your code working and then combine the working parts. Do you have any output you could use for debugging, like an LCD or an LED?
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Fri Dec 31, 2010 12:38 pm     Reply with quote

Yup. I do have.
A servo so that it could rotate left or right.
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Fri Dec 31, 2010 1:17 pm     Reply with quote

I would start from the very beginning with a new set of code. The goal is to build up the code piece by piece, checking each addition along the way. And you can use the servos to verify your code is working along the way.

So, the first step would be to write two functions, one to pulse left and one to pulse right. Make them pulse different distances or times, so you can ensure that right is actually right and left is actually left.

Write those functions and put them in the main() while(true) loop like this:

Code:

while(true)
{
   pulse_left();
   delay_ms(500);
   pulse_right();
   delay_ms(500);
}



Once that is done and you've confirmed that everything is working you can build and test the next section of code, maybe the ISR.
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Fri Dec 31, 2010 9:58 pm     Reply with quote

Code:

#include <pic.h>                  // this sample code is using 16F877A !!
                        
//   configuration
//==========================================================================
__CONFIG ( 0x3F32 );            //configuration for the  microcontroller
                                 
//   define
//==========================================================================
#define servo   RB1

#define   MHZ   *1000L            /* number of kHz in a MHz */
#define   KHZ   *1               /* number of kHz in a kHz */

// Value x must not more that 255
#define   DelayUs(x)   { unsigned char _dcnt; \
           _dcnt = (((x)*(20MHZ))/(24MHZ))|1; \
           while(--_dcnt != 0) \
              continue; \
           _dcnt = (((x)*    (20MHZ))/(24MHZ))|1; \
           while(--_dcnt != 0) \
              continue; }


//   function                   (every function must have a function prototype)
//==========================================================================

void DelayMs(unsigned char y);    // Value y must not more that 255
                           // delay ms
//   main function               (main fucntion of the program)
//==========================================================================
void main(void)
{
   unsigned int i,a;
   
   //set IO port for servo pin
   TRISB = 0b00000001;         //servo motor is RB1
   PORTB = 0b00000000;         //clear port B

                        //servo will loop infinity
   while(1)               //from one position to another position
   {
      //*******************************************************
      //
      //Delay determine the servo motors position
      //Try change the value for different position
      //
      //Value in DelayUs and DelayMs function must not more than 255
      //Otherwise the timing will not accurate!!
      //
      //******************************************************
      
      for(i=0;i<50;i++)      //continues pulse for 50 times
      {
         servo=1;         //set servo pin high
         DelayUs(250);
         DelayUs(250);
         DelayUs(200);      //delay   250+250+200= 700us = 0.7ms   
                        //These delay only valid using 20MHz!
      
         servo=0;         //set servo pin low
         DelayMs(19);      //remain --> 20ms-0.7ms=19.3ms
         DelayUs(250);
         DelayUs(50);      //19ms+0.250ms+0.050ms=19.3ms
                        //These delay only valid using 20MHz!
      }
      
      //  _                   _                  _
      // | |                  | |                | |
      // | |                  | |                | |                 ~~50 times             
      // | |_________________| |________________| |____________________
      // 0.7ms    19ms      0.7ms      19ms     0.7ms   19ms
      // |               |
      // |<-------20ms------>|
      
      for(i=0;i<50;i++)      //continues pulse for 50 times
      {
         servo=1;         //set servo pin high
         DelayMs(2);         //delay   2ms   
                        //These delay only valid using 20MHz!
                        
         servo=0;         //set servo pin low
         DelayMs(18);      //delay 18ms
                        //These delay only valid using 20MHz!
      }   
         
      //  ___                   ___                 ___
      // |   |               |   |               |   |
      // |   |               |   |               |   |              ~~50 times       
      // |   |_______________|   |_______________|   |____________________
      //  2ms       18ms      2ms      18ms       2ms      18ms
      // |               |
      // |<-------20ms------>|
   }
      
}
   
//subroutine
//============================================================================   
void DelayMs(unsigned char y)
{
   unsigned char   i;
   do {
      i = 4;
      do {
         DelayUs(250);
      } while(--i);
   } while(--y);
}

This is the code that was supply by the manufacturer to control the servo motor. This code is working with my servo. It can turn left and right.
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Sat Jan 01, 2011 9:01 am     Reply with quote

Code:

#include <16F877A.h>
#device adc=8
#use delay(clock=4000000)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#define A0 PIN_a0
#define A1 PIN_a1
#define B1 PIN_B1
#define ADFM = 0;      //1 for ADC result to be right-justified, 0 for left-justified
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
unsigned char ldr_left;
unsigned char ldr_right;
int8 ldr_diff;


static void interrupt_isr(void)
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
   if(INT_TIMER0)// TIMER0 Interrupt Flag
   {               
    pulse_max++;            // Pulse Max Increment
    pulse_top++;            // Pulse Top Increment

    /* MAX_VALUE=200 turn off the pulse */
    if (pulse_max >= MAX_VALUE) {
    pulse_max=0;
    pulse_top=0;
    output_low(B1);                // Turn off RB1
    }

 
    if (pulse_top == top_value) {
    output_high(B1);                // Turn On RB1
    }

    set_timer0(206) ;             // Initial Value for 0.1ms Interrupt
    clear_interrupt(int_timer0);          // Clear TIMER0 interrupt flag
  }
}
void main(void)
{
   int1 done1;
   int1 done2;
   
   port_b_pullups(TRUE);
   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 
// Init Servo Pulse
 
   pulse_max=0;
   pulse_top=0;
   top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop

   // Init TIMER0: Period: Fosc/4 x Prescaler x TMR0
   set_timer0(206) ; //interrupt every 0.1ms
   enable_interrupts(int_timer0);
   enable_interrupts(GLOBAL);
   

      // Read the ADC here
for(;;){
A0;
     
         set_adc_channel(0);
         read_adc(ADC_READ_ONLY);
         done1 = adc_done();
         while(!done1) {   
         done1 = adc_done();
         }
         ldr_left=read_adc(ADC_READ_ONLY);
         delay_us( 30 );
         
 A1;   
   
     
         set_adc_channel(1);
         read_adc(ADC_READ_ONLY);
         done2 = adc_done();
         while(!done2) {   
         done2 = adc_done();
         }
         ldr_right=read_adc(ADC_READ_ONLY);
         delay_us( 30 );
       
     
          // Get the different
      ldr_diff = ldr_left - ldr_right;   

      if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE))
      {
         top_value = MAX_VALUE;     // Stop the Servo Motor
      }
      else
      {
         if (ldr_diff > THRESHOLD_VALUE)
         {
            top_value = CCW_ROTATION;  // Counterclockwise Rotation
         }
         else
         {
            top_value = CW_ROTATION;   // Clockwise Rotation
         }
      }
   }
}

I try to change a lot of the code but still to no avail :(
wind88



Joined: 29 Dec 2010
Posts: 37

View user's profile Send private message

PostPosted: Sun Jan 02, 2011 10:03 am     Reply with quote

Code:

static void interrupt_isr(void)
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
if(INT_TIMER0)// TIMER0 Interrupt Flag
{
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment

/* MAX_VALUE=200 turn off the pulse */
if (pulse_max >= MAX_VALUE) {
pulse_max=0;
pulse_top=0;
output_low(B1); // Turn off RB1
}


if (pulse_top == top_value) {
output_high(B1); // Turn On RB1
}

set_timer0(206) ; // Initial Value for 0.1ms Interrupt

}
}

Can anyone tell me if there is something wrong in this part? Thanx.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group