AnsweredAssumed Answered

Timer 1, Channel 3 Lower Than Expected Output Voltage

Question asked by stevens.mark on Sep 4, 2012
Latest reply on Jul 4, 2017 by Aaron Derbyshire
I have been developing some applications for the STM8S103F3 which I have on breadboard and I have recently transferred one of the projects to the STM8S Discovery board and I am finding a difference in behaviour which I cannot work out.

The program uses PWM Mode 2 to output a 60 uS square wave on timer 1 channel3.  On the STM8S103F3 on breadboard the program works fine and I get a 0 to 3.3V square wave.

On the Discovery board I have the square wave with the right frequency but the output voltage is only 280 mV peak-to-peak.  The only things I have connected to the Discovery board are the USB connection and the scope connected to the timer output and ground.

I am using IAR as the development environment and I have modified the include files and project options accordingly.

Any ideas where I could be going wrong? Am I correct in assuming that if the app runs on the STM8S103F3 then it will run on the Discovery board assuming I change the include file and target chip?

The code for the application is included below.

Regards,
Mark

#include <intrinsics.h>
#include <iostm8s103f3.h>


//
//  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.
}


//
//  Initialise Timer 1.
//
void InitialiseTimer1()
{
    TIM1_CR1 = 0;
    TIM1_CR2 = 0;
    TIM1_SMCR = 0;
    TIM1_ETR = 0;
    TIM1_IER  = 0;
    TIM1_SR2  = 0;
    TIM1_CCER1 = 0;
    TIM1_CCER2 = 0;
    TIM1_CCMR1 = 0;
    TIM1_CCMR2 = 0;
    TIM1_CCMR3 = 0;
    TIM1_CCMR4 = 0;
    TIM1_CCER1 = 0;
    TIM1_CCER2 = 0;
    TIM1_CCMR1 = 0;
    TIM1_CCMR2 = 0;
    TIM1_CCMR3 = 0;
    TIM1_CCMR4 = 0;
    TIM1_CNTRH = 0;
    TIM1_CNTRL = 0;
    TIM1_PSCRH = 0;
    TIM1_PSCRL = 0;
    TIM1_ARRH  = 0;
    TIM1_ARRL  = 0;
    TIM1_CCR1H = 0;
    TIM1_CCR1L = 0;
    TIM1_CCR2H = 0;
    TIM1_CCR2L = 0;
    TIM1_CCR3H = 0;
    TIM1_CCR3L = 0;
    TIM1_CCR4H = 0;
    TIM1_CCR4L = 0;
    TIM1_OISR  = 0;
    TIM1_EGR   = 0x01;
    TIM1_DTR   = 0;
    TIM1_BKR   = 0;
    TIM1_RCR   = 0;
    TIM1_SR1   = 0;
}


//
//  Set up Timer 1, channel 3 to output a single pulse lasting 30 uS.
//
void SetupTimer1()
{
    TIM1_ARRH = 0x03;       //  Reload counter = 960
    TIM1_ARRL = 0xc0;
    TIM1_PSCRH = 0;         //  Prescalar = 0 (i.e. 1)
    TIM1_PSCRL = 0;
    TIM1_CR1_DIR = 0;       //  Up counter.
    TIM1_CR1_CMS = 0;       //  Edge aligned counter.
    TIM1_RCR = 0;           //  No repetition.
    //
    //  Now configure Timer 1, channel 3.
    //
    TIM1_CCMR3_OC3M = 7;    //  Set up to use PWM mode 2.
    TIM1_CCER2_CC3E = 1;    //  Output is enabled.
    TIM1_CCER2_CC3P = 0;    //  Active is defined as high.
    TIM1_CCR3H = 0x01;      //  480 = 50% duty cycle (based on TIM1_ARR).
    TIM1_CCR3L = 0xe0;
    TIM1_BKR_MOE = 1;       //  Enable the main output.
//    TIM1_CR1_OPM = 1;
    TIM1_CR1_CEN = 1;
}


//
//  Main program loop.
//
void main()
{
    //
    //  Initialise the system.
    //
    __disable_interrupt();
    InitialiseSystemClock();
    InitialiseTimer1();
    SetupTimer1();
    __enable_interrupt();
    while (1)
    {
        __wait_for_interrupt();
    }
}

Outcomes