我需要用到stm32f103+THB6128的方案驱动步进电机,只需控制脉冲就行,要实现多颗电机运动、加减速这两个功能,所以打算用DMA传输数据到TIM1的TIMx_ARR寄存器,数组元素个数即脉冲数,在keil的仿真下输出的脉冲个数和数组元素个数是一样的,但实际用示波器测得并不是,且用该种方式得到的脉冲频率很低,程序配置如下,应该怎么改呢 #include "dma_tim.h" #define TIM1_CCR1_Address ((uint32_t)0x40012C34) //TIM1通道1比较寄存器 #define TIM1_CCR2_Address ((uint32_t)0x40012C38) //TIM1通道2比较寄存器 #define TIM1_ARR_Address ((uint32_t)0x40012C2C) //TIM1自动装载寄存器 #define TIM1_DMAR_ADDRESS ((uint32_t)0x40012C4C) //uint16_t SRC_Buffer[7] = {50,50,50,50,50,50,0};//送到ARP或CCR寄存器的值,这里数组有7个元素,则输出7个占空比50/Period的脉冲 u16 ARR_Buffer[1000] = {0};//频率数组 单位Hz #define SIZE_MEASURE 50 //DMA通道元素个数 void TIM1_Configuration(void) { GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_Cmd(TIM1,DISABLE); //设置前先关闭定时器 //IO口定义 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); //PE11 TIM1_CH2 DMA1_CH3 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽模式 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOE,&GPIO_InitStruct); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //用重映射时必须打开AFIO时钟 GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);//TIM1完全重映射 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //开启TIM1的时钟 TIM1和TIM8在APB2总线上 最大工作72M TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //TIM_CKD_DIV1 = 0 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//设置为向上计数模式 TIM_TimeBaseInitStruct.TIM_Period = Period-1; //设置自动重装计数器值 填入值要减1 载入DMA模式也需要这条语句 TIM_TimeBaseInitStruct.TIM_Prescaler =Prescaler-1; //设置TIMx的预分频系数 填入值要减1 TIM_TimeBaseInit(TIM1 ,&TIM_TimeBaseInitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:脉冲宽度调制模式 TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OCInitStruct.TIM_Pulse = 50; //占空比 TIM_OC2Init(TIM1, &TIM_OCInitStruct); TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1,ENABLE); //允许在定时器工作时向ARR缓存器写入新值 TIM_Cmd(TIM1,ENABLE); TIM_CtrlPWMOutputs( TIM1, ENABLE ); /* Main Output Enable */ //允许CCR1 DMA请求 TIM_DMACmd(TIM1,TIM_DMA_CC2, ENABLE); //通道2占空比DMA允许 } void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure;//定义DMA初始化结构体 //DMA clock enable DMA时钟开启 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //DMA Channel2 DMA_DeInit(DMA1_Channel3);//复位DMA1通道3 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM1_ARR_Address;//定义DMA通道外设基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ARR_Buffer;//把measure_dma首址赋给DMA存储器基址; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = SIZE_MEASURE;//DMA_BUFFER_SIZE;//定义DMA缓冲区大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//当前外设寄存器地址不变 DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Enable;// DMA_MemoryInc_Disable;//当前存储器地址也不变化 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度16位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//定义存储器数据宽度16位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular;//DMA通道操作模式-位环形缓冲模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道优先级高 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//不允许DMA通道存储器到存储器传输 DMA_Init(DMA1_Channel3, &DMA_InitStructure);//初始化DMA通道3 //DMA Channel3 enable DMA_ClearFlag( DMA1_IT_TC3 ); DMA_ITConfig( DMA1_Channel3, DMA_IT_TC , ENABLE ); //使能DMA传输完成中断 半满和全满中断| DMA_IT_HT } void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx) { DMA_Cmd(DMA_CHx, DISABLE ); DMA_SetCurrDataCounter(DMA_CHx,SIZE_MEASURE);//DMA通道的DMA缓存的大小 DMA_Cmd(DMA_CHx, ENABLE); } void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2 ); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure ); } |
仿ç波形ï¼èå²ä¸ªæ°=50
调试了一早上现在可以以1K左右频率控制电机了,而且脉冲数可控,但是有个问题就是DMA传输完一次数据后,我再次调用MYDMA_Enable(DMA1_Channel3);函数,PWM的频率和个数会变得不正常,需要再次配置一次void TIM1_Configuration(void)才正常,不只为何 |
请问您解决了吗,我也遇到相同问题 |