|
|
View previous topic :: View next topic |
Author |
Message |
Bernhard
Joined: 02 May 2011 Posts: 2
|
Frequency counter with PIC16F877A HELP! |
Posted: Mon May 02, 2011 12:18 pm |
|
|
Hi. I'm working on a project to count the number of interruptions per second. I found this frequency counter schematic and modified the PIC program. Mainly the code counts the number of "1s" on RB0, convert it into decimal, then shows it on the common cathode ssd. The problem I have is showing the number of interruptions in digits because it is supposed to show 1s in 150us, then 10s in 150us, then 100s 150us after, etc... but it only refreshes all seven segment display at the same time. So I can see digit, only the display turned on.
Here is my code and schematic.
Code: |
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Project : Simple frequency counter using PIC16F877A, crystal frequency 4Mhz
// compiler : HITEC PICC
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#define PIC_CLK 4000000
#include <pic.h>
///////////////////////////////////////////////////////////////////
__CONFIG(XT & WDTDIS & PWRTDIS & BORDIS & LVPDIS );
///////////////////////////////////////////////////////////////////
unsigned long cntr ; // number of RB0 transition
unsigned int ovrflw ; // number of timer0 overflows
unsigned long x ;
unsigned int y ;
///////////////////////////////////////////////////////////////////
unsigned char digit0, digit1, digit2, digit3;
const char ssd[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//SSD mask for common cathode type
///////////////////////////////////////////////////////////////////
unsigned char delayus_variable;
#if (PIC_CLK == 4000000)
#define dly1u asm("nop")
#define dly2u dly1u;dly1u
#endif
//*****
//delay routine
#if PIC_CLK == 4000000
#define DelayDivisor 4
#define WaitFor1Us asm("nop")
#define Jumpback asm("goto $ - 2")
#endif
void decode(unsigned int value){
digit3=value/1000;
digit2=(value%1000)/100;
digit1=(value%100)/10;
digit0=(value%10);
}
void DelayUs(unsigned char x) {
delayus_variable=(unsigned char)(x/DelayDivisor);
WaitFor1Us;
}
unsigned char delayus_variable;
void DelayBigUs(unsigned int cnt)
{
unsigned char i;
i = (unsigned char)(cnt>>Cool;
while(i>=1)
{
i--;
DelayUs(253);
CLRWDT();
}
DelayUs((unsigned char)(cnt & 0xFF));
}
void DelayMs(unsigned char cnt)
{
unsigned char i;
do {
i = 4;
do {
DelayUs(250);
CLRWDT();
} while(--i);
} while(--cnt);
}
//this copy is for the interrupt function
void DelayMs_interrupt(unsigned char cnt)
{
unsigned char i;
do {
i = 4;
do {
DelayUs(250);
} while(--i);
} while(--cnt);
}
void DelayBigMs(unsigned int cnt)
{
unsigned char i;
do {
i = 4;
do {
DelayUs(250);
CLRWDT();
} while(--i);
} while(--cnt);
}
void DelayS(unsigned char cnt)
{
unsigned char i;
do {
i = 4;
do {
DelayMs(250);
CLRWDT();
} while(--i);
} while(--cnt);
}
///////////////////////////////////////////////////////////////////
void display(){
unsigned char i;
for(i=0;i<5;i++){
PORTD=0b00000001;
PORTC=ssd[digit0];
DelayUs(150);
PORTD=0b00000010;
PORTC=ssd[digit1];
DelayUs(150);
PORTD=0b00000100;
PORTC=ssd[digit2];
DelayUs(150);
PORTD=0b00001000;
PORTC=ssd[digit3];
DelayUs(150);
}
}
///////////////////////////////////////////////////////////////////
main(){
TRISD=0b11110000;
TRISC=0; //
TRISB = 3 ; //input
///////////////////////
OPTION = 0b11011000 ; //no prescaler
INTCON = 0b10110000 ; //T0IF, INTF and GIE enabled
while(1){
if (RB1 == 1) y=(x/1000); //for scaling Display to KHz
else y=x;
decode(y); //Display frequency on Seven Segment Display
display();
}
}
///////////////////////////////////////////////////////////////////
/* * interrupt routine called 4000000/256 times by seconds :
* the timer TMR0 is increased each 4 clock cycles (quartz frequency is 16 Mhz),
* and overflows when reseting from 255 to 0,
* calling the interrupt procedure with bit T0IF set
* * also called on each RBO transition, with bit INTF set */
void interrupt isr(void){
if ((INTF)){
cntr++ ; // inc. transition counter
INTF = 0 ; // clear interrupt flag to enable next call
}
else if(T0IF==1){
ovrflw++ ; // inc. overflow counter
T0IF = 0 ; // clear interrupt flag to enable next call on overflow
}
if (ovrflw > 3906) { // 4000000/ 4/ 256 = 3906.25
GIE = 0;
x=cntr;
cntr = 0 ; // clear counters
ovrflw = 0 ;
INTCON = 0b10110000 ; // T0IF, INTF and GIE enabled
}
} |
I added 330ohm resistors on every segment. Thanks for any help!
[img]http://935158805287174861-a-1802744773732722657-s-sites.googlegroups.com/site/ehobbyprojects/make-a-simple-frequency-counter/untitled.JPG?attachauth=ANoY7cpVJCEJIdFP0sQdTMdym0p8GLxXYGVw5wPtXpx4j9AUkhWLJ7TYAK_tYxianBlnhWoaF62O80Kc4OccP0_9550E0CR8vJf9k0oCoNjDddvH3Wz-g5HVmZfJSKtsrY2hRhL6qynutZJ1nBtLmCO3nDwkKNtx66Qg-OpL3pUYvCpBotwOGP6Xdt2OSQIMvVet2OPdbQaFB_kNg_CT7qOFhsQDFgtltamdbMK8ng-SCJfpRG3F6K1CaA8C0J82c2_0Tx2oPdHW&attredirects=0[/img] |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Bernhard
Joined: 02 May 2011 Posts: 2
|
|
Posted: Mon May 02, 2011 12:57 pm |
|
|
I'm using Microchip MPASM Toolsuite |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 02, 2011 1:28 pm |
|
|
It's not MPASM. It's C.
And, your own code says it's for HiTech C:
Quote: | compiler : HITEC PICC |
In any case, this is not the correct forum for you. |
|
|
|
|
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
|