2011-07-11 06:01 AM
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) {} }2011-07-11 08:07 AM
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) {} }2011-07-12 02:35 AM
2011-09-19 12:27 PM
Will this code also work for the STM32 Discovery board? What is TIM3-CH2?
2011-09-19 01:29 PM
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.2011-09-22 11:26 AM
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?2011-09-22 12:23 PM
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.
2011-09-27 02:21 PM
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) {}2011-09-27 06:32 PM
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 ticksu16 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) {}2011-09-30 09:04 AM
Thank you very much. I appreciate it.