I want to use Sm8s003f3p6 as a frequency counter , My program is as described in stm8s reference manual 17.4.3 External clock source mode 1
and
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
I want to know is this speed of counting correct ?
I
I want to make a frequency counter and need to have more speed to count
count high frequency wave .
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;#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
counter
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;
}
}
}
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;
}