5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)

标题: 航模遥控双向有刷电调电路和程序 [打印本页]

作者: sysmu    时间: 2013-11-18 13:00
标题: 航模遥控双向有刷电调电路和程序




以下代码为代论坛魔友zyb5918 发布,因为才注册帐号,想分享但发不上帖子,所以我***此贴~!
  1. ;根据PPM控制PWM  控制LED
  2. ; P1.0正转LED灯渐暗。
  3. ; P1.1反转LED灯渐亮。
  4. ;2013-11-14 参数调整可使用,接场效应管电机实验转速变化控制正常
  5. ;现有的缺点,不能断信号保护(油门保护)(失控保护)

  6.          PWM   EQU  00H       ;PWM赋初始值实验中必须00H

  7.          OUTA  EQU  P1.3      ;正转PWM输出口。
  8.          OUTB  EQU  P1.2      ;反转PWM输出口。
  9.          BZW   EQU  40H       ;正反标志
  10.          PPM   EQU  P3.5      ;接收PPM信号口

  11.          ORG   0000H
  12.          LJMP  START
  13.          ORG   000BH
  14.          LJMP  INTT0
  15.          ORG   001BH
  16.          LJMP  INTT1
  17.          ORG   0030H

  18. ;主程序
  19. ;定时器0工作在模式1,定时器1工作在模式2。

  20. START:   
  21.           MOV  SP,#30H       ;#30H
  22.           MOV TMOD,#21H      ;#21H
  23.           MOV TH1,PWM        ;脉宽调节
  24.           MOV TL1,#00H
  25.           MOV TH0,#0FFH      ;1ms延时常数#0FCH-#0D4H
  26.           MOV TL0,#00H      ;频率调节#66H-#0CDH
  27.           SETB EA
  28.           SETB ET0
  29.           SETB ET1
  30.           SETB TR0
  31. LOOP:
  32.         MOV A,PWM        ;
  33.         JB PPM,INCL      ;是否有PPM信号输入?
  34.         CLR  40H
  35.    LJMP LOOP
  36. INCL:
  37.       LCALL   YAN11   ;先延时1.1ms毫秒
  38.       JNB  PPM,PWM1   ;小于1.1,到PWM1正转最快
  39.       LCALL   YAN01    ;延时0.1ms毫秒
  40.       JNB  PPM,PWM2   ;小于1.2,到PWM2正转80/
  41.       LCALL   YAN01    ;延时0.1ms毫秒
  42.       JNB  PPM,PWM3   ;小于1.3,到PWM3正转60/
  43.       LCALL   YAN01    ;延时0.1ms毫秒
  44.       JNB  PPM,PWM4   ;小于1.4,到PWM4正转40/
  45.       LCALL   YAN01            ;延时0.1ms毫秒
  46.       JNB  PPM,PWM5   ;小于1.5,到PWM5正转最慢
  47.       LCALL   YAN01            ;延时0.1ms毫秒
  48.       JNB  PPM,PWM6   ;小于1.6,到PWM6反转最慢
  49.       LCALL   YAN01            ;延时0.1ms毫秒
  50.       JNB  PPM,PWM7   ;小于1.7,到PWM7反转40/
  51.       LCALL   YAN01    ;延时0.1ms毫秒
  52.       JNB  PPM,PWM8   ;小于1.8,到PWM8反转60/
  53.       LCALL   YAN01    ;延时0.1ms毫秒
  54.       JNB  PPM,PWM9   ;小于1.9,到PWM9反转80/
  55.       LCALL   YAN01    ;延时0.1ms毫秒
  56.       JNB  PPM,PWM0   ;小于2ms,到PWM0反转最快
  57. ljmp   LOOP

  58. PWM1:        ;正转最快
  59.      MOV   PWM,#01H
  60.      MOV   40H,#10H    ;正转标志
  61.      ljmp   LOOP

  62. PWM2:        ;正转80/
  63.      MOV   PWM,#2fH
  64.      MOV   40H,#10H    ;正转标志
  65.      ljmp   LOOP

  66. PWM3:        ;正转60/
  67.      MOV   PWM,#60H
  68.      MOV   40H,#10H    ;正转标志
  69.      ljmp   LOOP

  70. PWM4:        ;正转40
  71.      MOV   PWM,#9fH
  72.      MOV   40H,#10H    ;正转标志
  73.      ljmp   LOOP

  74. PWM5:        ;正转最慢
  75.      MOV   PWM,#0FfH
  76.      MOV   40H,#30H    ;正转标志
  77.      ljmp   LOOP

  78. PWM6:        ;反转最慢
  79.      MOV   PWM,#0FfH
  80.      MOV   40H,#30H    ;反转标志
  81.     ljmp   LOOP

  82. PWM7:        ;反转40/
  83.      MOV   PWM,#9fH
  84.      MOV   40H,#20H    ;反转标志
  85.      ljmp   LOOP

  86. PWM8:        ;反转60/
  87.      MOV   PWM,#60H
  88.      MOV   40H,#20H    ;反转标志
  89.      ljmp   LOOP

  90. PWM9:        ;反转80/
  91.      MOV   PWM,#2fH
  92.      MOV   40H,#20H    ;反转标志
  93.      ljmp   LOOP

  94. PWM0:        ;反转最快
  95.      MOV   PWM,#01H
  96.      MOV   40H,#20H    ;反转标志
  97.      ljmp   LOOP

  98. ;T0中断服务子程序   (频率)
  99. ;控制定时器1中断

  100. INTT0:
  101.        CLR  TR1
  102.        MOV TH0,#0FFH    ;1ms延时常数0FCH-0D4H
  103.        MOV TL0,#00H     ;频率调节66H-0CDH
  104.        MOV  TH1,PWM
  105.        SETB TR1
  106.        MOV   A,40H
  107.        CJNE  A,#10H,SHIB    ;如果标志不是#10H就开反转口
  108.          
  109.        CLR  OUTA
  110.        CLR  A
  111.    RETI

  112. SHIB:
  113.     CJNE  A,#20H,TUIC
  114.     CLR  OUTB
  115.     CLR  A
  116.    RETI

  117. TUIC:
  118.     CLR  A
  119.    RETI

  120. ;T1中断服务子程序      (脉宽)
  121. ;控制PWM脉冲宽度

  122. INTT1:
  123.       CLR  TR1        ;脉宽调节结束
  124.       SETB  OUTA
  125.       SETB  OUTB      ;结束输出
  126.       CLR  A
  127.   RETI

  128.          ;1.1ms延时子程序
  129. yan11:      ;STC1T,11.0592晶振
  130.     MOV R7,#01H
  131. DL1:
  132.     MOV R6,#0C4H
  133. DL0:
  134.     MOV R5,#0EH
  135.     DJNZ R5,$
  136.     DJNZ R6,DL0
  137.     DJNZ R7,DL1
  138.     NOP
  139. RET

  140.          ;0.1ms延时子程序
  141. yan01:      ;STC1T,11.0592晶振
  142.      MOV R6,#3DH
  143. DL01:
  144.     MOV R5,#03H
  145.     DJNZ R5,$
  146.     DJNZ R6,DL01
  147.     NOP
  148. RET

  149. ;WDT1:    ;看门狗 清0计数器
  150. ;MOV  WDT,#00111000B   ;#00111111B
  151. ;ret      ;71.1mS毫秒复位

  152.   END
复制代码
下面是线路图:
(, 下载次数: 173)


***完毕,哈哈,欢迎zyb5918兄弟来做沙发!


作者: zyb5918    时间: 2013-11-18 13:01
谢谢啊。


作者: sysmu    时间: 2013-11-18 13:02
呵呵,感谢兄弟热情分享!

作者: zyb5918    时间: 2013-11-18 13:13
参考一些直流电机PWM调速程序,修改测试了以上程序,驱动舵机改的小车正反转齿轮箱,用舵机测试器驱动调速,并且正反转。都可控制,昨晚又增加了正反输出各3个采样和输出。现在问题是如果在通电时随机断开输入信号,输出信号断不掉。想尽办法也不能在程序中达到这一效果。当然使用外部电路能达到,但又要增加电气元件.这个用在小车,船上一般使用都是没问题的,贴出来抛砖引玉希望高手帮忙改进。论坛里有使用PIC单片机的DIY电调,但是电路有些复杂,而且PIC单片机编程烧写也麻烦一些,我这只会一点C51汇编,所以就想用手头现有的来实验了。

作者: zyb5918    时间: 2013-11-18 13:24
附件是修改后的程序。大家可根据电机的特性自己修改速度点

作者: zyb5918    时间: 2013-11-18 13:31
使用小电机可直接接在+5V和输出OUTA之间,可单向遥控调速.省去4个场效应管

作者: sabaka    时间: 2013-11-18 13:36
   汇编啊,看不懂。。。。。。

作者: caijizhang    时间: 2013-11-18 15:03



学习


作者: fangqiaoming    时间: 2013-11-18 15:43
看不懂怎么破?

作者: woogangstrong    时间: 2013-11-18 16:09
马克下来喽!谢谢啦!

作者: smsx    时间: 2013-11-18 21:44
DIY顶一个。

作者: 山水2000    时间: 2013-11-21 20:57
好,顶一下,有空搞个试试。

作者: t01051    时间: 2013-11-21 21:40
汇编真心看不懂,要是能有C参照就好了

作者: zyb5918    时间: 2013-11-22 02:55
C语言还没入门


作者: zyb5918    时间: 2013-11-22 03:00
有个也是使用STC12C2052AD的,一片就输入2个通道,输出控制2个电机,有电路图有C程序,表示看不懂.编译时也报错,楼上懂C程序的能否帮忙修改一下?
#include"STC12C2052AD.H"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit input1=P3^0;                                   
sbit input2=P3^1;                                    
sbit output11=P1^0;                                       
sbit output12=P1^1;                                       
sbit output21=P1^2;
sbit output22=P1^3;
bit no1=1,no2=1,leftup=0,leftdown=0;
bit rightup=0,rightdown=0;
uint no5=0,no6=0;
uchar i;
char no7=0,no8=0,no9=0,no10=0;
char no11=0,no12=0;
void timer();
void zx();
void hx();
void hh();
void sc();
void main()
{                                                      
     P3M0=0x00;   //由于要在P3.7和P3.5输出PWM,故把P3.7和P3.5设为推挽输出。
     P3M1=0xa0;   //同上。
     AUXR=0x80;  //计数器工作在1T模式(计数速度与晶振频率相同)0x8E
     TMOD=0x02;  //计数器0工作在方式2(自动装入计数值模式)
     TH0=254;    //PWM模块输出频率约为23KHz
     TL0=254;
     EA=1;
     ET0=1;
     CMOD=0x05;                                             
     CCON=0x40;                                             
     CCAPM0=0x42;                                            
     CCAPM1=0x42;                                            
     CCAP0H=0xff;                                            
     CCAP0L=0xff;                                            
     CCAP1H=0xff;                                            
     CCAP1L=0xff;                                            
     TR0=1;
     while(1)
     {
     if((input1&no1)==1)   //纵向通道扫描
     {
      while(input1==1)
      {
       no5++;
      timer();
       }
      no1=0;
      }
      if((input2&no2)==1)   //横向通道扫描
      {
      while(input2==1)
     {
       no6++;
       timer();
      }
      no2=0;
      }
    if((no1|no2)==0)   //单次扫描完成判断
     {
      no1=1;
     no2=1;
     zx();
     hx();
     hh();
     sc();
   

作者: zyb5918    时间: 2013-11-22 03:00
output11=leftup;  //每次对扫描得到的数据处理完成之后对电机方向控制端口进行置位
    output12=leftdown;    //同上
    output21=rightup;       //同上
    output22=rightdown;   //同上
     no5=0;
     no6=0;
      }
     }
     }
    void timer()                                                
     {
     for(i=18;i>0;i--);
         _nop_();
         _nop_();                                                         
         _nop_();                                                         
      }
      void zx()   //纵向摇杆信号处理子程序
     {
     if(no5<115)
     {
          no7=-7;
          no8=-7;
     }
     else if(no5>=115&&no5<120)
     {
          no7=-6;
          no8=-6;
     }
     else if(no5>=120&&no5<125)
     {
          no7=-5;
          no8=-5;
     }
     else if(no5>=125&&no5<130)
     {
          no7=-4;
          no8=-4;
     }
     else if(no5>=130&&no5<135)
     {
          no7=-3;
          no8=-3;
     }
     else if(no5>=135&&no5<140)
     {
          no7=-2;
          no8=-2;
     }
     else if(no5>=140&&no5<145)
     {
          no7=-1;
          no8=-1;
     }
     else if(no5>=145&&no5<=155)
     {
          no7=0;
          no8=0;
     }
     else if(no5>155&&no5<=160)
     {
          no7=1;
          no8=1;
     }
     else if(no5>160&&no5<=165)
     {
          no7=2;
          no8=2;
     }
     else if(no5>165&&no5<=170)
     {
          no7=3;
          no8=3;
     }else if(no5>=170&&no5<175)
     {
          no7=4;
          no8=4;
     }
     else if(no5>=175&&no5<180)
     {
          no7=5;
          no8=5;
     }
     else if(no5>=180&&no5<185)
     {
          no7=6;
          no8=6;
     }
     else
     {
          no7=7;
          no8=7;
     }
    void hx()      //横向摇杆信号处理子程序
     {
     if(no6<115)
     {
          no9=7;
          no10=-7;
     }
     else if(no6>=115&&no6<120)
     {
          no9=6;
          no10=-6;
     }
     else if(no6>=120&&no6<125)
     {
          no9=5;
          no10=-5;
     }
     else if(no6>=125&&no6<130)
     {
          no9=4;
          no10=-4;
     }
     else if(no6>=130&&no6<135)
     {
          no9=3;
          no10=-3;
     }
     else if(no6>=135&&no6<140)
     {
          no9=2;
          no10=-2;
     }
     else if(no6>=140&&no6<145)
     {
          no9=1;
          no10=-1;
     }
     else if(no6>=145&&no6<=155)
     {
          no9=0;
          no10=-0;
     }
     else if(no6>155&&no6<=160)
     {
          no9=-1;
          no10=1;
     }
     else if(no6>160&&no6<=165)
     {
          no9=-2;
          no10=2;
     }
     else if(no6>165&&no6<=170)
     {
          no9=-3;
          no10=3;
     }
     else if(no6>=170&&no6<175)
     {
          no9=-4;
          no10=4;
     }
     else if(no6>175&&no6<=180)
     {
          no9=-5;
          no10=5;
     }
     else if(no6>180&&no6<=185)
     {
          no9=-6;
          no10=6;
     }
     else
     {
          no9=-7;
          no10=7;
     }
    void hh()        //混合两通道信号子程序
     {
     no11=no7+no9;
     no12=no8+no10;
     if(no11>7)
     {
          no11=7;
     }
     if(no11<-7)
     {
          no11=-4;
     }
     if(no12>7)
     {
          no12=7;
     }
     if(no12<-7)
     {
          no12=-7;
     }
     }
    void sc()    //输出占空比选择和电机旋转方向选择子程序
      {
     switch(no11)
     {
     case 7:                          
        CCAP0H=0x0a;
        leftup=1;
        leftdown=0;                 
      break;
      case 6:                          
         CCAP0H=0x27;
          leftup=1;
          leftdown=0;                 
           break;
       case 5:                          
                 CCAP0H=0x4b;
                 leftup=1;
                 leftdown=0;                 
                 break;
          case 4:                          
                 CCAP0H=0x6f;
                 leftup=1;
                 leftdown=0;                                 
                 break;
          case 3:                          
                 CCAP0H=0x93;
                 leftup=1;
                 leftdown=0;                                 
                 break;
          case 2:                          
                 CCAP0H=0xb7;
                 leftup=1;
                 leftdown=0;                                 
                 break;
          case 1:                          
                 CCAP0H=0xdb;
                 leftup=1;
                 leftdown=0;                                 
                 break;
          case 0:                          
                 CCAP0H=0xff;
                 leftup=0;
                 leftdown=0;                 
                 break;
         case -1:                          
                 CCAP0H=0xdb;
                 leftup=0;
                 leftdown=1;                                 
                 break;
         case -2:                          
                 CCAP0H=0xb7;
                 leftup=0;
                 leftdown=1;                                 
                 break;
         case -3:                          
                 CCAP0H=0x93;
                 leftup=0;
                 leftdown=1;                                 
                 break;
         case -4:                          
                 CCAP0H=0x6f;
                 leftup=0;
                 leftdown=1;
                 break;
         case -5:                          
                 CCAP0H=0x4b;
                 leftup=0;
                 leftdown=1;                 
                 break;                 
         case -6:                          
                 CCAP0H=0x27;
                 leftup=0;
                 leftdown=1;                 
                 break;
         case -7:                          
                 CCAP0H=0x0a;
                 leftup=0;
                 leftdown=1;                 
                 break;
     }
     switch(no12)
     {
          case 7:                          
                 CCAP1H=0x0a;
                 rightup=1;
                 rightdown=0;                 
                 break;
          case 6:                          
                 CCAP1H=0x27;
                 rightup=1;
                 rightdown=0;                 
                 break;
          case 5:                          
                 CCAP1H=0x4b;
                 rightup=1;
                 rightdown=0;                 
                 break;
          case 4:                          
                 CCAP1H=0x6f;
                 rightup=1;
                 rightdown=0;                 
                 break;
          case 3:                          
                 CCAP1H=0x93;
                 rightup=1;
                 rightdown=0;                 
                 break;
          case 2:                          
                 CCAP1H=0xb7;
                 rightup=1;
                 rightdown=0;                 
                 break;
          case 1:                          
                 CCAP1H=0xdb;
                 rightup=1;
                 rightdown=0;                 
                 break;
          case 0:                          
                 CCAP1H=0xff;
                 rightup=0;
                 rightdown=0;                 
                 break;
         case -1:                          
                 CCAP1H=0xdb;
                 rightup=0;
                 rightdown=1;
                 break;
         case -2:                          
                 CCAP1H=0xb7;
                 rightup=0;
                 rightdown=1;                 
                 break;                 
         case -3:                          
                 CCAP1H=0x93;
                 rightup=0;
                 rightdown=1;                 
                 break;
         case -4:                          
                 CCAP1H=0x6f;
                 rightup=0;
                 rightdown=1;                 
                 break;
         case -5:                          
                 CCAP1H=0x4b;
                 rightup=0;
                 rightdown=1;                 
                 break;
         case -6:                          
                 CCAP1H=0x27;
                 rightup=0;
                 rightdown=1;                 
                 break;
         case -7:                          
                 CCAP1H=0x0a;
                 rightup=0;
                 rightdown=1;                 
                 break;
     }
}

作者: zyb5918    时间: 2013-11-22 03:06
实在是不懂他是怎么输入处理2路遥控信号PPM,去调速控制2个电机的转速和转向,原贴在http://www.geekfans.com/thread-62034-1-1.html航模PPM信号转PWM信号转换器

作者: zyb5918    时间: 2013-11-22 03:07
期待懂C程序的来讲解一下。我好用汇编写出来.做做试试

作者: skypup    时间: 2013-11-23 01:23
查了数据手册,STC12C2052AD带硬件PWM输出。
似乎上面的C程序就是依次读遥控接收器的PWM控制信号,改变PWM输出的占空比。

请问楼主是用的什么芯片喔?

作者: zyb5918    时间: 2013-11-23 02:22
我一般用STC11F04E, STC12C2052AD我也有,C2052AD的PWM只能在P3.5和P3.7脚输出,要想控制2台电机得增加外围驱动控制电路,除非将P.5和P3.7的PWM输出转移到P1口的其它4个I/O口上输出.不知是否能办到。


作者: zyb5918    时间: 2013-11-23 02:26
t01051 发表于 2013-11-21 21:40
汇编真心看不懂,要是能有C参照就好了

贴出C程序了,别人的,单个STC12C2052AD控制2个电机。2路遥控输入。你看看程序,讲讲输入输出程序的控制理吧。C程序真心看不懂啊



作者: 地方政府    时间: 2013-11-30 10:04
做做试试


作者: 我就是个渣    时间: 2014-3-2 23:26
打酱油的路过。

作者: code    时间: 2014-4-23 19:26
mark一下

作者: hljwkwgy    时间: 2014-4-24 16:36
围观~~~挣分~~~

作者: robingao    时间: 2014-5-11 19:32
本帖最后由 robingao 于 2014-5-22 21:16 编辑

我是初学者,按 zyb5918 的图纸做了这个电调,用的AT89C2051单片机 和 2013-11-14 版本的程序,驱动 140 玩具电机。
上电测试,万用表测量第 9 管脚能正常收到接收机的脉冲信号,但 12,13 管脚没有输出。接收机是富斯 FS-R6B 六通接收机。

我的测试如下:
1、万用表测量管脚9(P35/T1),10(GND) 有接收机发出的脉冲信号,但12(P10),13(P11) 管脚没有输出;(怎样确定这个程序正常工作?)
2、这两个三极管 8550 PNP 或 8550 BG 是完全一样的型号吗?
3、将电机一端直接连接到 OUTA,另一端连接正 5V,短路三极管 8550 PNP,电机正常转动。
问下大家应该怎样排错和调试?先谢谢了!我的QQ 498735756 (, 下载次数: 75)

请教 zyb5918 和大家:
1、管脚12(P10),13(P11)  连接的电阻应该是1K 还是 470欧,管脚 12,13 是否要加上拉电阻?
2、图纸左上角的连接2和3管脚的 JP1 是什么,是必须的吗?
3、右下角的 7805 芯片左管脚接正 5V 是起稳压的作用吗?
4、使用 Keil4 编译程序为 HEX 文件时要注意什么吗,烧写HEX 时是否必须要有配置文件?
这是我的编译配置,请问有错吗? (, 下载次数: 72)

5、是否应该把所有的地线连在一起,另把所有的正 5V 连接在一起?














作者: zyb5918    时间: 2014-5-24 22:21
robingao 发表于 2014-5-11 19:32
我是初学者,按 zyb5918 的图纸做了这个电调,用的AT89C2051单片机 和 2013-11-14 版本的程序,驱动 140 玩 ...

对不住呀,这长时间才看到。你可调试程序是观察2个发光二极管。随着遥控手柄变化亮度会改变。这些程序我都是实验过的。


作者: zyb5918    时间: 2014-5-24 22:25
robingao 发表于 2014-5-11 19:32
我是初学者,按 zyb5918 的图纸做了这个电调,用的AT89C2051单片机 和 2013-11-14 版本的程序,驱动 140 玩 ...

你也用的富斯遥控接收。和我的一样


作者: zyb5918    时间: 2014-5-24 22:28
robingao 发表于 2014-5-11 19:32
我是初学者,按 zyb5918 的图纸做了这个电调,用的AT89C2051单片机 和 2013-11-14 版本的程序,驱动 140 玩 ...

当然要所有+5V接在一起,GND地线接在一起


作者: ooyayaoo    时间: 2014-7-4 14:21
学习一下  谢谢

作者: iwt2014    时间: 2014-7-4 22:51
太牛了,汇编太厉害了。不过,看不懂了。十年前还会一点

作者: cuipingguo    时间: 2014-12-31 14:07
程序没有太大的问题!
通过keil uv4编译后可以检测p1.2 p1.3 的电压变化!

但是接上8550后.8550放大前的LED可以显示电压变化.

但是8550后的放大电路好像有一路是不通的.查资料说pnp .电压降低时候将截止.也就以为着不会放大导通!

所以要在4个MOS前段加上2个8550和2个8050.搭建一个放大


程序方面.感觉调速区间不够线性.在增加几段程序. 多加几级调速段 就会线性一点!!!!!!!!


楼主方便的话留下电话或者QQ!


作者: cuipingguo    时间: 2014-12-31 14:12
robingao 发表于 2014-5-11 19:32
我是初学者,按 zyb5918 的图纸做了这个电调,用的AT89C2051单片机 和 2013-11-14 版本的程序,驱动 140 玩 ...

按照89s51来看的话!
芯片内部无上拉电阻.理论上应该加上拉!

我这边可以检测到12  13的电压信号

但是就是芯片下载程序不稳定  我用的STC11F02E

下次时候 老是提示请给MCU上电  快郁闷死了


作者: chenjun72    时间: 2015-5-27 16:35






欢迎光临 5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年) (http://wz.5imx.com/) Powered by Discuz! X3.3