cancel
Showing results for 
Search instead for 
Did you mean: 

How can create a tone with timer ?

antonius
Senior
Posted on February 05, 2014 at 03:04

Guys

How can create a tone with timer on STM32 ? This code is the way I made it on AVR, how can I mimic it on STM32 ?

timer1_ctc_init()
{
TCCR1A = 
// Mode 4 CTC 1:64 Prescaler
_BV(COM1A0); 
// set OC1A on compare match, clear them at top
//| _BV(COM1A1); // set OC1A on compare match, clear them at top
//TCCR1B |= _BV(CS11) | _BV(CS10) | _BV(WGM12);
TCCR1B |= _BV(CS11) | _BV(WGM12); 
//1:8 pre scaler
}
void
tone(
int
freq)
{
timer1_ctc_init();
OCR1A=freq;
}

thanks
19 REPLIES 19
antonius
Senior
Posted on February 10, 2014 at 03:14

It's working already,

but I use :

 NVIC_InitStructure.NVIC_IRQChannel = 25;

anyway, is there any built in _delay_ms() function ?

so I can conviniently call a delay for example _delay_ms(250) ?

thanks

Posted on February 10, 2014 at 04:49

You could use any free running timer, SysTick, or DWT_CYCCNT?

stm32vldiscovery_package\Project\Examples\SysTick\main.c
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on February 10, 2014 at 12:56 I tried to change the frequency to 5 kHz

1.
TIM1_Config(5000); 
// 5000 Hz

but, it's not changing, what should I configure to get 5 kHz? thanks
Posted on February 10, 2014 at 16:23

Ok, the OCInit needed some more attention, TIM1 is special.

// STM32VL-Discovery TIM1 16-bit PWM (PA.08 TIM1_CH1) - sourcer32@gmail.com
// TIM1CLK = 24000000 APB2=AHB/2 * 2
#include ''stm32F10x.h''
#include ''STM32vldiscovery.h''
//****************************************************************************
void RCC_Configuration(void)
{
// clock for GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// clock for TIM1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
}
//****************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // PA.08 TIM1_CH1
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//****************************************************************************
void TIM1_Configuration(uint32_t Freq)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Prescaler, Period;
// Roughly factor into 16-bit
Period = (SystemCoreClock / 1) / Freq;
Prescaler = (Period / 65536) + 1;
Period = (Period / Prescaler);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = Prescaler - 1;
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* Enable TIM1 Preload register on ARR */
TIM_ARRPreloadConfig(TIM1, ENABLE);
/* TIM PWM1 Mode configuration */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = Period / 2; // 50/50 duty
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
/* Output Compare PWM1 Mode configuration: Channel1 PA.08 */
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);
}
//****************************************************************************
void TIM1_UP_TIM16_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
/* LED3 toggling with frequency halved */
STM32vldiscovery_LEDToggle(LED3);
}
}
//****************************************************************************
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM1 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM16_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//****************************************************************************
int main(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
/* Initialize Leds mounted on STM32 VL-Discovery board */
STM32vldiscovery_LEDInit(LED3);
STM32vldiscovery_LEDInit(LED4);
/* Turn on LED3 and LED4 */
STM32vldiscovery_LEDOn(LED3);
STM32vldiscovery_LEDOn(LED4);
TIM1_Configuration(50); // 50 Hz, LED3 toggles at 25 Hz
while(1);
}
//****************************************************************************
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on February 11, 2014 at 00:49

my crystal is 8 MHz...does it matter for the timer clock setting ?

what should I change with these ones ?


/* TIM PWM1 Mode configuration */

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_Pulse = Period / 2; 
// 50/50 duty


TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;


TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;

TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;

TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

Posted on February 11, 2014 at 02:36

None of them....This is an up hill battle.

The TIMCLK is going to depend on your PLL/AHB/APB settings. Check what you have in your system_stm32f1xx.c file, and then refer to the Clock Tree diagram in the RM0008 Reference Manual.

Going to presume you're not running your STM32F107 at 8 MHz, I'd expect the SystemCoreClock to be 72000000, and the PLL set to get you to 72 MHz. If you're doing something else, then please describe.

The TIMCLK is divided down by the values prescribed in the Prescaler and Period values programmed into the timer.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on February 12, 2014 at 02:15 page 90 RM0008 ? which part should I focus ? thanks

1.
Period = (SystemCoreClock / 1) / Freq;
2.
3.
Prescaler = (Period / 65536) + 1;
4.
5.
Period = (Period / Prescaler);

Is my systemclock = 72MHz ? How can I set it as 72MHz, because my crystal = 8MHz ? Do I need to set PLLMul ? how ? 0690X00000602rBQAQ.jpg Thanks
Posted on February 12, 2014 at 04:16

To reiterate, for the clock setting being used you need to examine SYSTEM_STM32F1XX.C, the SystemInit() routine should be called by the start up code prior to your main() routine.

The PRESCALER and PERIOD are numbers that DIVIDE down the TIMCLK ie CLKOUT = TIMCLK / (PRESCALER * PERIOD) Where

TIM_TimeBaseStructure.TIM_Prescaler = PRESCALER - 1;
TIM_TimeBaseStructure.TIM_Period = PERIOD - 1;

In order to get a desired output frequency we have to FACTOR the numbers in a manner to achieve that.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
antonius
Senior
Posted on February 12, 2014 at 07:29

do you mean :


/**

* @brief Setup the microcontroller system

* Initialize the Embedded Flash Interface, the PLL and update the 

* SystemCoreClock variable.

* @note This function should be used only after reset.

* @param None

* @retval None

*/

void
SystemInit (
void
)

{

/* Reset the RCC clock configuration to the default reset state(for debug purpose) */

/* Set HSION bit */

RCC->CR |= (uint32_t)0x00000001;


/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */

#ifndef STM32F10X_CL

RCC->CFGR &= (uint32_t)0xF8FF0000;

#else

RCC->CFGR &= (uint32_t)0xF0FF0000;

#endif /* STM32F10X_CL */ 


/* Reset HSEON, CSSON and PLLON bits */

RCC->CR &= (uint32_t)0xFEF6FFFF;


/* Reset HSEBYP bit */

RCC->CR &= (uint32_t)0xFFFBFFFF;


/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */

RCC->CFGR &= (uint32_t)0xFF80FFFF;


#ifdef STM32F10X_CL

/* Reset PLL2ON and PLL3ON bits */

RCC->CR &= (uint32_t)0xEBFFFFFF;


/* Disable all interrupts and clear pending bits */

RCC->CIR = 0x00FF0000;


/* Reset CFGR2 register */

RCC->CFGR2 = 0x00000000;

#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)

/* Disable all interrupts and clear pending bits */

RCC->CIR = 0x009F0000;


/* Reset CFGR2 register */

RCC->CFGR2 = 0x00000000; 

#else

/* Disable all interrupts and clear pending bits */

RCC->CIR = 0x009F0000;

#endif /* STM32F10X_CL */


#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)

#ifdef DATA_IN_ExtSRAM

SystemInit_ExtMemCtl(); 

#endif /* DATA_IN_ExtSRAM */

#endif 


/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */

/* Configure the Flash Latency cycles and enable prefetch buffer */

SetSysClock();


#ifdef VECT_TAB_SRAM

SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; 
/* Vector Table Relocation in Internal SRAM. */

#else

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 
/* Vector Table Relocation in Internal FLASH. */

#endif 

}

antonius
Senior
Posted on February 12, 2014 at 07:31

on main :


int
main(
void
)

{

RCC_Config();


NVIC_Config();


GPIO_Config();


SystemInit();


/* TIM1 Configuration */

TIM1_Config(5000); 
// 50 Hz




while
(1)

{

}

}