cancel
Showing results for 
Search instead for 
Did you mean: 

STM8 startup bug Timer 2 input capture

mitchell
Associate
Posted on April 28, 2015 at 12:50

Hi,

I wanna make a frequency pulse counter with an STM8. The counter is based on the input capture of the STM timer 2. The frequency is a frequency with a range of 1 Hz - 20 kHz. With the following code this is possible:


#include <
iostm8s003k3.h
>

#include <
intrinsics.h
>

#include <
stdio.h
>

#include ''stm8s.h''


unsigned int CaptureLow;

unsigned int CaptureHigh;

unsigned int CaptureValue;

unsigned int Freq;

unsigned char flag;

char string[20];

float Frequency;


//

// Setup the system clock to run at 16MHz using the internal oscillator.

//

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; // Ditto.

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 InitMCU(void)

{

PB_DDR = 0x0F;

PB_CR1 = 0x0F;

PB_ODR = 0x00;


PC_DDR_DDR1 = 1;

PC_CR1_C11 = 1;

PC_ODR_ODR1 = 0;


PC_DDR_DDR2 = 1;

PC_CR1_C12 = 1;

PC_ODR_ODR2 = 0;

}


void InitCaptureTIM2(void)

{

TIM2_PSCR = 3;

TIM2_CCMR1 = 0x01; //CAPTURE / VERGELIJK moderegister 1

TIM2_CCER1_CC1P = 0;

TIM2_CCER1_CC1E = 1;

TIM2_SR1_CC1IF = 0;

TIM2_SR2_CC1OF = 0;

TIM2_IER_CC1IE = 1;

}


void __delay(void)

{

unsigned long int j=200000;

while(j--);

}


//

// Setup the UART to run at 115200 baud, no parity, one stop bit, 8 data bits.

//

// Important: This relies upon the systemk clock being set to run at 16 MHz.

//

void InitialiseUART()

{

//

// Clear the Idle Line Detected bit in the status rerister by a read

// to the UART1_SR register followed by a Read to the UART1_DR register.

//

unsigned char tmp = UART1_SR;

tmp = UART1_DR;

//

// Reset the UART registers to the reset values.

//

UART1_CR1 = 0;

UART1_CR2 = 0;

UART1_CR4 = 0;

UART1_CR3 = 0;

UART1_CR5 = 0;

UART1_GTR = 0;

UART1_PSCR = 0;

//

// Now setup the port to 115200,n,8,1.

//

UART1_CR1_M = 0; // 8 Data bits.

UART1_CR1_PCEN = 0; // Disable parity.

UART1_CR3_STOP = 0; // 1 stop bit.

UART1_BRR2 = 0x0a; // Set the baud rate registers to 115200 baud

UART1_BRR1 = 0x08; // based upon a 16 MHz system clock.

//

// Disable the transmitter and receiver.

//

UART1_CR2_TEN = 0; // Disable transmit.

UART1_CR2_REN = 0; // Disable receive.

//

// Set the clock polarity, lock phase and last bit clock pulse.

//

UART1_CR3_CPOL = 1;

UART1_CR3_CPHA = 1;

UART1_CR3_LBCL = 1;

//

// Turn on the UART transmit, receive and the UART clock.

//

UART1_CR2_TEN = 1;

UART1_CR2_REN = 1;

UART1_CR3_CKEN = 1;

}


//

// Send the message in the string to UART1.

//

void UARTPrintF(char *message)

{

char *ch = message;

while (*ch)

{

UART1_DR = (unsigned char) *ch; // Put the next character into the data transmission register.

while (UART1_SR_TXE == 0); // Wait for transmission to complete.

ch++; // Grab the next character.

}

}


int main( void )

{


//Setup of program, initializing

__disable_interrupt();

InitMCU(); 

InitCaptureTIM2();

InitialiseSystemClock();

InitialiseUART();

__enable_interrupt();


TIM2_CR1_CEN = 1; 


for(;;)

{

Frequency = (float)Freq/0;


sprintf(string,''%.2f \n\r'',Frequency);

UARTPrintF(string);

}

}


#pragma vector = TIM2_CAPCOM_CC1IF_vector

__interrupt void Timer2_CAPTURE_INT(void)

{ 

if(!flag)

{

TIM2_CNTRH = 0;

TIM2_CNTRL = 0;

flag ^= 1;

}

else

{

CaptureHigh = TIM2_CCR1H;

CaptureLow = TIM2_CCR1L;

CaptureValue = ((CaptureHigh << 8) | CaptureLow);

flag ^= 1;

Freq = 200000000/CaptureValue;

}

}

My problem is that there is a bug in the code. The timer UART output start always with a wrong frequency (1150 Hz), maybe a reset or an initialisation is wrong but I can't find the mistake? When the frequency drops down, below 50 Hz, the system is working until a new system startup. With a new system startup there is the same start up problem. What is wrong in my code?? Thankyou!!
0 REPLIES 0