![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
prach Guest
|
please check my code why output at ra3 it high-low two time |
Posted: Mon May 16, 2005 8:40 pm |
|
|
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);
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Tue May 17, 2005 3:31 am |
|
|
Probably because you used angle (int_count=angle;) but haven't actually assigned any values to it. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue May 17, 2005 4:32 am |
|
|
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);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Tue May 17, 2005 10:40 am |
|
|
thank you very much for any suggestion. ![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|