yemingxp 发表于 2009-9-27 13:38:18

请教并讨论STM32的TIM控制步进电机的策略

参考ST官方的应用笔记,将TIM2初始化为TIM_OCMode_Toggle模式,而非直接输出PWM来控制电机;
而在其调速控制过程中,是通过修改ARR寄存器(#define   TIM2_ARR_Address    0x4000002C),也即是修改TIM_Period;
这跟PWM控制,修改Period有什么区别?
官方的应用笔记与原代码: http://www.stmicroelectronics.com.cn/stonline/mcu/STM32_AN.htm
附我现在的TIM代码:
#define SET_STEPMOTOR_ENA()GPIO_SetBits(GPIOE,GPIO_Pin_13)
#define CLR_STEPMOTOR_ENA()GPIO_ResetBits(GPIOE,GPIO_Pin_13)

void StepMotor_Configration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;

/* GPIOA Configuration:TIM2 Channel1 in Output */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

//PE12 ALMPE13 ENAPE14 DIR
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);

SET_STEPMOTOR_ENA();

/* ---------------------------------------------------------------
TIM2 Configuration: Output Compare Toggle Mode:
--------------------------------------------------------------- */
   /* Time base configuration */
TIM_TimeBaseStructure.TIM_Period =800;
TIM_TimeBaseStructure.TIM_Prescaler = 2;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

/* Output Compare Toggle Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);

TIM_ARRPreloadConfig(TIM2, ENABLE);

/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);   
}

yemingxp 发表于 2009-9-27 13:41:02

另外我在EDN看到southcreek网友的一段话,十分不明白其控制方法,为什么PWM要改变占空比,不是直接改变频率就行吗?望高人释惑:

"一般控制步进电机不要用PWM ,因为一般使用PWM,总是固定一个频率然后改变占空比。我的办法是使用定时器的输出比较功能。将需要的定时的一半写入一个输出比较定时器。将输出比较对应的通道设置为在达到匹配时切换输出电平。在产生输出比较时进入中断,清空定时器。然后设置下一步需要的频率。"

地址:http://group.ednchina.com/619/25416.aspx

qwerttt 发表于 2009-9-27 16:52:20

不知道EDN的southcreek兄用什么MCU控了

用PWM控制可以,我做过用430的PWM控制伺服电机,周期和占空比很容易改
现在研究STM32在固定的频率,输出任意个脉冲数(非定时器中断IO反转那种)

yemingxp 发表于 2009-9-27 17:38:11

回复qwerttt,上面的southcreek也是用的STM32;
另外我想用TIM的一个CHNNAEL输出固定频率的脉冲,再用另一个CHANNEL或者TIMER计数,就可以控制输出脉冲个数呢?或者还有更简单的方法?请大家赐教。

yemingxp 发表于 2009-9-29 08:28:14

讨论,上去

lxyppc 发表于 2009-9-29 09:20:59

我想到一个思路
用到了Timer Master Slave中的Gate模式
比如TIM1输出PWM, 频率为F
可以用TIM2通过Gate来控制TIM1的输出
将TIM2预频设为1/(F*2),则TIM2的Period 就是 脉冲个数*2 - 1

/*         1   2   3   4   5   6   7   8   9
             __    __    __    __    __    __    __    __    __         
            ||||||||||||||||||            
TIM1:    ___||__||__||__||__||__||__||__||__||____________________
          ->| Period1|<-
             1) 2) 3) 4) 5) 6) 7) 8) 9) 10)11)12)13)14)15)16)17)
             __________________________________________________
            |                                                |
TIM2:    ___|                                                |____________________
          ->||<--- Pres2 = Period1/2
            |<------------Period2 =N*2-1 = 17 ------------>|
*/

2nd090215 发表于 2009-9-29 11:13:08

关注,

yemingxp 发表于 2009-9-30 10:19:48

回复 lxyppc,
看到ST有相关的这种定时器链式应用,还在研究,有点生涩啊。。


/* Timers synchronisation in cascade mode ----------------------------
   1/TIM2 is configured as Master Timer:
   - PWM Mode is used
   - The TIM2 Update event is used as Trigger Output

   2/TIM3 is slave for TIM2 and Master for TIM4,
   - PWM Mode is used
   - The ITR1(TIM2) is used as input trigger
   - Gated mode is used, so start and stop of slave counter
      are controlled by the Master trigger output signal(TIM2 update event).
      - The TIM3 Update event is used as Trigger Output.

      3/TIM4 is slave for TIM3,
   - PWM Mode is used
   - The ITR2(TIM3) is used as input trigger
   - Gated mode is used, so start and stop of slave counter
      are controlled by the Master trigger output signal(TIM3 update event).

   The TIMxCLK is fixed to 72 MHz, the TIM2 counter clock is 72 MHz.

   The Master Timer TIM2 is running at TIM2 frequency :
   TIM2 frequency = (TIM2 counter clock)/ (TIM2 period + 1) = 281.250 KHz
   and the duty cycle = TIM2_CCR1/(TIM2_ARR + 1) = 25%.

   The TIM3 is running:
   - At (TIM2 frequency)/ (TIM3 period + 1) = 70.312 KHz and a duty cycle
   equal to TIM3_CCR1/(TIM3_ARR + 1) = 25%

   The TIM4 is running:
   - At (TIM3 frequency)/ (TIM4 period + 1) = 17.578 KHz and a duty cycle
   equal to TIM4_CCR1/(TIM4_ARR + 1) = 25%
-------------------------------------------------------------------- */

/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 255;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Period = 3;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Period = 3;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

/* Master Configuration in PWM1 Mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 64;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OC1Init(TIM2, &TIM_OCInitStructure);

/* Select the Master Slave Mode */
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

/* Master Mode selection */
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

/* Slaves Configuration: PWM1 Mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1;

TIM_OC1Init(TIM3, &TIM_OCInitStructure);

TIM_OC1Init(TIM4, &TIM_OCInitStructure);

/* Slave Mode selection: TIM3 */
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);

/* Select the Master Slave Mode */
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

/* Master Mode selection: TIM3 */
TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);

/* Slave Mode selection: TIM4 */
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);

/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_Cmd(TIM4, ENABLE);

yemingxp 发表于 2009-10-1 14:05:20

__STM32___推荐的方法是另用一个TIM定时控制以达到控制脉冲个数的目的,大家是怎样做?

http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3425424&bbs_page_no=1&search_mode=1&search_text=%C2%F6%B3%E5&bbs_id=3020

lxyppc 发表于 2009-10-1 16:50:56

那边的前提是频率很低,可以用中断的方式
我用的是Gate的方式

yemingxp 发表于 2009-10-2 15:40:33

回复lxyppc ,看到STM32的AN有这样的应用,也是GATE从模式,想请问你用的方法有用代码实现过吗?能很方便的控制TIMx输出脉冲个数吗?因为我还是对你的想法不太理解,望参考下代码,谢谢。
http://cache.amobbs.com/bbs_upload782111/files_19/ourdev_487854.JPG
(原文件名:01.JPG)

http://cache.amobbs.com/bbs_upload782111/files_19/ourdev_487855.JPG
(原文件名:02.JPG)

lxyppc 发表于 2009-10-5 18:56:45

好的
不过代码在公司,要放完假才能贴过来了

那个的代码的思路是MASTER用one pulse模式
门控slave,同时用master的另一路channel触发一个DMA,用来复位slave

楼主能描述一下你应用的需求吗?

yemingxp 发表于 2009-10-6 10:19:57

lxyppc 上午好,
我是想用TIM控制输入给步进驱动器的驱动脉冲个数,我现在用TIM2产生PWM波供驱动器,用TIM8检测电机光电编码盘的反馈脉冲,但是遇到些问题,所以想在源头,即输入脉冲上作控制,就比如,我想让电机走半圈,我就控制TIM输出500个PWM脉冲给驱动器。

TRINAMIC 发表于 2009-10-7 21:10:46

推荐使用TMC223这款芯片集成了控制功能+驱动功能+MOSFETS,加速度,减速度,位置,速度,细分全部集成在TMC223芯片内部.上位的MCU只需要调用其函数进行管理即可.
http://cache.amobbs.com/bbs_upload782111/files_19/ourdev_489165.gif
(原文件名:1.gif)

http://cache.amobbs.com/bbs_upload782111/files_19/ourdev_489166.gif
(原文件名:3.gif)

http://cache.amobbs.com/bbs_upload782111/files_19/ourdev_489167.gif
(原文件名:6.gif)
TMC223资料:
点击此处下载 ourdev_489168.pdf(文件大小:1.79M) (原文件名:TMC223_datasheet.pdf)
电路图:
点击此处下载 ourdev_489169.pdf(文件大小:86K) (原文件名:Eval222_Schematics.pdf)

TRINAMIC 发表于 2009-10-7 21:34:56

型号        性能
                         控制芯片
TMC211        1个步进控制+驱动芯片 LIN通讯
TMC222        1个步进控制+驱动芯片 IIC通讯
TMC223        1个步进控制+驱动芯片 IIC通讯 StallGuard功能
TMC428        3个电机控制芯片;SPI或step/dir控制信号
TMC454        位置闭环芯片,PID功能,ABN编码器输入,微步406,classic/SPI/SD
TMC457        位置闭环芯片,PID功能,ABN编码器输入,微步2048;classic/SPI/SD
TMC401        信号转化芯片 SPI---STEP/DIR;42细分
                   编码器信号处理芯片
TMC423        3路ABN编码器处理芯片
                      步进驱动芯片
TMC236        2相步进驱动芯片;1.5A;64细分;齐全的保护和诊断功能
TMC239        2相步进驱动芯片;MOSFETS外置;64细分;齐全的保护和诊断功能
TMC246        2相步进驱动芯片;1.5A;64细分;齐全的保护和诊断功能; 具有专利技术StallGuard技术
TMC249        2相步进驱动芯片;MOSFETS外置;64细分;齐全的保护和诊断功能;具有专利技术StallGuard技术
                                      3相步进驱动芯片
TMC332        适用2相或3相步进电机;自动高速;运动平稳;细分数2相256细分,3相171细分;S/D接口;ABN编码器输入
                   无传感器直流无刷驱动芯片
TMC603        3相BLDC;20A;12-50V;无需Hall换向
       
       
详细资料及参考电路        详细资料及参考电路
       
TMC211        http://www.trinamic.com/tmc/render.php?sess_pid=209
TMC222        http://www.trinamic.com/tmc/render.php?sess_pid=222
TMC223        http://www.trinamic.com/tmc/render.php?sess_pid=223
TMC428        http://www.trinamic.com/tmc/render.php?sess_pid=428
TMC454        http://www.trinamic.com/tmc/render.php?sess_pid=454
TMC457        http://www.trinamic.com/tmc/render.php?sess_pid=457
TMC401        http://www.trinamic.com/tmc/render.php?sess_pid=401
       
TMC423        http://www.trinamic.com/tmc/render.php?sess_pid=423
       
TMC236        http://www.trinamic.com/tmc/render.php?sess_pid=236
TMC239        http://www.trinamic.com/tmc/render.php?sess_pid=239
TMC246        http://www.trinamic.com/tmc/render.php?sess_pid=246
TMC249        http://www.trinamic.com/tmc/render.php?sess_pid=249
       
TMC332        http://www.trinamic.com/tmc/render.php?sess_pid=332
       
TMC603        http://www.trinamic.com/tmc/render.php?sess_pid=603

stm32_boy 发表于 2009-10-7 21:52:39

楼上的芯片太贵了
AVR也可以实现的但是前提是要用两个定时器资源

1个产生pulse
另外一个计数,比较中断中停止脉冲
比较寄存器的值就是脉冲个数

STM32不知到用一个定时器能不能实现,原本以为那个重复寄存器可以实现这个功能,看来是不行的。

yemingxp 发表于 2009-10-8 10:13:47

回复stm32_boy,
对的,其实要实现并不难,以前用ARM7作直接计PWM的中断就可以,但是STM32应该有更好的方法

zhenfanhei 发表于 2009-10-9 11:07:36

楼主,用定时器1.2.3.4中的一个做主定时器,另外用一个定时器工作在外部时钟模式下,直接对主定时器的PWM脉冲进行计数,在匹配中断产生后,通知CPU,即可控制任意脉冲数的输出。这个是想法,我实验一下看看,

shenhaojj 发表于 2009-10-9 19:40:19

要控制步进电机的步数、速度以及加减速最好使用AVR应用笔记446的算法,效果很好。我现在把同样的算法移植到STM32上,很爽,加减速很平滑,无抖动!

yemingxp 发表于 2009-10-10 08:28:42

多谢zhenfanhei;
多谢shenhaojj,去找来看看

qwerttt 发表于 2009-10-10 11:24:59

20楼提供的资料,要对电机有深入了解呀
还是配上驱动器控制比较方便

stm32_boy 发表于 2009-10-10 12:32:17

【19楼】 zhenfanhei
所说的就是我所说的

lxyppc 发表于 2009-10-12 18:49:03

终于来上班了,我试了一下,下面代码可以控制输出的脉冲数
软件:
IAR 4.42限制版
ST库    2.01
硬件:
万利199开发板 STM3210B-LK1
/*0001*//* Includes ------------------------------------------------------------------*/
/*0002*/#include "stm32f10x_lib.h"
/*0003*/
/*0004*//* Private typedef -----------------------------------------------------------*/
/*0005*//* Private define ------------------------------------------------------------*/
/*0006*//* Private macro -------------------------------------------------------------*/
/*0007*//* Private variables ---------------------------------------------------------*/
/*0008*/ErrorStatus HSEStartUpStatus;
/*0009*/
/*0010*//* Private function prototypes -----------------------------------------------*/
/*0011*/voidRCC_Configuration(void);
/*0012*/voidNVIC_Configuration(void);
/*0013*//* Private functions ---------------------------------------------------------*/
/*0014*/
/*0015*/#define   PWM_Period      120
/*0016*/int main(void)
/*0017*/{
/*0018*/u16       waveNumber = 10;
/*0019*//* System Clocks Configuration */
/*0020*/RCC_Configuration();
/*0021*/
/*0022*//* Enable related peripheral clocks */
/*0023*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*0024*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/*0025*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
/*0026*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
/*0027*/
/*0028*//* Config IO for related timers */
/*0029*/{
/*0030*/    GPIO_InitTypeDef GPIO_InitStructure;
/*0031*/    /* Timer1 Channel 2, PA9 */
/*0032*/    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;
/*0033*/    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
/*0034*/    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*0035*/    GPIO_Init(GPIOA, &GPIO_InitStructure);
/*0036*/    /* Timer3 Channel 4, PB1*/
/*0037*/    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
/*0038*/    GPIO_Init(GPIOB, &GPIO_InitStructure);
/*0039*/}
/*0040*//* Setup Timer3 channel 4, Timer3 is master timer
<font color=#646400>|*0041*|   This timer is used to control the waveform count of timer1 */</font>
/*0042*/{
/*0043*/    TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
/*0044*/    TIM_OCInitTypeDefTIM_OCInitStructure;
/*0045*/    TIM_DeInit(TIM3);
/*0046*/    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
/*0047*/    TIM_OCStructInit(&TIM_OCInitStructure);
/*0048*/    TIM_TimeBaseStructure.TIM_Prescaler = PWM_Period/2 - 1;
/*0049*/    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
/*0050*/    TIM_TimeBaseStructure.TIM_Period = waveNumber*2;
/*0051*/    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
/*0052*/    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
/*0053*/   
/*0054*/    /* Timer2 Channel 3 Configuration in PWM2 mode, this is used for enable Recive clcok */
/*0055*/    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
/*0056*/    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
/*0057*/    TIM_OCInitStructure.TIM_Pulse = waveNumber*2 - 1;
/*0058*/    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/*0059*/    TIM_OC4Init(TIM3,&TIM_OCInitStructure);
/*0060*/    TIM_CtrlPWMOutputs(TIM3, ENABLE);
/*0061*/    TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Single);
/*0062*/}
/*0063*//* Setup timer1 channel 2, Timer1 is slave timer
<font color=#646400>|*0064*|   This timer is used to output waveforms */</font>
/*0065*/{
/*0066*/    TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
/*0067*/    TIM_OCInitTypeDefTIM_OCInitStructure;
/*0068*/    TIM_DeInit(TIM1);
/*0069*/    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
/*0070*/    TIM_OCStructInit(&TIM_OCInitStructure);
/*0071*/    TIM_TimeBaseStructure.TIM_Prescaler = 0;
/*0072*/    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
/*0073*/    TIM_TimeBaseStructure.TIM_Period = PWM_Period;
/*0074*/    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
/*0075*/    TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
/*0076*/   
/*0077*/    /* Timer2 Channel 3 Configuration in PWM2 mode, this is used for enable Recive clcok */
/*0078*/    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
/*0079*/    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
/*0080*/    TIM_OCInitStructure.TIM_Pulse = PWM_Period/2;
/*0081*/    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/*0082*/    TIM_OC2Init(TIM1,&TIM_OCInitStructure);
/*0083*/    TIM_CtrlPWMOutputs(TIM1, ENABLE);
/*0084*/}
/*0085*//* Create relationship between timer1 and timer3, timer3 is master, timer1 is slave
<font color=#646400>|*0086*|    timer1 is work under gate control mode, and controled by timer3
|*0087*|    timer3's channel 4 is used as the control signal
|*0088*|   */</font>
/*0089*/    /* Enable timer's master/slave work mode */
/*0090*/    TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);
/*0091*/    TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
/*0092*/    /* timer3's channel 4 is used as the control signal */
/*0093*/    TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_OC4Ref );
/*0094*/    /* Check the master/slave is valid or not */
/*0095*/    compile_assert((u16)GetInternalTrigger(TIM1,TIM3) != (u16)-1);
/*0096*/    /* Config timer1's external clock */
/*0097*/    TIM_ITRxExternalClockConfig(TIM1, GetInternalTrigger(TIM1,TIM3));
/*0098*/    TIM_SelectSlaveMode(TIM1,TIM_SlaveMode_Gated);
/*0099*/   
/*0100*//* Enable the slave tiemr*/
/*0101*/TIM_Cmd(TIM1,ENABLE);
/*0102*///SetupAlltimers();
/*0103*/while(1){
/*0104*/    /* Check whether the previous action is done or not */
/*0105*/    if(!(TIM3->CR1 & 1)){
/*0106*/      TIM1->CNT = 0; /* It would be very perfect if gate mode can
<font color=#646400>|*0107*|                        reset the slave timer automatically */</font>
/*0108*/      TIM3->ARR = waveNumber*2;/* Reload wave number*/
/*0109*/      TIM3->CCR4 = waveNumber*2 - 1;
/*0110*/      TIM3->CR1|=1; /* Re-enable the timer */
/*0111*/      /* update waveform number */
/*0112*/      waveNumber++;
/*0113*/      if(waveNumber == 13){
/*0114*/      waveNumber = 10;
/*0115*/      }
/*0116*/    }
/*0117*/}
/*0118*/}
/*0119*/
/*0120*//*******************************************************************************
<font color=#646400>|*0121*|* Function Name: RCC_Configuration
|*0122*|* Description    : Configures the different system clocks.
|*0123*|* Input          : None
|*0124*|* Output         : None
|*0125*|* Return         : None
|*0126*|*******************************************************************************/</font>
/*0127*/void RCC_Configuration(void)
/*0128*/{
/*0129*//* RCC system reset(for debug purpose) */
/*0130*/RCC_DeInit();
/*0131*/
/*0132*//* Enable HSE */
/*0133*/RCC_HSEConfig(RCC_HSE_ON);
/*0134*/
/*0135*//* Wait till HSE is ready */
/*0136*/HSEStartUpStatus = RCC_WaitForHSEStartUp();
/*0137*/
/*0138*/if(HSEStartUpStatus == SUCCESS)
/*0139*/{
/*0140*/    /* Enable Prefetch Buffer */
/*0141*/    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/*0142*/
/*0143*/    /* Flash 2 wait state */
/*0144*/    FLASH_SetLatency(FLASH_Latency_2);
/*0145*/
/*0146*/    /* HCLK = SYSCLK */
/*0147*/    RCC_HCLKConfig(RCC_SYSCLK_Div1);
/*0148*/
/*0149*/    /* PCLK2 = HCLK */
/*0150*/    RCC_PCLK2Config(RCC_HCLK_Div1);
/*0151*/
/*0152*/    /* PCLK1 = HCLK/2 */
/*0153*/    RCC_PCLK1Config(RCC_HCLK_Div2);
/*0154*/
/*0155*/    /* PLLCLK = 8MHz * 9 = 72 MHz */
/*0156*/    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/*0157*/
/*0158*/    /* Enable PLL */
/*0159*/    RCC_PLLCmd(ENABLE);
/*0160*/
/*0161*/    /* Wait till PLL is ready */
/*0162*/    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
/*0163*/    {
/*0164*/    }
/*0165*/
/*0166*/    /* Select PLL as system clock source */
/*0167*/    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/*0168*/
/*0169*/    /* Wait till PLL is used as system clock source */
/*0170*/    while(RCC_GetSYSCLKSource() != 0x08)
/*0171*/    {
/*0172*/    }
/*0173*/}
/*0174*/}

输出波形如下图
http://cache.amobbs.com/bbs_upload782111/files_20/ourdev_490837.jpg
(原文件名:TEK0000.jpg)

yemingxp 发表于 2009-10-13 08:29:34

感谢lxyppc,我现在直接用PWM更新中断计的脉冲个数,最笨,最耗资源的办法,过后就实验您的代码方法,谢谢。

有点疑问,为什么主程序里面每次都要重新更新TIM3的参数呢?
TIM1->CNT = 0; /* It would be very perfect if gate mode can
|*0107*|                        reset the slave timer automatically */
/*0108*/      TIM3->ARR = waveNumber*2;/* Reload wave number*/
/*0109*/      TIM3->CCR4 = waveNumber*2 - 1;
/*0110*/      TIM3->CR1|=1; /* Re-enable the timer */

lxyppc 发表于 2009-10-13 09:26:02

更新TIM3是为了让每次间隔后输出的脉冲的个数不一样(如示波器看到的那样),如果不改变输出脉冲的个数,就不用更新TIM3的参数

zooky 发表于 2009-12-25 21:31:27

MARK

ysyin 发表于 2009-12-25 22:42:51

有点兴趣

bluelool 发表于 2009-12-26 14:52:11

mark

rube 发表于 2010-1-5 11:11:56

收藏

lofeng 发表于 2010-1-5 12:13:32

mark

lofeng 发表于 2010-1-7 18:11:13

学习

hbzx 发表于 2010-6-28 17:22:52

mark

langley 发表于 2010-6-28 19:35:34

我目前正在做一个东西,用stm32给电机发脉冲,电机要求可定位,可调速,有编码器反馈,完成这东西最少要用几个定时器呢?

xukai871105 发表于 2010-7-5 16:15:35

学习了啊,AVR的资料也看了一下
以前看STM32的时候不知道这个主从模式应该如何使用,现在又点感觉了

有时间的话可以试一下啊

EILIANHELL 发表于 2010-7-30 23:58:01

mark

zjj2010 发表于 2010-8-4 21:28:29

mark

googse 发表于 2010-8-4 23:03:24

这个资料好,标记

sjgsjg 发表于 2010-11-11 10:34:38

回复【20楼】shenhaojj
要控制步进电机的步数、速度以及加减速最好使用avr应用笔记446的算法,效果很好。我现在把同样的算法移植到stm32上,很爽,加减速很平滑,无抖动!
-----------------------------------------------------------------------

你说的avr应用笔记446的算法在哪里有,能否共享你移植到stm32上的代码?

zhou_1989 发表于 2010-11-13 23:08:27

mark

tongyf 发表于 2010-11-18 16:21:43

同样关注加减速控制问题

holmesruan 发表于 2011-5-6 16:33:11

MARK

wso75839840 发表于 2011-6-13 11:57:17

mark

代码中的compile_assert见
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3551560&bbs_page_no=73&bbs_id=3020

xl071310 发表于 2011-6-13 12:51:15

写的不错

hong_hong789 发表于 2011-9-3 11:47:11

仔细研究

daicp 发表于 2011-9-12 23:54:16

回复【24楼】lxyppc
-----------------------------------------------------------------------

回复【24楼】lxyppc
终于来上班了,我试了一下,下面代码可以控制输出的脉冲数
软件:
iar 4.42限制版
st库    2.01
硬件:
万利199开发板 stm3210b-lk1
/*0001*//* includes ------------------------------------------------------------------*/
/*0002*/#include "stm32f10x_lib.h"
/*0003*/
<font co......
-----------------------------------------------------------------------

请教if(!(TIM3->CR1 & 1)) 这个位清0是否有中断产生呢?可否用中断方式处理?

daicp 发表于 2011-9-13 03:35:46

TIM1总是有脉冲啊

wers_l 发表于 2011-9-13 09:54:23

MARK

wers_l 发表于 2011-9-22 13:32:40

mark

lihe 发表于 2011-10-10 14:22:52

mark

jiang47 发表于 2011-10-11 11:13:03

mark

henry 发表于 2011-10-11 12:58:43

mark

sillyboyhe 发表于 2011-10-18 19:21:35

mark

denglu 发表于 2011-11-8 07:11:07

Mark

LOVEDOVE 发表于 2012-4-13 10:49:15

谢谢楼主奉献

fall556 发表于 2012-7-3 09:51:50

没看懂lxyppc的程序,注释中的TIM2是做什么用的啊

youxp 发表于 2012-7-10 11:19:37

看到如此好贴,不得不赶快注册一个然后回复。

gongcheng111 发表于 2012-7-26 08:59:02

谢谢分享

geiter001 发表于 2012-8-5 23:36:04

这个帖子里面的东西技术含量高啊,要看,要好好看,呵呵,非常感谢LZ及坛友!

sk_2006_ren 发表于 2012-9-4 11:34:42

好资料,正在找这样的资料

champtech 发表于 2013-1-21 09:46:26

好帖子,讲得不错

lovelywwei 发表于 2014-5-27 09:31:38

好帖。收藏细看。

daienming 发表于 2014-7-2 22:57:10

正在找相关的资料,回头研究一下ls提供的方法。

磊磊映画 发表于 2014-7-20 21:41:45

daicp 发表于 2011-9-12 23:54
回复【24楼】lxyppc
-----------------------------------------------------------------------



放在主程序里面,在执行的的时候就要把这个判断保护起来,套到while(1)中,完成后再跳出来,不这样的话很有可能错过这个条件的发生啊,不知道用中断怎么做呢

wsh 发表于 2015-3-11 22:43:22

下载了先,明天再看{:victory:}

奇美亚 发表于 2015-4-28 14:19:42

好帖。收藏细看。

w12315 发表于 2015-8-6 21:44:16

mark{:lol:}

f_14@163.com 发表于 2015-11-25 09:52:44

Nice,正在参考这个帖子做 3轴联动

eagle_avr 发表于 2018-6-11 15:16:24

STM32对步进电机的控制,并没有PIC做的好。这个方法很好,学习了!

xxlin 发表于 2020-11-7 17:26:15

在看用DMA+脉冲反转调速,希望能有帮助
页: [1]
查看完整版本: 请教并讨论STM32的TIM控制步进电机的策略