2014-03-01 02:52 AM
Hi,
I want to generate a timer interrupt for 6.25 us, 9.375 us, 0.1 milisec, 0.4 millisecond and so on . I think that it can be done by using DMA taking the array SRC_Buffer_DEC[4] ={200,300,3200,12800} as DMA memory base address and ADC1->ARR as peripheral address therefore the Auto reload value should change everytime and should generate an interrupt for each value. but I am not able to do that . I didn't get any example for this but I think that it can be done. Can anybody help me and say me whether my thinking is right or wrong. whether it is achieveable, if no how it can be done? I have paste my code below please see #include ''unistd.h'' #include ''stm32f4xx.h'' #include ''stm32f4_discovery.h'' #include ''stm32f4xx_tim.h'' #include ''stm32f4xx_rcc.h'' #include ''stm32f4xx.h'' #include <misc.h> #include ''stm32f4xx_adc.h'' #include ''stm32f4xx_gpio.h'' #include ''stm32f4xx_dac.h'' #include ''stm32f4xx_tim.h'' #include ''stm32f4xx_dma.h'' #include ''stm32f4xx_usart.h'' #include ''time.h'' uint16_t SRC_Buffer_DEC[4] ={200,300,3200,12800}; int main(void) { STM_EVAL_LEDInit(LED3); rcc(); INTTIM_Config(); NVIC_Configuration(); EnableTimerInterrupt(); while(1); DMA(); #ifdef DEBUG debug(); #endif } void rcc() { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); /** * Enable clock for DMA2 (ADC DMA) **/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); /** * Enable clock for TIM2 (used for ADC Trigger) **/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); } #if 1 void DMA() { DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_Channel = DMA_Channel_6; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM2->ARR; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&SRC_Buffer_DEC; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = 4; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream4, &DMA_InitStructure); // DMA_ITConfig(DMA2_Stream4, DMA_IT_TC | DMA_IT_HT, ENABLE); DMA_Cmd(DMA2_Stream4, ENABLE); /* TIM8 Update DMA Request enable */ TIM_DMACmd(TIM2, TIM_DMA_Trigger , ENABLE); TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE); } #endif void INTTIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_OCInitTypeDef TIM_OCInitStructure; /* TIM2 clock enable */ /* Time base configuration */ TIM_InitStruct.TIM_Prescaler = 2 - 1; // This will configure the clock to 2 kHz TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; // Count-up timer mode // TIM_InitStruct.TIM_Period = 200 - 1; // 2 kHz down to 1 Hz = 1 second TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // Divide clock by 1 TIM_InitStruct.TIM_RepetitionCounter = 0; // Set to 0, not used TIM_TimeBaseInit(TIM2, &TIM_InitStruct); TIM_ARRPreloadConfig(TIM2, ENABLE); /* TIM8 enable counter */ TIM_Cmd(TIM2, ENABLE); /* TIM2 enable counter */ TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); } void EnableTimerInterrupt() { NVIC_InitTypeDef nvicStructure; nvicStructure.NVIC_IRQChannel = TIM2_IRQn; nvicStructure.NVIC_IRQChannelPreemptionPriority = 0; nvicStructure.NVIC_IRQChannelSubPriority = 0; nvicStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvicStructure); } void TIM2_IRQHandler() { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); STM_EVAL_LEDToggle(LED3); } }2014-04-30 07:03 AM
I didn't get what this implies ........'' void TIM3_IRQHandler(void) ??''
TIM3 is working rather than this other general purpose timer is not able to generate interrupt..2014-04-30 07:07 AM
But it's not going to work for TIM15, is it?
void TIM3_IRQHandler(void) // <----- Really?
{
static int i = 0;
if (TIM_GetITStatus(TIM15, TIM_IT_Update) != RESET)
{
if (i == 0)
{
GPIO_SetBits(GPIOC, (GPIO_Pin_8 | GPIO_Pin_9));
i = 1;
}
else
{
GPIO_ResetBits(GPIOC, (GPIO_Pin_8 | GPIO_Pin_9));
i = 0;
}
TIM_ClearITPendingBit(TIM15, TIM_IT_Update);
}
}
2014-05-01 09:59 PM
Oh so sorry , really I totally ignore this ...thanks clive once again
2014-06-07 06:16 AM
I'm not going to respond in off topic threads. Your problem with TIM5 seems to be an inability/desire to read the Reference Manual and tailor your code appropriately.
// STM32 TIM5 PWM DMA STM32F4 @ 128 MHz - Scope PA1 - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
#define SAMPLES 4
uint32_t SampleVector[SAMPLES] = { 200, 300, 3200, 12800 }; // TIM5 32-bit
/**************************************************************************************/
void RCC_Configuration(void)
{
/* DMA1 (TIM5 on APB1) clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
/* TIM5 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // PA1 TIM5_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect TIM5 pin */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM5); // PA1 TIM5_CH2
}
/**************************************************************************************/
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
// Per RM0090 TIM5_CH2 is DMA1, Channel 6, Stream 4
DMA_DeInit(DMA1_Stream4);
DMA_InitStructure.DMA_Channel = DMA_Channel_6;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM5->ARR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&SampleVector[0];
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = SAMPLES;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; // TIM5 is 32-bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream4, &DMA_InitStructure);
DMA_Cmd(DMA1_Stream4, ENABLE);
}
/**************************************************************************************/
void TIM5_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_InitStruct;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Time base configuration */
TIM_InitStruct.TIM_Prescaler = 2 - 1; // This will configure the clock to 32 MHz
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; // Count-up timer mode
TIM_InitStruct.TIM_Period = 200 - 1; // 160 KHz initially
TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // Divide clock by 1
TIM_InitStruct.TIM_RepetitionCounter = 0; // Set to 0, not used
TIM_TimeBaseInit(TIM5, &TIM_InitStruct);
TIM_ARRPreloadConfig(TIM5, ENABLE);
/* Output Compare Toggle Mode configuration: Channel2 - so we can actually measure widths */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; // 80 KHz
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = 1;
TIM_OC2Init(TIM5, &TIM_OCInitStructure);
/* TIM5 Update Interrupt enable - for whatever purpose, likely to saturate */
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);
/* TIM5 Update DMA Request enable */
TIM_DMACmd(TIM5, TIM_DMA_Update, ENABLE);
/* TIM5 enable counter */
TIM_Cmd(TIM5, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable TIM5 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void TIM5_IRQHandler(void)
{
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM5, TIM_IT_Update);
STM_EVAL_LEDToggle(LED3);
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
STM_EVAL_LEDInit(LED3);
DMA_Configuration();
TIM5_Configuration();
while(1); // Don't want to exit
}
/**************************************************************************************/
#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