cancel
Showing results for 
Search instead for 
Did you mean: 

Creating a square wave

thomaspfeffer9
Associate II
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) {}

}

14 REPLIES 14
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
Up vote any posts that you find helpful, it shows what's working..
thomaspfeffer9
Associate II
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
Posted on September 19, 2011 at 21:27

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

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
Up vote any posts that you find helpful, it shows what's working..
pritz1
Associate II
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?

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
Up vote any posts that you find helpful, it shows what's working..
pritz1
Associate II
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) {}

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
Up vote any posts that you find helpful, it shows what's working..
pritz1
Associate II
Posted on September 30, 2011 at 18:04

Thank you very much.  I appreciate it.