![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
deesarus
Joined: 13 Dec 2004 Posts: 1
|
PIC 12F629 as Frequency Divider |
Posted: Mon Dec 13, 2004 2:24 pm |
|
|
Hello all,
I am a newbie to PIC-C programming,and am trying to develop a PIC-C program for frequency division.I have to use a PIC 12F629,that has to divide the input frequency by 32.I am using an external RC circuitry,that will change to give different values of input frequency.Thus,for example,if the input freq is 3.2 MHz,which will be supplied at Pin2..which is the GP5 pin...I shld produce a Sqaure wave of 100 KHz at Pin5..which is GP2.
I wud really appreciate any pointers and suggestions.I tried to see if I could use the CCP module,but it turns out the 12f629 does not have it.I find the Timer registers function confusing.I wrote a program to calculate the frequency at Pin 2,then divide that by 8,and output a sqaure wave at pin 5,based on that program.but it doesnt seem to be rite.
Any suggestions are gladly appreciated.
Thanks. |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Dec 13, 2004 3:25 pm |
|
|
Code: | count = 0;
while(1)
{
// Wait for a high transistion
while (!input(PIN_A5));
// See if we have seen 32 pulses yet
if (count == 32)
{
count = 0;
output_toggle(PIN_A2);
}
count++;
// Wait for a low transistion
while (input(PIN_A5));
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Libor Guest
|
|
Posted: Mon Dec 13, 2004 4:18 pm |
|
|
You can use the 12F629 PIC's TIMER0 module as a counter with GP2/T0CKI pin as a clock source, then all you have to do is set the output pin to the counter value's corresponding bit to achieve a division by 32.
I have not tried it, use this code fragment as a clue only, I may have made errors:
#include <12F629.h>
#fuses NOCPD,PROTECT,MCLR,PUT,INTRC_IO,BROWNOUT
#use delay(clock=4000000)
#use fast_io(A)
void main() {
int i;
set_tris_a(0b11011111); //GP5 output, all others input
setup_comparator(NC_NC); //no comparator, make all ports digital I/O
setup_timer_0(RTCC_EXT_L_TO_H | RTCC_DIV_1) //count low to high transitions on GP2
while (TRUE) { //do it forever
i = get_timer0(); //get counter value into i
output_bit(PIN_A5, bit_test(i, 5)); //output counter's 5th bit
}
} |
|
![](templates/subSilver/images/spacer.gif) |
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
Some sample code |
Posted: Tue Dec 14, 2004 1:11 am |
|
|
Edit:
I believe this may be off by, oh... say 255*2 counts. After getting my beauty rest, I realized that you are getting counts every 100kHz (using the 3.2MHz clock) on the timer so you only need one count.
So you need to divide-by-16 (not 32), and set timer0 to 255, this way everytime it counts once it rolls over and sets the interrupt. The div-by-16 is there so you toggle at twice the desired frequency, giving you in effect the desired clock output.
You can also not divide down, and count 16 to interrupt (set timer0 to 256-16). This would give you a programmable divider with a maximum of 255). Unfortunately, you have to limit the maximum output frequency well below the master clock so you can do the output toggling. You may need to use a higher master clock (e.g. 16-20MHz) to give you room to do the interrupt service and bit toggling. As it is you only have 4 instruction cycles (with 4MHz master clock), and 200kHz toggling rate.
Clear as mud...
I have not tried this but have done something similar. This should get you started. For the frequencies you're referring to (i.e. 3.2MHz), counting with the internal clock (4MHz / 4 =1MHz) will not get you there. For this you have to use the timer function.
Example Code:
Code: |
/////////////////////////////////////////////////////////////////////////
/// Example program to output a divide-by-32 output from the CLKIN PIN
///
/// Fuses: LP,XT,INTRC,HS,NOWDT,WDT,CPD,NOCPD,PROTECT,NOPROTECT,NOMCLR
/// Fuses: MCLR,PUT,NOPUT,RC,EC,RC_IO,INTRC_IO,BROWNOUT,NOBROWNOUT
/// Fuses: BANDGAPLOW,BANDGAPHIGH
/////////////////////////////////////////////////////////////////////////
// Preprocessor
#include <12F629.h>
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOCPD,NOMCLR
#use delay(clock=4000000)
#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5
#define CLKOUT GP2
#define CLKIN GP5
int1 flag;
#INT_TIMER0
divider_isr()
{
if ( flag )
{
flag = 0;
}
else
{
flag = 1;
}
}
void init()
{
set_tris_a( 0b00111011 ); // set GP2 to output, all other inputs
setup_comparator( NC_NC_NC_NC ); // disable comparators
}
// Main Program
main()
{
init();
flag = 0;
setup_timer_0( RTCC_EXT_L_TO_H | RTCC_DIV_32 ); // divide CLKIN by 32
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
while (1)
{
if (flag)
{
output_high(CLKOUT);
}
else
{
output_low(CLKOUT);
}
}
} |
Hope it helps. |
|
![](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
|