牛卧堂MCU技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

开启左侧

直流无刷电机控制Mini5D代码——成熟的代码可节省研发时间

[复制链接]
 楼主| Angus 发表于 2016-10-26 16:16:40 | 显示全部楼层
冰破 发表于 2016-10-26 15:03
PWM024_0_MOS_On() ;                 // PWM024 输出低时 MOS 导通,调用此函数让输出反相     
  PWM135_ ...

若不调用这两个函数,数组数据对应:PWM024输出高,上 MOS 导通。PWM135输出低,下 MOS 导通。
回复 支持 反对

使用道具 举报

冰破 发表于 2016-10-26 16:55:32 | 显示全部楼层
本帖最后由 冰破 于 2016-10-26 18:56 编辑

本楼预留,原问题已经看懂了
回复 支持 反对

使用道具 举报

冰破 发表于 2016-10-27 09:21:52 | 显示全部楼层
计算周期的时候,定时器计到了最大值,然后从0再开始,这时读出来的TIMER1->DR会比上一次的值小,这时候计算周期的公式还是正确的吗?

例如 上一次的值ZeroTick为0xFFFF00, 到了这次过零,TIMER1->DR已经从最小重新开始数了,变成了0x0000FF, 那下面计算还能得到正确的周期值吗?

PeriodLast = (TIMER1->DR - ZeroTick) & 0xFFFFFF ;
回复 支持 反对

使用道具 举报

 楼主| Angus 发表于 2016-10-27 09:34:16 | 显示全部楼层
冰破 发表于 2016-10-27 09:21
计算周期的时候,定时器计到了最大值,然后从0再开始,这时读出来的TIMER1->DR会比上一次的值小,这时候计 ...

正确的,你可以测试一下。
回复 支持 反对

使用道具 举报

冰破 发表于 2016-10-27 10:52:13 | 显示全部楼层
关于TIMER0的配置和使用,我有点疑问

code中这么初始化的:
TIMER0->CSR   =  T_CRST | T_MODE_PERIODIC   | T_WR_TCMP_NO_RST | T_TDR_EN + 21 ;
所以更新timer0的CMP寄存器时,只要当TCMP <= TDR时才会重新从0开始计数
Periodic Mode Behavior Selection
0 = In One-shot or Periodic mode, when write new TCMP, timer counter will reset.
1 = In One-shot or Periodic mode, when write new TCMP if new TCMP > TDR(current
counter) , timer counter keep counting and will not reset. If new TCMP <= TDR(current
counter) , timer counter will reset.



再看运用:
void TMR1_IRQHandler(void)                                    
{  
  uint32_t  PeriodLast ;


  TIMER0->CMPR = ~0 ;          //     ~0 is 0xFFFFFFFF                     
  TIMER1->ISR  = ~0 ;                                           // Clear all interrupt flag
  ZeroDeadline = PeriodNow << 1 ;
  do{
    if((*pPhase) & DetectUpBit){                                                                                          
      if(ACMP->SR & AcmpOutBit){ ++StepCount; break; }           // up zero      
    }
    else{                                                                                                                 
      if((ACMP->SR & AcmpOutBit)==0){ ++StepCount; break; }      // down zero                     
    }
  }while(TIMER0->DR < ZeroDeadline) ;   
  PeriodLast = (TIMER1->DR - ZeroTick) & 0xFFFFFF ;



这里ZeroDeadline 的值是周期的一半,按while条件中的比较,TIMER0->DR从0开始计数才是合理的,但是前面TIMER0->CMPR赋予的是最大值,所以定时器0不会RST,
TIMER0->DR不会从0开始计数。这个while的延时条件是有问题的。




================================
我认为应该这么做:
只要更新TIMER0->CMPR值,就会重新从0开始计数
TIMER0->CSR   =  T_CRST | T_MODE_PERIODIC  | T_TDR_EN + 21 ;  

然后再修改一处地方:
  if(PeriodNow > PeriodMax) PeriodNow = PeriodMax ;  
  TIMER0->CMPR = TIMER0->DR + ((PeriodNow*PhaseAngle) >> 6) ;    // Set TIMER0 period
  TIMER1->CMPR = TIMER1->DR + ((PeriodNow*3)>>2) ;               // Set TIMER1 interrupt
修改成:
  if(PeriodNow > PeriodMax) PeriodNow = PeriodMax ;  
  TIMER0->CMPR = ((PeriodNow*PhaseAngle) >> 6) ;    // Set TIMER0 period
  TIMER1->CMPR = TIMER1->DR + ((PeriodNow*3)>>2) ;               // Set TIMER1 interrupt


回复 支持 反对

使用道具 举报

admin 发表于 2016-10-27 13:10:30 | 显示全部楼层
回复

使用道具 举报

admin 发表于 2016-10-27 13:31:00 | 显示全部楼层
回复

使用道具 举报

 楼主| Angus 发表于 2016-10-27 14:25:57 | 显示全部楼层
冰破 发表于 2016-10-27 10:52
关于TIMER0的配置和使用,我有点疑问

code中这么初始化的:

善于思考是个好习惯
你手头有板子,也有代码,你可以验证一下你的思路是否正确,看看电机能否正常转动。
回复 支持 反对

使用道具 举报

冰破 发表于 2016-10-27 15:52:20 | 显示全部楼层
Angus 发表于 2016-10-27 14:25
善于思考是个好习惯。
你手头有板子,也有代码,你可以验证一下你的思路是否正确,看看电机能否正常转 ...

能先告诉我答案吗? 我的分析是否正确。

我手上的板子不是按那个电路图来的。我目前的阶段是理解你的代码以后,再摘取有用的部分移植进我的BLDC代码中。我自己有成熟代码,不过是基于STM32的
回复 支持 反对

使用道具 举报

 楼主| Angus 发表于 2016-10-27 17:46:39 | 显示全部楼层
本帖最后由 Angus 于 2016-10-27 20:44 编辑

你说的方法应该也是可以的。
配置"写 TIMER0->CMPR 不从 0 开始计数",但写 TIMER0->CMPR 时加上了定时器的当前值。
你配置"写 TIMER0->CMPR 从 0 开始计数",但写 TIMER0->CMPR 时没加定时器的当前值。
二者延时长度是一样的,
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注新唐微信服务号

小黑屋|手机版|新唐(华邦)MCU技术交流 ( 沪ICP备13045913号

GMT+8, 2017-3-31 06:39 , Processed in 0.270401 second(s), 27 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表