完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我需要用到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 ); } |
|
相关推荐
1个回答
|
|
根据您提供的问题描述,首先需要确认一下几点:
1. DMA传输数据到TIM1的TIMx_ARR寄存器时,是否已正确配置TIM1的时钟和定时器参数? 2. 电机的步进脉冲频率是否在合理范围内? 3. DMA传输的数据是否已正确加载到TIM1对应的寄存器中? 针对您的问题建议以下几点调试和优化: 1. 确保TIM1已正确配置为PWM模式,使其能够输出PWM波形。可以参考STM32F103的参考手册来进行参数配置。确保TIM1的时钟和分频系数设置正确,并配置适当的ARR和PSC寄存器值来以期望的频率和占空比来产生PWM信号。 2. 如果您希望通过改变TIMx_ARR寄存器的值来改变PWM的脉冲数,需要确保计数器以正确的频率自动重载。请注意,如果您希望在脉冲之间暂停一段时间来实现加减速功能,您需要在TIM1的ARR寄存器中预先计算并加载相应的值。例如,如果步进电机每个脉冲之间需要一段延时,则需要将ARR寄存器的值设置为适当的计数值和延时之和。 3. 在确认DMA传输数据已正确加载到TIM1对应的寄存器之前,您可以使用调试工具,如UART,将要传输的数据打印出来,以确保数据正确。 4. 您还可以通过示波器来检查实际PWM输出的脉冲个数和频率,判断问题可能出在哪里。可以检查DMA传输数据时TIM1的ARR寄存器的值是否正确,以及是否有额外的延时或误差导致脉冲频率降低。 综上所述,您可以根据这些调试和优化建议来尝试修改您的代码,并使用调试工具来帮助您找出问题所在。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1649 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1566 浏览 1 评论
994 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
694 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1613 浏览 2 评论
1874浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
660浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
528浏览 3评论
544浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
517浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 11:51 , Processed in 0.904598 second(s), Total 47, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号