Skip to main content
thomaspfeffer9
Associate
July 11, 2011
Question

Creating a square wave

  • July 11, 2011
  • 14 replies
  • 6347 views
Posted on July 11, 2011 at 15:01

I'm an absolutly beginner in microcontrollers.

I want to create a simple square wave signal on STM32F103VB with

tim3, ch2, but nothing happens.

Can anybody tell me what I'm doing wrong?

Thanks

Tom

#define DEF_SPEED 140;

#define CCR1_Val  32768;

int main(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

  TIM_OCInitTypeDef TIM_OCInitStructure;

  // RCC/System clocks configuration

  RCC_Config();

  // Enable Timer3 clock and release reset

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

  // map PC7 as TIM3-CH2

  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7; //7

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // clock to 50MHz

  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;  // alternate function pull

  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); // ?!!!!!!!!!!

  // Time base configuration

  TIM_TimeBaseStructure.TIM_Period = 0xFF; // 8 bit resolution

  TIM_TimeBaseStructure.TIM_Prescaler = DEF_SPEED;       

  TIM_TimeBaseStructure.TIM_ClockDivision = 0;    

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

 

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  // Output Compare Toggle Mode configuration: Channel2

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;          

  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;  

  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

  TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  TIM_Cmd(TIM3,ENABLE);

 

  while (1) {}

}

    This topic has been closed for replies.

    14 replies

    Tesla DeLorean
    Guru
    July 11, 2011
    Posted on July 11, 2011 at 17:07

    If you're going to remap pins, you'll need to enable the AFIO peripheral first.

    Personally, to generate a square wave, I'd be using the PWM mode and set the pulse width to 50%.

    What are you bus frequencies, and what output frequency are you looking at?

    int main(void)

    {

      u16 period; // Period, interrupt periodicity in timer ticks

      u16 scale; // Prescale another clock divider (1-65536)

      u16 width; // Pulse width

      GPIO_InitTypeDef GPIO_InitStructure;

      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

      TIM_OCInitTypeDef TIM_OCInitStructure;

      // RCC/System clocks configuration

      RCC_Config();

      // Enable Timer3 clock and release reset

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // Permit ReMap

      // map PC7 as TIM3-CH2

      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7; //7

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // clock to 50MHz

      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;  // alternate function pull

      GPIO_Init(GPIOC, &GPIO_InitStructure);

      GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

      //  72 MHz Master Clock

      scale = 72; // 72 MHz / 72 = 1 MHz

      period = 1000; // 1 MHZ / 1000 = 1 KHz

      width = period / 2;     //  ~50/50 duty

      // Time base configuration

      TIM_TimeBaseStructure.TIM_Period = (period - 1); // 1-65536

      TIM_TimeBaseStructure.TIM_Prescaler = (scale - 1); // 1-65536, Master Clock Divisor

      TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 1,2 or 4 for tDTS

      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

     

      TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

       /* PWM1 Mode configuration: Channel2 on PC.07 */

      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

      TIM_OCInitStructure.TIM_Pulse = width; // Pulse Width

      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

      TIM_OC2Init(TIM3, &TIM_OCInitStructure);

      TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

      TIM_ARRPreloadConfig(TIM3, ENABLE);

      /* TIM3 enable counter */

      TIM_Cmd(TIM3,ENABLE);

     

      while (1) {}

    }

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    thomaspfeffer9
    Associate
    July 12, 2011
    Posted on July 12, 2011 at 11:35

    Yes, it works fine, thank you.

    Finally the frequency should be adjustable in steps as well as continuous by software.
    pritz1
    Associate II
    September 19, 2011
    Posted on September 19, 2011 at 21:27

    Will this code also work for the STM32 Discovery board?  What is TIM3-CH2?

    Tesla DeLorean
    Guru
    September 19, 2011
    Posted on September 19, 2011 at 22:29

    Will this code also work for the STM32 Discovery board?  What is TIM3-CH2?

    Which one? They make a VL and L series Discovery Board. The former won't run at 72 MHz, so you'll need to adapt it to be appropriate. The STM32F100 (VL) runs at up to 24 MHz.

    TIM3-CH2 is Channel Two, of Timer Three. The port output can be observed on PIN PC.7 presuming you remap/mux it  there. If this isn't making sense you should probably review the technical documentation, and pin configuration diagrams, in the manuals.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    pritz1
    Associate II
    September 22, 2011
    Posted on September 22, 2011 at 20:26

    Nice.  That wasn't too hard for me to figure out, although I ended up just commenting out RCC_Config() because it said the function did not exist...

    Is there an easy way to output two square waves of different frequencies simultaneously?

    Tesla DeLorean
    Guru
    September 22, 2011
    Posted on September 22, 2011 at 21:23

    That wasn't too hard for me to figure out, although I ended up just commenting out RCC_Config() because it said the function did not exist...

    This is an abstraction from the OP, but most of us park the initialization of RCC source/pll/ahb/apb dividers in it's own subroutine to localize it and permit change in a singular location. Depending on the library you're using this might occur prior to the run-time calling main(), or if you don't do anything the system will come up at 8 MHz via the HSI.

    Is there an easy way to output two square waves of different frequencies simultaneously?

     

    Sure, use one of the other timers. You could use the same timer and output signals of the same frequency, but with different duty cycles, on alternate channels.

    Your ability to generate certain frequencies depends on your core clocks, but you're not limited to 8 MHz, you can use magic number crystals (ie 7.15909 MHz for NTSC). Also you might need to choose a lower core frequency and PLL settings, for example to get 256 KHz out, you'd need to run the core at 64 MHz, instead of 72 MHz, the VL will be further limited.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    pritz1
    Associate II
    September 27, 2011
    Posted on September 27, 2011 at 23:21

    I tried to alter the code to use the TIM3 to output a 200 Hz signal and to use the TIM2 to output a 220 Hz signal.  It doesn't work so well.  The TIM3-200Hz signal works fine but the TIM2-220Hz signal does not.  What have I done wrong?  This is for the stm32 VL Discovery board.

     u16 period; // Period, interrupt periodicity in timer ticks

     u16 scale; // Prescale another clock divider (1-65536)

     u16 width; // Pulse width

     GPIO_InitTypeDef GPIO_InitStructure;

     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

     TIM_OCInitTypeDef TIM_OCInitStructure;

     // RCC/System clocks configuration

     //RCC_Config();

     // Enable Timer3, Timer2 clock and release reset

     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // Permit ReMap

     // map PC7 as TIM3-CH2

     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7; //7

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // clock to 50MHz

     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;  // alternate function pull

     GPIO_Init(GPIOC, &GPIO_InitStructure);

     GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

     //  24 MHz Master Clock

     scale = 24; // 24 MHz / 24 = 1 MHz

     period = 5000; // 1 MHZ / 5000 = 200 Hz

     width = period / 2;     //  ~50/50 duty

     // Time base configuration

     TIM_TimeBaseStructure.TIM_Period = (period - 1); // 1-65536

     TIM_TimeBaseStructure.TIM_Prescaler = (scale - 1); // 1-65536, Master Clock Divisor

     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 1,2 or 4 for tDTS

     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

      /* PWM1 Mode configuration: Channel2 on PC.07 */

     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

     TIM_OCInitStructure.TIM_Pulse = width; // Pulse Width

     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

     TIM_OC2Init(TIM3, &TIM_OCInitStructure);

     TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

     TIM_ARRPreloadConfig(TIM3, ENABLE);

     /* TIM3 enable counter */

     TIM_Cmd(TIM3,ENABLE);

     // map PC6 as TIM2-CH2

     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6; //6

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // clock to 50MHz

     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;  // alternate function pull

     GPIO_Init(GPIOC, &GPIO_InitStructure);

     GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);

     //  24 MHz Master Clock

     scale = 24; // 24 MHz / 24 = 1 MHz

     period = 4545; // 1 MHZ / 4545 = 220 Hz

     width = period / 2;     //  ~50/50 duty

     // Time base configuration

     TIM_TimeBaseStructure.TIM_Period = (period - 1); // 1-65536

     TIM_TimeBaseStructure.TIM_Prescaler = (scale - 1); // 1-65536, Master Clock Divisor

     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 1,2 or 4 for tDTS

     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

     /* PWM1 Mode configuration: Channel2 on PC.06 */

     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

     TIM_OCInitStructure.TIM_Pulse = width; // Pulse Width

     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

     TIM_OC2Init(TIM2, &TIM_OCInitStructure);

     TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

     TIM_ARRPreloadConfig(TIM2, ENABLE);

     /* TIM2 enable counter */

     TIM_Cmd(TIM2,ENABLE);

     while (1) {}

    Tesla DeLorean
    Guru
    September 28, 2011
    Posted on September 28, 2011 at 03:32

    You're not going to be able to push the TIM2 signal out of PC.6, it just isn't connected like that, refer to the pin definitions in Table 4 of the STM32F100xx manual.

    TIM2_CH1 could be on PA.0 without remapping the peripheral, TIM2_CH2 on PA.1 (remappable to PB.3)

    Lose the remap, enable the GPIOA clock, configure/use PA.1 for the clock output.

    Quoted Message

    I tried to alter the code to use the TIM3 to output a 200 Hz signal and to use the TIM2 to output a 220 Hz signal.  It doesn't work so well.  The TIM3-200Hz signal works fine but the TIM2-220Hz signal does not.  What have I done wrong?  This is for the stm32 VL Discovery board.

              u16 period; // Period, interrupt periodicity in timer ticks

     u16 scale; // Prescale another clock divider (1-65536)

     u16 width; // Pulse width

     GPIO_InitTypeDef GPIO_InitStructure;

     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

     TIM_OCInitTypeDef TIM_OCInitStructure;

     // RCC/System clocks configuration

     //RCC_Config();

     // Enable Timer3, Timer2 clock and release reset

     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // Permit ReMap

     // map PC7 as TIM3-CH2

     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7; //7

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // clock to 50MHz

     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;  // alternate function pull

     GPIO_Init(GPIOC, &GPIO_InitStructure);

     GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

     //  24 MHz Master Clock

     scale = 24; // 24 MHz / 24 = 1 MHz

     period = 5000; // 1 MHZ / 5000 = 200 Hz

     width = period / 2;     //  ~50/50 duty

     // Time base configuration

     TIM_TimeBaseStructure.TIM_Period = (period - 1); // 1-65536

     TIM_TimeBaseStructure.TIM_Prescaler = (scale - 1); // 1-65536, Master Clock Divisor

     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 1,2 or 4 for tDTS

     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

      /* PWM1 Mode configuration: Channel2 on PC.07 */

     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

     TIM_OCInitStructure.TIM_Pulse = width; // Pulse Width

     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

     TIM_OC2Init(TIM3, &TIM_OCInitStructure);

     TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

     TIM_ARRPreloadConfig(TIM3, ENABLE);

     /* TIM3 enable counter */

     TIM_Cmd(TIM3,ENABLE);

     // map PC6 as TIM2-CH2

     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6; //6

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // clock to 50MHz

     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;  // alternate function pull

     GPIO_Init(GPIOC, &GPIO_InitStructure);

     GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);

     //  24 MHz Master Clock

     scale = 24; // 24 MHz / 24 = 1 MHz

     period = 4545; // 1 MHZ / 4545 = 220 Hz

     width = period / 2;     //  ~50/50 duty

     // Time base configuration

     TIM_TimeBaseStructure.TIM_Period = (period - 1); // 1-65536

     TIM_TimeBaseStructure.TIM_Prescaler = (scale - 1); // 1-65536, Master Clock Divisor

     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 1,2 or 4 for tDTS

     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

     /* PWM1 Mode configuration: Channel2 on PC.06 */

     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

     TIM_OCInitStructure.TIM_Pulse = width; // Pulse Width

     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

     TIM_OC2Init(TIM2, &TIM_OCInitStructure);

     TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

     TIM_ARRPreloadConfig(TIM2, ENABLE);

     /* TIM2 enable counter */

     TIM_Cmd(TIM2,ENABLE);

     while (1) {}

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    pritz1
    Associate II
    September 30, 2011
    Posted on September 30, 2011 at 18:04

    Thank you very much.  I appreciate it.

    saudkhanis
    Associate II
    June 5, 2014
    Posted on June 05, 2014 at 17:57

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6Y5&d=%2Fa%2F0X0000000bqR%2FKSGp5OE3ZXhZUxxd.x4_4OuNf9f5HzJn1SW6CkWDsBE&asPdf=false