cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 Stpper Motor (PWM +DMA)

matthias23
Associate II
Posted on January 20, 2014 at 16:12

Hieverybody,

I have aquestion regarding a stepper controller firmware provided by ST. Actually I do not get the DMA run on my STM32F107!

The capturecontrol toggle mode is working, but no other values are loaded in the ARR byDMA and the DMA1_Channel1_IRQHandler is never called.

I triedanother timer-channel with the corresponding DMA channel, but got the sameresult. Where is my error? I’m happy about every suggestion.

void Stepper_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* TIM2 clock enable */
RCC_APB
1
PeriphClockCmd(RCC_APB
1
Periph_TIM
4
, ENABLE);
/* GPIOA clock enable */
RCC_APB
2
PeriphClockCmd(RCC_APB
2
Periph_GPIOA, ENABLE);
/* GPIOC clock enable */
RCC_APB
2
PeriphClockCmd(RCC_APB
2
Periph_GPIOC, ENABLE);
/* GPIOB clock enable */
RCC_APB
2
PeriphClockCmd(RCC_APB
2
Periph_GPIOB, ENABLE);
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA
1
, ENABLE);
RCC_AHBPeriphClockCmd(RCC_APB
2
Periph_AFIO, ENABLE);
/* GPIOB Configuration:TIM4 Channel1 in Output */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_
6
;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
/*AF Alternate Function*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_
50
MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* ---------------------------------------------------------------
NVIC Cofig
--------------------------------------------------------------- */
/*
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
*/
NVIC_SetPriorityGrouping(
7
); 
/* 0 bits for pre-emption priority 4 bits for subpriority*/
NVIC_SetPriority(DMA
1
_Channel
1
_IRQn, 
0
x
01
); 
/* 0x01 = 0x0 << 3 | (0x1 & 0x7), prority is 0x01 << 4 */
NVIC_EnableIRQ(DMA
1
_Channel
1
_IRQn);
/* ---------------------------------------------------------------
TIM2 Configuration: Output Compare Toggle Mode:
--------------------------------------------------------------- */
TIM_DeInit( TIM
4
);
/* Time base configuration */
TIM_TimeBaseStructInit( &TIM_TimeBaseStructure );
TIM_TimeBaseStructure.TIM_Period =
60000
;
TIM_TimeBaseStructure.TIM_Prescaler = 
3
; //(Durch 
4
Teilen)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV
1
;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM
4
, &TIM_TimeBaseStructure);
//TIM_ITConfig(TIM
4
, TIM_IT_CC
1
, ENABLE);
/* Output Compare Toggle Mode configuration: Channel4 */
TIM_OCStructInit( &TIM_OCInitStructure );
TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_Pulse = 
0
; //When a match is found between the capture/compare register and the 
counter
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC
1
Init(TIM
4
, &TIM_OCInitStructure);
TIM_ARRPreloadConfig(TIM
4
, ENABLE);
/* TIM enable counter */
TIM_Cmd(TIM
4
, ENABLE);
/* -------------------------------------------------------------------
DMA1 configuration 
---------------------------------------------------------------------- */
/* DMA1 channel1 configuration ----------------------------------*/
DMA_DeInit(DMA
1
_Channel
1
);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint
32
_t)(&TIM
4
->ARR); //(uint
32
_t)TIM
2
_BASE + 
0
x
2
C; //(uint
32
_t)TIM
2
_ARR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint
32
_t)SRC_Buffer_INC;//
536870952
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = BufferSize;
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_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M
2
M = DMA_M
2
M_Disable;
DMA_Init(DMA
1
_Channel
1
, &DMA_InitStructure);
/* Enable DMA1 Channel1 Transfer Complete interrupt */
DMA_ITConfig(DMA
1
_Channel
1
, DMA_IT_TC, ENABLE);
/* Enable DMA1 Channel1 */
DMA_Cmd(DMA
1
_Channel
1
, ENABLE);
/* Enable TIM4 DMA update request */
TIM_DMACmd(TIM
4
,TIM_DMA_Update, ENABLE);
}

#stm32f107-stpper-pwm-dma
5 REPLIES 5
Posted on January 20, 2014 at 16:25

Unfortunately there is a lot of surrounding code missing, so this is overly difficult to compile and test.

TIM_DMACmd(TIM
4
,TIM_DMA_Update, ENABLE);

One suspects this would be DMA1_Channel7 (TIM4_UP), decide if you want to do this on the Update or CC1
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
matthias23
Associate II
Posted on January 20, 2014 at 16:41

Hi,
with this code it should be possible to debug
/* Private typedef -------------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* Private define --------------------------------------------------------------*/
/* Private macro ---------------------------------------------------------------*/
/* Private variables -----------------------------------------------------------*/
uint16_t SRC_Buffer_DEC[20] ={15000,15000,20000,20000,25000,25000,30000,30000,35000,35000,
40000,40000,45000,45000,50000,50000,55000,55000,60000,60000};
uint16_t SRC_Buffer_INC[20] ={60000,60000,55000,55000,50000,50000,45000,45000,40000,40000,
35000,35000,30000,30000,25000,25000,20000,20000,15000,15000};

Main:

/* Private typedef -----------------------------------------------------------*/
#define SystemFrequency 72000000
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ErrorStatus HSEStartUpStatus;
RCC_ClocksTypeDef RCC_Clocks;
FlagStatus acceleration = RESET;
uint16_t Soll_TogVal;
uint16_t rpm = 10;
uint16_t MSTEP = 1600;
uint32_t test;
/* Private function prototypes -----------------------------------------------*/
void
RCC_Configuration(
void
);
void
NVIC_Configuration(
void
);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval : None
*/
int
main(
void
)
{
// Setzt die Systemclock auf 72MHz besser als RCC_Config, da diese nicht für ConectivityLine ist.
SystemInit();
/* Activate the driver */
//Set_PeriphClock(ENABLE);
/* Peripherals configuration */
Stepper_Init();
while
(1)
{
}
}
void
SysTick_Handler(
void
)
{
USART2_Snd_Str(
''SysTick_Handler

''
);
/* Change the DMA_MemoryBaseAddr to the decrement buffer */
DMA1_Channel7->CMAR = (uint32_t)SRC_Buffer_DEC;
/* Define the DMA_BufferSize */
DMA1_Channel7->CNDTR = BufferSize;
/* Enable DMA1 Channel2 */
DMA1_Channel7->CCR |= ((uint32_t)0x00000001);
/* Enable TIM2 DMA request */
TIM2->DIER |= TIM_DMA_Update;
/* Disable SysTick Counter */
SysTick->CTRL &= 0xFFFFFFFE;
/* Clear SysTick Counter */
SysTick->VAL = ((uint32_t)0x00000000);
acceleration = SET;
}
void
DMA1_Channel1_IRQHandler(
void
)
{
USART2_Snd_Str(
''DMA1_Channel7_IRQ

''
);
/* Disable TIM2 DMA */
TIM2->DIER &= ~TIM_DMA_Update;
/* Disable DMA Channel2 request */
DMA1_Channel7->CCR &= ((uint32_t)0xFFFFFFFE);
if
(acceleration == SET)
{
/* Change the DMA_MemoryBaseAddr to the decrement buffer */
DMA1_Channel7->CMAR =(uint32_t)SRC_Buffer_INC;
/* Define the DMA_BufferSize */
DMA1_Channel7->CNDTR = BufferSize;
/* Enable DMA Channel2 */
DMA1_Channel7->CCR |= ((uint32_t)0x00000001);
/* Enable TIM2 DMA request */
TIM2->DIER |= TIM_DMA_Update;
acceleration = RESET;
}
else
{
/* SysTick end of count event each 8ms */
/* Setup SysTick Timer for 1 msec interrupts */
if
(SysTick_Config(SystemFrequency / 8000)) 
/* SystemFrequency is defined in
“system_stm32f10x.h�? and equal to HCLK frequency */
{
/* Capture error */
while
(1);
}
acceleration = SET;
}
/* Clear DMA1 Channel2 Transfer Complete pending bit */
DMA1->IFCR = DMA1_FLAG_TC7;
}
#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) */
while
(1)
{
} 
}
#endif

matthias23
Associate II
Posted on January 20, 2014 at 16:48

Here is the link to the firmware provided by st.

http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/PF257854

I also want to use the ARR Register. But as mentioned, I do not get the DMA working :(

matthias23
Associate II
Posted on January 20, 2014 at 17:18

WTF! Now I understand what you wanted to say! Of course! TIM4_UP thanks a lot!

Marcin Wionczyk
Associate
Posted on June 30, 2018 at 14:05

I didn't tried that yet, but I believe it is worth trying:

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint

32

_t)(&TIM

4

->CCR1); // for channel1

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32

_t)(&TIM

4

->CCR2); // for channel2

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32

_t)(&TIM

4

->CCR3); // for channel3

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32

_t)(&TIM

4

->CCR4); // for channel4