找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

26万转:用最短代码,转最快电机

  [复制链接]
81#
 楼主| Angus 发表于 2016-10-26 16:14:32 | 只看该作者
本帖最后由 Angus 于 2016-10-26 22:44 编辑
冰破 发表于 2016-10-26 14:21
PWM->PHCHGMASK =  PHCHG_CTL_CMP1 | P01_OUT_D6 | P00_OUT_D7 ;        

P01和P00用PWM输出模块输出值 ...

P00,P01用做串口,只要把这两个引脚配置成串口功能即可,其它不用改。
回复 支持 反对

使用道具 举报

82#
 楼主| Angus 发表于 2016-10-26 16:16:40 | 只看该作者
冰破 发表于 2016-10-26 15:03
PWM024_0_MOS_On() ;                 // PWM024 输出低时 MOS 导通,调用此函数让输出反相     
  PWM135_ ...

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

使用道具 举报

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

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

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

使用道具 举报

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

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

使用道具 举报

85#
冰破 发表于 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


回复 支持 反对

使用道具 举报

86#
 楼主| Angus 发表于 2016-10-27 14:25:57 | 只看该作者
冰破 发表于 2016-10-27 10:52
关于TIMER0的配置和使用,我有点疑问

code中这么初始化的:

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

使用道具 举报

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

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

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

使用道具 举报

88#
 楼主| Angus 发表于 2016-10-27 17:46:39 | 只看该作者
本帖最后由 Angus 于 2016-10-27 20:44 编辑

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

使用道具 举报

89#
 楼主| Angus 发表于 2017-1-4 12:45:44 | 只看该作者
wangjiahao88 发表于 2016-12-26 17:13
有没有开发板?

在哪里采购?

电机开发板,已赠送完了,没再做。
Mini52/NM1200 的最小系统板子,仍有,可通过代理商申请。
回复 支持 反对

使用道具 举报

90#
pongwy 发表于 2017-2-9 09:45:17 | 只看该作者
学习了,做的很好很好,可以拿着份资料入门了,非常感谢!
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU