cancel
Showing results for 
Search instead for 
Did you mean: 

STM8 Frequency Counter

SBrow.1
Associate II

Hello, I'm trying to implement a simple frequency counter. The idea is I have some external signal sitting at 6MHz, and I want to measure it by simply starting the TIM1 counter, waiting 1ms (delay), then reading the count, which I'd expect to be about 6,000. I also have an AND gate which i use to control when the 6MHZ is present on pin C3 (TIM1 chan 3); by writing high to the end gate the signal is present and by writing low, there is no signal. This is the only job for the microcontroller, and the signal in question isn't fast changing so taking a 1ms sample every 200ms should be more than enough.

Here's my main routine

main(){
	clock_setup();
	GPIO_setup();
	UART1_setup();
	TIM1_setup();
	TIM4_setup();
		
	SerialPutString("Starting STM8 \r\n");
	while(1){
		GPIO_WriteReverse(GPIOD, GPIO_PIN_2); //LED
 
	       delay_ms(200);  //slow down the blinking		
		TIM1_setup();
		//TIM1_SetCounter(0);  //Clear the count
		GPIO_WriteHigh(GPIOC, GPIO_PIN_4);  //AND Gate
		delay_us(1000);
		GPIO_WriteLow(GPIOC, GPIO_PIN_4);  //AND Gate
		count = TIM1_GetCapture3();
		//count = TIM1_GetCounter();
		
		clearprintBuffer(printBuffer);
		SerialPutString(printBuffer);  //For some this needs to be called first
                sprintf(printBuffer, "count = %u \r\n", count);
                SerialPutString(printBuffer);
	}
}

I've confirmed that the AND gate is being set correctly, and I've confirmed that the delay_us() function is working correctly. The issue is that I am getting ~16,146 as the output of TIM1_GetCounter(), which appears to be my 16MHZ clock, rather than the signal on pin C3.

Below is my Timer1 setup:

void TIM1_setup(void){	
//links:		
//https://sites.google.com/site/klaasdc/stm8s-projects/rpm-counter-1?authuser=0
//http://embedded-lab.com/blog/starting-stm8-microcontrollers/22/
	TIM1_DeInit();
  TIM1_TimeBaseInit(1, TIM1_COUNTERMODE_UP, 65535, 0);
  TIM1_ICInit(TIM1_CHANNEL_3, TIM1_ICPOLARITY_RISING, 	
							TIM1_ICSELECTION_DIRECTTI,  TIM1_ICPSC_DIV1, 0x00);
  TIM1_SelectInputTrigger(TIM1_TS_TI1F_ED); //Triggered by edge
  // Trigger standard mode - The counter starts at a rising edge of the trigger TRGI (but, it is not reset). 	Only the start of the counter is controlled. 
  TIM1_SelectSlaveMode(TIM1_SLAVEMODE_TRIGGER);
  // Overflow interrupt ; Capture1 interrupt enabled 
	TIM1_ITConfig(TIM1_IT_UPDATE | TIM1_IT_CC3, DISABLE);
  // Generate an update event to ensure values are set
  TIM1_GenerateEvent(TIM1_EVENTSOURCE_CC3);
  // Clear CC1 and update interrupt flag 
  TIM1_ClearFlag(TIM1_FLAG_CC3 | TIM1_FLAG_UPDATE);
  // Enable TIM1 
  TIM1_Cmd(ENABLE);
}

and here is my clock setup:

void clock_setup(void){
	CLK_DeInit();
                     
  CLK_HSECmd(ENABLE);
  CLK_LSICmd(DISABLE);
  CLK_HSICmd(DISABLE);
  while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);
      
  CLK_ClockSwitchCmd(ENABLE);
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
      
  CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, 
      DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
			
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);
  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, ENABLE); 
}

Can anyone advise me on how I should configure TIM1 for it to count the number of pulses on channel 3 (pin C3)? Also, I've noticed I'm getting the same value from both TIM1_GetCounter(), and TIM1_GetCapture3(), can anyone advise me on the differences between these two signals?

0 REPLIES 0