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

please check my code why output at ra3 it high-low two time

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
prach
Guest







please check my code why output at ra3 it high-low two time
PostPosted: Mon May 16, 2005 8:40 pm     Reply with quote

i builde hardware for trick SCR at 45 degree by sense interrupts external and then disable external ,enable rtcc for delay time on RA3 (5 us per degree), but RA3 it on two time in 1 half cycle (in cdoe i want on-off RA3 one time in half cycle )
thank you , sorry in my english

Code:


#include    <16F877.h>
#fuses      XT,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
#device     *=16 ADC=10
#use        delay(clock=4000000)

int       int_count,angle;

//===========================================================================
#int_rtcc
void clock_isr(){
   int_count--;
//----------------------------------------------------------------------
    if(int_count==0) {
      disable_interrupts(int_rtcc);           
        output_high(pin_a3);
           delay_ms(1);
        output_low(pin_a3);
           int_count=angle;
      enable_interrupts(INT_EXT);
     }
//----------------------------------------------------------------------
     set_timer0(251);         //set_timer0(251);
   }
//===========================================================================
#int_ext
isr(){
  disable_interrupts(INT_EXT);
  enable_interrupts(INT_RTCC);
}
//===========================================================================
void main() {
     int_count=45;
          set_timer0(251);      //set_timer0(251);
             set_tris_a(0x01);
               output_a(0x00);

    set_tris_b(0x01);
     setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
      enable_interrupts(GLOBAL);
          enable_interrupts(INT_EXT);
             while(true);
}
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Tue May 17, 2005 3:31 am     Reply with quote

Probably because you used angle (int_count=angle;) but haven't actually assigned any values to it.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue May 17, 2005 4:32 am     Reply with quote

Besides the remark grom Hapl several other issues:
1) Beware that the interrupt routines have some overhead, something like 20 instructions for the PIC16 series. Running at 4MHz this results in a minimum timing resolution of something like 20us. Your 5us using interrupts is impossible at this clock frequency.
2) Timer0 is always active at power-on, so after your setting the timer value and enabling the interrupt, the interrupt will fire immediately or the timer has already rolled over and the interrupt will fire later than intended. Clear the interrupt flag and set the timer directly before enabling the interrupt, or forget about setting the timer at all (your startup time is not synchronized anyway).
3) I don't like delay_ms() function calls inside an interrupt routine. Interrupt routines are supposed to run as fast as possible. One side effect of your code is the timer0 still counting, so when exiting the interrupt it will fire again directly.
4) A 5us resolution is very small for a processor running at 4MHz, executing a single instruction takes 1us and a jump takes even 2-3us.
5) Why not use the available CCP hardware unit to do all the hard work?

My suggestion: Use the timer1 and CCP1 in compare mode. Have timer1 running at 1 us speed and set the compare register to the required timing delay. At reaching the preset time the compare register will trigger an interrupt and you can perform whatever action required.
For even greater accuracy you can forget about the interrupt and just test the interrupt flag in a while loop, this saves the interrupt overhead.


example:
Code:
#include    <16F877.h>
#fuses      XT,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
#device     *=16 ADC=10
#use        delay(clock=4000000)

#byte PIR1 = 0x0C
#bit CCP1IF = PIR1.2

//===========================================================================
void main()
{
  int8 angle;

  angle = 45;
  output_a(0x00);

  while(TRUE)
  {
    // Wait for trigger on pin B0
    while (! input(PIN_B0))
      ;     // Do nothing
 
    // Setup compare registers
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
    set_timer1(0);
    setup_ccp1(CCP_COMPARE_INT);
    CCP_1 = angle * 5;       // 5 timer ticks of 1us per degree
    clear_interrupt(INT_CCP1);
 
    // Wait for specified time to have past
    while( CCP1IF == 0 )
      ;     // Do nothing
 
    // Generate pulse on A3 pin.
    output_high(PIN_A3);
    clear_interrupt(INT_CCP1);
    delay_ms(1);
    output_low(PIN_A3);
  }
}
Guest








PostPosted: Tue May 17, 2005 10:40 am     Reply with quote

thank you very much for any suggestion. Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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