cancel
Showing results for 
Search instead for 
Did you mean: 

generating an interrupt for the loaded values in ARR

sanjib
Associate III
Posted on March 01, 2014 at 11:52

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);

    }

}

23 REPLIES 23
Posted on March 01, 2014 at 14:28

TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE); // PER RM0090 DMA1 STREAM1 CHANNEL 3

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
sanjib
Associate III
Posted on March 07, 2014 at 12:34

Thanks clive for your reply , but I am not able to try this as I blow up my stm board . I will try as soon I get my new board and I will let you know .

sanjib
Associate III
Posted on March 29, 2014 at 09:50

Hi clive

I got my board . and I tried but still the same . My system clk is 128 mhsz and timer 2 is 64 MHz so for different  ARR value like for 200 it should give 6.25 us 64000000/2*200 and for 300 9.3 us and so on I mean in Cn CRO different timing should apper when I masure rising edge and falling edge but it is giving 1.56 us for every rising and falling edge. What mistake I am doing. Please say
Posted on March 29, 2014 at 13:27

I don't have a scope to hand, will look over in a couple of days.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
sanjib
Associate III
Posted on April 02, 2014 at 07:07

HI

Thanks clive for your reply. the problem was I was not calling the DMA function. So now continious 1.56 us problem is solved but still there is a problem like for the arr value 50 it should show in the oscilloscope 1.56   us but it is showing 0.10 s and for 200 it is showing 0.40 sec why is it so? I tried separately I mean without calling the arr value through dma it`s fine but why the problem occurs when dma is called it`s there any latency problem or some other problem. how to solve this problem please help. I need to be done with DMA .

Thanks in Advance.  
Posted on April 02, 2014 at 21:10

There are a whole mess of issues with your code, and I don't think interrupting is the way to go. I output via a timer pin, and measure that.

// STM32 TIM2 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 }; // TIM2 32-bit
/**************************************************************************************/
void RCC_Configuration(void)
{
/* DMA1 (TIM2 on APB1) clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, 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 TIM2_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 TIM2 pin */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); // PA1 TIM2_CH2
}
/**************************************************************************************/
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Stream1);
DMA_InitStructure.DMA_Channel = DMA_Channel_3;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM2->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; // TIM2 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_Stream1, &DMA_InitStructure);
DMA_Cmd(DMA1_Stream1, ENABLE);
}
/**************************************************************************************/
void TIM2_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(TIM2, &TIM_InitStruct);
TIM_ARRPreloadConfig(TIM2, 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(TIM2, &TIM_OCInitStructure);
/* TIM2 Update Interrupt enable - for whatever purpose, likely to saturate */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* TIM2 Update DMA Request enable */
TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable TIM2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
STM_EVAL_LEDToggle(LED3);
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
STM_EVAL_LEDInit(LED3);
DMA_Configuration();
TIM2_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
/**************************************************************************************/

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
sanjib
Associate III
Posted on April 03, 2014 at 15:41

thanks clive you really rock I will try this code and let you know as now i am making my stm32f030 up . thanks a lot once again . you really helped me a lot many times

sanjib
Associate III
Posted on April 10, 2014 at 07:21

I have checked the pin through oscilloscope for 200 -1 it should show 6.25 us (160 khz) but it is giving 24 us why?

sanjib
Associate III
Posted on April 10, 2014 at 10:34

Sorry Clive it's done problem was in sys clk

Thank you