milan.rajik
Banned
- Joined
- Apr 1, 2013
- Messages
- 2,524
- Helped
- 540
- Reputation
- 1,078
- Reaction score
- 524
- Trophy points
- 1,393
- Activity points
- 0
Why this PIC18F45K22 based frequency counter not working?
I am using PIC18F45K22 and 20 MHz crystal. I am testing in Proteus and also hardware but in Proteus it gives 216 Hz for 1500 Hz and in hardware it is not at all working. I am using T0CKI pin to read the input pulses. I think all registers are configured properly. I also lit an LED in hardware to see if WDT is resetting but no, WDT is not resetting. So, problem is something else. Please help me to solve the problem. I am attaching complete mikroC PRO PIC project files. I am feeding CCP1 to RA4/T0CKI. I have set PWM freq to 1500 Hz.
This is the code.
- - - Updated - - -
I made PIC16F877A based Frequency Counter and Tachometer and it gives exact values. In Proteus simulation use Clock model to feed clock pulses. I have also implemented code for CCP1 to generate 1500 Hz PWM, 50% duty. You can also feed that and check. It gives 1495 instead of 1500 Hz. I tested it both in Proteus and hardware and I get the same values in both. It is the problem of mikroC PRO PIC PWM library. It generated 1495 Hz for 1500 Hz. I fed 10 KHz from seeedstudio's DSO Quad to hardware PIC and it gave exact 10000 Hz without any fluctuations in reading. I have attached Proteus 8.1 SP1 format files. I will soon post code and video. My Camera battery is charging. I will improve the code to make a 60 Mhz frequency counter.
- - - Updated - - -
Edit:
videos attached. Shows testing in hardware (PIC16F877A). DSO Quad is feeding 100 KHz and I get 100000, 100006 and 100007 Hz readings in hardware. Maybe it is problem of DSO Quad. I don't have better frequency generator and counter to check if DSO Quad output is stable or not. Also simulation video attached. It shows values for different input values.
@FvM
Is this precision enough ?
I will make another project which uses Timer1 prescalar in counter mode and make it measure 50 MHz.
I am using PIC18F45K22 and 20 MHz crystal. I am testing in Proteus and also hardware but in Proteus it gives 216 Hz for 1500 Hz and in hardware it is not at all working. I am using T0CKI pin to read the input pulses. I think all registers are configured properly. I also lit an LED in hardware to see if WDT is resetting but no, WDT is not resetting. So, problem is something else. Please help me to solve the problem. I am attaching complete mikroC PRO PIC project files. I am feeding CCP1 to RA4/T0CKI. I have set PWM freq to 1500 Hz.
This is the code.
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 sbit Data7219 at LATD0_bit; sbit Load7219 at LATD1_bit ; sbit Clk7219 at LATD2_bit; sbit Data7219_Direction at TRISD0_bit; sbit Load7219_Direction at TRISD1_bit; sbit Clk7219_Direction at TRISD2_bit; const unsigned char Font_B[16] = {0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70, 0x7f,0x7b,0x77,0x1f,0x4e,0x3d,0x4f,0x47 }; void Send7219 (char,char); void Send7219byte(char); void MAX7219init(); void Display(unsigned long); char freq[17]; unsigned long frequency = 0; char start = 0; char counter = 0, done_ = 0; //Timer1 //Prescaler 1:8; TMR1 Preload = 3036; Actual Interrupt Time : 100 ms //Place/Copy this part in declaration section void interrupt() { if(TMR0IF_bit) { TMR0IF_bit = 0; ++frequency; } if(TMR1IF_bit) { TMR1IF_bit = 0; TMR1H = 0x0B; TMR1L = 0xDC; //Enter your code here if(++counter == 10) { TMR0ON_bit = 0; TMR0IE_bit = 0; TMR1IE_bit = 0; counter = 0; done_ = 1; } } } void MAX7219init() { Data7219_Direction = 0; Load7219_Direction = 0; Clk7219_Direction = 0; Data7219 = 0; Load7219 = 0; Clk7219 = 0; Send7219(0x09, 0x00); //Decode Mode Send7219(0x0A, 0x05); //Brightness Send7219(0x0B, 0x07); //Scan limit Send7219(0x0C, 0x01); Send7219(0x0F, 0x00); } void Send7219(char Digit,char Data) { Send7219byte(Digit); Send7219byte(Data); Data7219 = 0; Load7219 = 1; Delay_us(20); Load7219 = 0; } void Send7219byte(char byte) { unsigned char i; for(i = 0; i < 8; i++) { if(byte & 0x80) Data7219 = 1; else Data7219 = 0; Clk7219 = 1; Delay_us(50); Clk7219 = 0; byte <<= 1; } } void Display(unsigned long myUInt) { unsigned char dispskip; // add 1 if "." found within string unsigned char i, str[30]; LongToStr(myUInt, str); //Convert float value to string Ltrim(str); //remove spaces padded to left of string dispskip = strlen(str) - 1; if(dispskip >= 8)dispskip = 7; i = 0; while(i <= dispskip) { if((str[dispskip-i] >= 0x30) && (str[dispskip - i] <= 0x39)) { Send7219(i+1, (Font_B[str[dispskip-i] - 0x30]));//0-9 } i++; } /*while(i <= 8) { Send7219(i, 0); i++; }*/ } void main() { CM1CON0 = 0x00; CM2CON0 = 0x00; ANSELA = 0x00; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; ANSELE = 0x00; TRISA = 0xF0; TRISB = 0x00; TRISC = 0x00; TRISD = 0x00; TRISE = 0x08; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x08; LATA = 0x00; LATB = 0x00; LATC = 0x00; LATD = 0x00; LATE = 0x00; MAX7219init(); Display(frequency); PWM1_Init(1500); PWM1_Set_Duty(127); PWM1_Start(); Delay_ms(2000); while(1) { if(start == 0) { TMR0H = 0; TMR0L = 0; T1CON = 0x31; INTCON = 0xC0; T0CON = 0b10101000; TMR1IF_bit = 0; TMR0IF_bit = 0; TMR1H = 0x0B; TMR1L = 0xDC; TMR0IE_bit = 1; TMR1IE_bit = 1; start = 1; } if(done_) { frequency = (frequency * 65536) + ((TMR0H << 8) + TMR0L); Display(frequency); frequency = 0; done_ = 0; start = 0; } LATD.F7 = 1; } }
- - - Updated - - -
I made PIC16F877A based Frequency Counter and Tachometer and it gives exact values. In Proteus simulation use Clock model to feed clock pulses. I have also implemented code for CCP1 to generate 1500 Hz PWM, 50% duty. You can also feed that and check. It gives 1495 instead of 1500 Hz. I tested it both in Proteus and hardware and I get the same values in both. It is the problem of mikroC PRO PIC PWM library. It generated 1495 Hz for 1500 Hz. I fed 10 KHz from seeedstudio's DSO Quad to hardware PIC and it gave exact 10000 Hz without any fluctuations in reading. I have attached Proteus 8.1 SP1 format files. I will soon post code and video. My Camera battery is charging. I will improve the code to make a 60 Mhz frequency counter.
- - - Updated - - -
Edit:
videos attached. Shows testing in hardware (PIC16F877A). DSO Quad is feeding 100 KHz and I get 100000, 100006 and 100007 Hz readings in hardware. Maybe it is problem of DSO Quad. I don't have better frequency generator and counter to check if DSO Quad output is stable or not. Also simulation video attached. It shows values for different input values.
@FvM
Is this precision enough ?
I will make another project which uses Timer1 prescalar in counter mode and make it measure 50 MHz.
Attachments
Last edited: