![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
complex72
Joined: 10 May 2014 Posts: 11
|
Zero crossing detection and Triac firing with timer1 |
Posted: Tue May 27, 2014 11:55 am |
|
|
Hi I've worked before with zero crossing detection, what I would like assistance in is on using timer1 for handling the firing of the triac. I basically have a C# interface with a slider that sends me a 16bit number to the microcontroller 0-65535 and loads it to the timer. What I couldn't figure out is what time does this values represent.
For instance I know that the maximum time for firing depends on the wave cycle so using 60Hz freq the period would be T=1/60=16.67ms and Half a cycle is 1/2T=8.33ms so the maximum time I have for firing after the zero crossing is 8.33ms here is my code:
Code: | ************************************************CONFIGURATION**********************************************************/
#include "18f4550.h"
#fuses HSPLL,PLL5,CPUDIV1,PUT,NOWRT,NOWDT,NOBROWNOUT,NOPROTECT,NODEBUG
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=N)
#use standard_io(B)
#include <stdio.h>
#byte RD16=1
#byte TO8BIT=0
#define tirac_fire Pin_B2
#include <stdio.h>
#include <stdlib.h>
//------------------------------------------------VARIABLES-----------------------------------------------------------
int16 angle;
int x,y;
//--------------------------------------------------------------------------------------------------------------------
#int_RDA
void RDA_isr()
{
x=getc();
y=getc();
angle=make16(y,x);
}
#INT_EXT
void zero_crossing()
{
output_low(triac_fire);
set_timer1(angle);
}
#INT_TIMER1
void timer1()
{
if(angle>0)
output_high(triac_fire);
}
//--------------------------------------------------Main()------------------------------------------------------------------
void main()
{
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
enable_interrupts(INT_TIMER1);
ext_int_edge(H_TO_L);
enable_interrupts(INT_RDA);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while(1){
delay_ms(100);
}
}
//***********************************************End************************************************************************** |
So basically I have to find values from 0-65535 that represent 0-8.33m and load them to timer1? is that a good approach? and how can I figure them out?
Thank you |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue May 27, 2014 12:19 pm |
|
|
Your timer1, runs off the master oscillator/8 (Fosc/4 /2).
So with your 48MHz clock, it is counting in 6 millionths of a second. So will count 49980 in 8.33mSec (8330*6).
However remember there will be latency in getting into the ISR and loading the value. Perhaps 20+ counts, so use 49950 as your maximum value.
There are problems with your 'angle' code.
INT_RDA, says _one_ character is available to read. You are reading two, so the code _will_ hang waiting for the second character in this ISR.
Then there is nothing to say when the number starts or ends. If a character gets missed at any point, the value will become invalid....
Suggest you just use a single character as 'percent'. Then when this is updated, multiply this by 499, to use in your angle code. Each character is then the complete 'message'. |
|
![](templates/subSilver/images/spacer.gif) |
complex72
Joined: 10 May 2014 Posts: 11
|
|
Posted: Tue May 27, 2014 1:36 pm |
|
|
Ttelmah wrote: | Your timer1, runs off the master oscillator/8 (Fosc/4 /2).
So with your 48MHz clock, it is counting in 6 millionths of a second. So will count 49980 in 8.33mSec (8330*6).
However remember there will be latency in getting into the ISR and loading the value. Perhaps 20+ counts, so use 49950 as your maximum value.
There are problems with your 'angle' code.
INT_RDA, says _one_ character is available to read. You are reading two, so the code _will_ hang waiting for the second character in this ISR.
Then there is nothing to say when the number starts or ends. If a character gets missed at any point, the value will become invalid....
Suggest you just use a single character as 'percent'. Then when this is updated, multiply this by 499, to use in your angle code. Each character is then the complete 'message'. |
Thanks Ttelmah, one last question how did you figure out the 6 millionths of a second, what if I where to use a 20Mhz clock..thank you |
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue May 27, 2014 2:10 pm |
|
|
[quote="complex72"] Ttelmah wrote: |
Thanks Ttelmah, one last question how did you figure out the 6 millionths of a second, what if I where to use a 20Mhz clock..thank you |
He meant 6 million a second.
You're feeding the timer at 6MHz.
That's your 48MHz/4 then /2.
The /4 is because that's how 18F parts work and /2 because you've told the compiler to div_by_2.
It's all in the microchip data sheet.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
complex72
Joined: 10 May 2014 Posts: 11
|
|
Posted: Tue May 27, 2014 9:14 pm |
|
|
got it...! Thanks Ttelmah and Mike |
|
![](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
|