2021-05-06 11:32 AM
My program is as described in stm8s reference manual 17.4.3 External clock source mode 1
and pulse counting is done in pin PC7 using HSI 16 Mhz , but the speed of counting is very low , for example for a 10 mhz pulse in 1 ms TIM1_CNTRL counts to 60 .
I want to know is this speed of counting correct ?
I want to make a frequency counter and need to have more speed to count high frequency wave . now it is possible to count up to 200 mhz pulse but resolution is very bad due to low speed of timer1 pulse counting .
As I said for 10 mhz pulse , counter is 60 so each increment of counter is equal to 10Mhz/60 = 167 khz .
my code for timer counter is as follows
#include <iostm8S003f3.h>
#include <intrinsics.h>
unsigned long int fr=0,f=0; // fr increment in timer1 overflow , f is number of final pulse counting
unsigned char h; //dummy variable
int main(void)
{
__disable_interrupt();
InitialiseSystemClock();
InitialisePorts();
config_counter();
TIM1_IER_UIE = 1; // enable timer 1 interrupt
__enable_interrupt();
while (1)
{
fr=0;
TIM1_CNTRH = 0; //reset counter
TIM1_CNTRL = 0;
TIM1_CR1_CEN=1; // start counting
delayms(1);
TIM1_CR1_CEN=0; // stop counting
// calculate counter as a number = TIM1_CNTRH*256 + TIM1_CNTRL + fr*65536
// fr will increment whenever tim1 counter overflows
h=TIM1_CNTRH ;
f=h*256;
h=TIM1_CNTRL;
f=f+h;
f=fr*65536+f;
}
}
void delayms(int t)
{
int d;
while(t--)
for (d = 0; d < 2020; ++d) ; //approximately 1 ms delay with 16 mhz clock
}
#pragma vector = TIM1_OVR_UIF_vector
__interrupt void TIM1_UPD_OVF_IRQHandler(void)
{
fr++;
TIM1_SR1_UIF = 0;
}
void InitialisePorts()
{
PC_DDR_DDR7=0; // pc7 as input
PC_CR1_C17 = 0; // no pullup
PC_CR2_C27 = 0; // no interrupt
}
void InitialiseSystemClock()
{
CLK_ICKR = 0; // Reset the Internal Clock Register.
CLK_ICKR_HSIEN = 1; // Enable the HSI.
CLK_ECKR = 0; // Disable the external clock.
while (CLK_ICKR_HSIRDY == 0); // Wait for the HSI to be ready for use.
CLK_CKDIVR = 0; // Ensure the clocks are running at full speed.
CLK_PCKENR1 = 0xff; // Enable all peripheral clocks.
CLK_PCKENR2 = 0xff;
CLK_CCOR = 0; // Turn off CCO.
CLK_HSITRIMR = 0; // Turn off any HSIU trimming.
CLK_SWIMCCR = 0; // Set SWIM to run at clock / 2.
CLK_SWR = 0xe1; // Use HSI as the clock source.
CLK_SWCR = 0; // Reset the clock switch control register.
CLK_SWCR_SWEN = 1; // Enable switching.
while (CLK_SWCR_SWBSY != 0); // Pause while the clock switch is busy.
}
void config_counter(){
TIM1_CNTRH = 0;
TIM1_CNTRL = 0; //Reset counter
TIM1_IER = 0; //Interrupt disabled
TIM1_SR1 = 0; //Clear Interrupt
TIM1_CCMR2 |= 1<<0; //External pulse source T1C2
TIM1_CCER1 &= ~(1<<5); //Rising edge
TIM1_SMCR |= (7<<0); //External Clock Source
TIM1_SMCR |= (6<<4); //T1C2 Input Source
TIM1_CR1 &= ~(1<<0); //Counter disabled
return;
}
2021-05-07 03:28 AM
Any input signal has to be synchronized with the internal clock. In RM0016 page 191 you can read that:
---
The ETRP frequency must be, at most,1/4 of fMASTER frequency. A prescaler can be enabled to
reduce ETRP frequency. It is useful when inputting fast external clocks.
---
So if your internal clock is 16 MHz, the maximum input frequency is 4 MHz. This is (probably) valid or every input to every peripheral, don't go any higher than 1/4 of the internal clock.
2021-05-07 03:40 AM
I would suggest an external prescaler, like a highspeed equivalent to the 74LS68/74LS69, 74x90/74x93. or 74x160..163.
2021-05-07 03:50 AM
That would be the 74HC series, such as the 74HC390 (dual decade) or the 74HC393 (dual 4-bit binary riplle counter) The 74LS series need 5V to work, the 74HC will work as low as 2V although then they aren't very fast anymore. At 3.3V a frequency of 10 MHz will work fine.
2023-06-08 01:42 AM
Thanks for your answer.