找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3575|回复: 2
打印 上一主题 下一主题
收起左侧

求直流伺服电机怎么控制输出脉冲个数转动一度角度,哪位大佬能改下我这程序

[复制链接]
跳转到指定楼层
楼主
哪位大佬能看看我这程序,为啥我按键输入一度角度值,电机不能转转动对应角度,是脉冲函数部分错了吗,会的大佬能不能改一下,有感谢


单片机源程序如下:
  1. #include <reg52.h>
  2. #include<string.h>
  3. #include <intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6.      
  7. sbit lcdrs=P2^0;       //寄存器选择,0:数据寄存器。1:为状态/命令寄存器
  8. sbit lcden=P2^1;         //--LCD控制引脚

  9. sbit angle=P3^3;                                        //测转角端口
  10. sbit ENA=P2^2;                                        //电机使能控制端
  11. sbit Zheng=P2^5;                                                //正反转电平设置端口
  12. sbit Fan=P2^6;                                               



  13. uchar Timer0_flag=0;
  14. uchar Timer0_BiaoZhi=0;//初始化占空比为1:3(高:低)
  15. uchar  da;
  16. uchar gewei;
  17. uchar shiwei;
  18. uchar baiwei;
  19. uchar n;
  20. uchar angel;
  21. int aa[3];
  22. /******标志位设置*****/
  23. uchar KEY1=0;//优先级标志
  24. uchar KEY2=0;//加速标志

  25. uchar INT1_FLAG=0;
  26. uchar COUNTER_high=0;
  27. uchar COUNTER_low=0;
  28. uchar SUM=0;
  29. uint TIMER1_COUNTER=0;
  30. uint INT1_tingzhi=0;                //在要测速时置0

  31. /****面板显示****/
  32. uchar code lcd_desktop11[]="stop";//停止
  33. uchar code lcd_desktop12[]="ford";//正转
  34. uchar code lcd_desktop13[]=" fanzhuang";//反转
  35. uchar code lcd_desktop21[]=" speedup";//加速
  36. uchar code lcd_desktop22[]=" speeddn";//减速
  37. uchar code num[]={'0','1','2','3','4','5','6','7','8','9'};//要显示的转速数字。

  38. //-----lcd液晶屏头文件-----//
  39. /**延时函数**/
  40. void delayms(uchar xms)   
  41. {
  42.         uchar i,j;
  43.         for(i=xms;i>0;i--)
  44.         for(j=110;j>0;j--);
  45. }

  46. /****LCD写命令******/
  47. void write_command(uchar com)//com写入命令
  48. {
  49.         lcdrs=0;
  50.         P0=com;
  51.         delayms(2);
  52.         lcden=1;
  53.         delayms(2);
  54.         lcden=0;
  55. }

  56. /**************LCD写数据*********/
  57. void write_data(uchar date)//数据为DATA
  58. {
  59.         lcdrs=1;
  60.         P0=date;
  61.         delayms(2);
  62.         lcden=1;
  63.         delayms(2);
  64.         lcden=0;
  65. }

  66. /********LCD初始化****************/
  67. void lcd_init()//显示模式设置
  68. {
  69.         lcden=0;
  70.         write_command(0x38);
  71.         write_command(0x0c);
  72.         write_command(0x06);
  73.         write_command(0x01);
  74. }

  75. /**电机初始化函数**/
  76. void motor_init(void)
  77. {
  78.         ENA=0;                                //        停止
  79. }

  80. void ZhongDuanKaiQi(void)
  81. {
  82.         EA=1;               
  83.         ET0=1;        //计时器0允许中断。产生脉冲。
  84.         ET1=1;        //计时器1允许中断。对低电平进行计时。
  85.         //EX1=1;        //INT0允许中断。测速。由外部来启动。
  86.         IT1=1;        //低电平触发。
  87.         PX1=0;        //低级中断。
  88.         PT0=1;
  89.         PT1=0;
  90.         TMOD=0x12;//定时器工作方式控制
  91. }
  92. /***定时器T1初始化!!!等待外部脉冲的到来***/
  93. void Timer1_init(void)
  94. {
  95.         TH1=0;
  96.         TL1=0;                //等待外部脉的到来。INT1
  97. }
  98. /*****定时T0初始化*****/
  99. void Timer0_init(void)
  100. {
  101.         TH0=0;
  102.         TL0=0;
  103.         TR0=1;
  104. }
  105. /********测速模块,显示速度*******/
  106. /*void speed_test(void)
  107. {
  108. //        TIMER1_COUNTER;
  109.         COUNTER_high=TH1;
  110.         COUNTER_low=TL1;
  111.         SUM=COUNTER_high*256+COUNTER_low+TIMER1_COUNTER*65536;//得到的是多少us。
  112.         SUM=SUM/1000;                                //化为毫秒。
  113.         SUM=1000/SUM;                                //圈每秒。
  114.         SUM=SUM*60;                                        //圈每分钟;三位数。
  115.         gewei=SUM%10;
  116.         shiwei=SUM/10%10;
  117.         baiwei=SUM/100;
  118.         write_command(0xc0);
  119.         write_data(baiwei);
  120.         write_command(0xc1);
  121.         write_data(shiwei);
  122.         write_command(0xc2);
  123.         write_data(gewei);
  124.         SUM=0;
  125.         TIMER1_COUNTER=0;               
  126. }


  127. /********外中断1函数**********/
  128. void INT1_QIDONG() interrupt 2
  129. {
  130.         INT1_tingzhi++;
  131.         if(INT1_tingzhi==5)
  132.         {
  133.                 INT1_tingzhi=5;EX1=0;//关闭中断。
  134.         }
  135.         if(INT1_tingzhi<=4)
  136.         {
  137.                 INT1_FLAG++;
  138.           if(INT1_FLAG==2)
  139.                         {
  140.                                 INT1_FLAG=0;TR1=0;speed_test();
  141.                         }
  142.                 else
  143.                         {
  144.                                 Timer1_init();
  145.                                 TR1=1;
  146.                         }
  147.         }
  148. }
  149. /******定时器T1计数*******/
  150. void Timer1_QIDONG() interrupt 3
  151. {
  152.         TIMER1_COUNTER++;
  153. }


  154. /**相位测量并输出!!!!!出现问题???**/
  155. /*void xiangwei_test(void)
  156. {
  157.         uchar i=0,j=0;
  158.         //while((P2^3==0)&&(P2^4==0));
  159.         //if((P2^3==0)&&(P2^4==0))
  160.         {
  161.                 //delayms(5);
  162.                 if(P2^3==1)
  163.                 {
  164.                         write_command(0x01);
  165.                         write_command(0x80);for(i=0;i<=3;i++) write_data(lcd_desktop13[i]);//反转。
  166.                         j++;//反转
  167.                 }
  168.                
  169.                 if(P2^4==1)
  170.                 {
  171.                         write_command(0x01);
  172.                         write_command(0x80);for(i=0;i<=3;i++) write_data(lcd_desktop12[i]);//正转。
  173.                         j++;
  174.                 }
  175.         }
  176. }

  177. /****T0中断发出信号并进行通道选择****/
  178. void Timer0() interrupt 1
  179. {       
  180.         Timer0_flag--;
  181.         if((Timer0_BiaoZhi)>=(Timer0_flag))
  182.         {
  183.                 if(KEY2==0)
  184.                 {
  185.                         Zheng=1;Fan=0;
  186.                 }
  187.                 else
  188.                 {
  189.                         Zheng=0;Fan=1;
  190.                 }
  191.         }
  192.         else
  193.         {
  194.                 Zheng=0;Fan=0;                               
  195.         }       
  196.         if(Timer0_flag==0) Timer0_flag=5;
  197. }


  198. void Guan(void)
  199. {
  200.         ET0=0;
  201.         EX1=0;
  202.         ET1=0;       
  203. }

  204. /*********/
  205. void pulsegenerate(){
  206.           int g,N;
  207.           N=angel*40;
  208.           for(g=0;g<N;g++)
  209.             {
  210.                                 ENA=0;
  211.                                 delayms(10);
  212.                                 ENA=1;
  213.                                 delayms(10);
  214.                                 ENA=0;
  215.                                 delayms(10);
  216.        }
  217. }

  218. void keyscan()                         //按键扫描函数
  219. {
  220.         uint i=0;
  221.                         KEY1=5;
  222.                         Fan=0;
  223.                         Zheng=0;
  224.                         //ENA=1;
  225.                         KEY2=0;//初始化为正转。
  226.                   Timer0_BiaoZhi=0;
  227.                         Timer0_flag=4;
  228.                        
  229.                         ZhongDuanKaiQi();//开启中断       
  230.                         Timer0_init();//                初始化并开始发出脉场外中断已经开启。
  231.                         EX1=1;                                        //外中断开启;测速,显示速度。五次后结束关闭外中断1。出现问题!!!
  232.                        
  233.                         write_command(0x80);
  234.                         for(i=0;i<strlen(lcd_desktop11);i++)//显示正转。
  235.                         write_data(lcd_desktop12[i]);
  236.        
  237. }
  238. /******键盘0-9输入模块*******/

  239. uchar keyin(){      //键盘
  240. uchar temp;
  241.         uchar com,com1,com2;
  242.         P1=0xf0;
  243.         if(P1!=0xf0){
  244.                 com1=P1;
  245.                 P1=0x0f;
  246.                 com2=P1;
  247.         }
  248.         P1=0xf0;
  249.         while(P1!=0xf0);
  250.                 temp=com1|com2;
  251.                 if(temp==0xee)com=0x01;
  252.                 if(temp==0xed)com=0x02;
  253.                 if(temp==0xeb)com=0x03;
  254.                 if(temp==0xde)com=0x04;
  255.                 if(temp==0xdd)com=0x05;
  256.                 if(temp==0xdb)com=0x06;
  257.                 if(temp==0xbe)com=0x07;
  258.                 if(temp==0xbd)com=0x08;
  259.                 if(temp==0xbb)com=0x09;
  260.                 if(temp==0x7e)com=0x0a;
  261.                 if(temp==0x7d)com=0x00;
  262.                 if(temp==0x7b)com=0x0b;
  263.                 return com;
  264. }
  265. void xianshi(){
  266.         uchar a;
  267.         uchar d=1;
  268.         uchar da;
  269.         P1=0xf0;
  270.         for(a=0;a<d;a++){
  271.                 int i1=0;
  272.                 while(P1==0xf0);
  273.                 da=keyin();  //调用keyin函数
  274.                
  275.                 if(da>=0x00&&da<=0x09){
  276.                                 aa[i1]=da;
  277.                                 i1++;
  278.                                 if(i1==3){
  279.                                         angel=aa[0]*100+aa[1]*10+aa[2];
  280.                                         i1=0;
  281.                                 }
  282.                         }
  283.                         Timer0_flag = angel;
  284.                 //if(da>=0x00&&da<=0x09){aa[i1]=da;i1++;if(i1==3){angel1=aa[0]*100+aa[1]*10+aa[2];i1=0;}}
  285.                 if(4==d) {
  286.                         while(1){
  287.                                 da=keyin();  //调用keyin函
  288.                                 if(da==0x0a){
  289.                                                 lcd_init();
  290.                                                 //xianshi();
  291.                                 }else if(da==0x0b){
  292.                                                 keyscan();
  293.                                 }
  294.                         }
  295.                 }
  296.                        
  297.                 if(da==0x01){
  298.                                         write_data('1');
  299.                         d++;
  300.                 }else if(da==0x02){
  301.                                         write_data('2');
  302.                         d++;
  303.                 }else if(da==0x03){
  304.                                         write_data('3');
  305.                         d++;
  306.                 }else if(da==0x04){
  307.                                         write_data('4');
  308.                         d++;
  309.                 }else if(da==0x05){
  310.                                         write_data('5');
  311.                         d++;
  312.                 }else if(da==0x06){
  313.                                         write_data('6');
  314.                         d++;
  315.                 }else if(da==0x07){
  316.                                         write_data('7');
  317.                                         d++;
  318.                 }else if(da==0x08){
  319.                                         write_data('8');
  320.                         d++;
  321.                 }else if(da==0x09){
  322.                                         write_data('9');
  323.                         d++;
  324.                 }else if(da==0x00){
  325.                                         write_data('0');
  326.                         d++;
  327.                 }/*else if(da==0x0a){
  328.                         lcd_init();
  329.                         //xianshi();
  330.                 }else if(da==0x0b){
  331.                         pulsegenerate();
  332.                                 break;
  333.                 }*/
  334.        
  335.         }
  336. }       

  337. /***************/


  338. /*****************/

  339.        
  340. /* if((key2==0)&&(KEY1=5)) //按键K2按下,(正转)只改变转向(标志位改变输出端口)
  341.         {
  342.                 delayms(10);
  343.                 if(key2==0)
  344.                 {
  345.                         while(!key1);
  346.                         KEY1=5;
  347.                         Fan=0;
  348.                         Zheng=0;
  349.                         ENA=1;
  350.                         KEY2=0;//初始化为正转。
  351.                   Timer0_BiaoZhi=0;
  352.                         Timer0_flag=4;
  353.                        
  354.                         ZhongDuanKaiQi();//开启中断       
  355.                         Timer0_init();//                初始化并开始发出脉场外中断已经开启。
  356.                         EX1=1;                                        //外中断开启;测速,显示速度。五次后结束关闭外中断1。出现问题!!!
  357.                        
  358.                         write_command(0x80);
  359.                         for(i=0;i<strlen(lcd_desktop11);i++)//显示正转。
  360.                         write_data(lcd_desktop12[i]);
  361.                 }
  362.         }
  363.        
  364.         if((key3==0)&&(KEY1=5)) //按键K3按下,(反转)只改变转向
  365.         {
  366.                 delayms(10);
  367.                 if(key3==0)
  368.                 {
  369.                         while(!key3);
  370.                         KEY2=~0;                        //反转标志。
  371.                         //KEY2=(~0);
  372.                         xiangwei_test();
  373.                         KEY1=5;
  374.                         lcd_init();
  375.                          for(n=0;n<10;n++){
  376.                                 write_data(lcd_desktop13[n]);}
  377.                 }
  378.         }
  379.    if((key4==0)&&(KEY1==5))        //按键K4按下,(加速)改变装入的数值?循环次数?执行if里面的语句,通过size++来改变幅值的频率
  380.          {
  381.                  delayms(10);
  382.                  if(key4==0)
  383.                  {
  384.                          while(!key4);
  385.                          if(Timer0_BiaoZhi<4)
  386.                          {
  387.                                  Timer0_BiaoZhi++;
  388.                          }
  389.                          else
  390.                          {
  391.                                  Timer0_BiaoZhi=4;
  392.                          }
  393.                           EX1=1;
  394.                           KEY1=5;
  395.                          lcd_init();
  396.                          for(n=0;n<8;n++){
  397.                                 write_data(lcd_desktop21[n]);}
  398.                  }
  399.                
  400.          }
  401.          
  402.          if((key5==0)&&(KEY1==5))         //按键K5按下,(减速)对其它标志位没有影响。
  403.          {
  404.                  delayms(5);
  405.                  if(key5==0)
  406.                  {
  407.                          while(!key5);
  408.                          if(Timer0_BiaoZhi==0)
  409.                          {
  410.                                  Timer0_BiaoZhi=0;
  411.                          }
  412.                          else
  413.                          {
  414.                                  Timer0_BiaoZhi--;
  415.                          }
  416.                           EX1=1;
  417.                           KEY1=5;
  418.                          lcd_init();
  419.                          for(n=0;n<8;n++){
  420.                                 write_data(lcd_desktop22[n]);}
  421.                  }
  422.          }
  423.          if((key6==0)&&(KEY1==5))//按键K6按下,电机停止转动使能端和计数启动关闭,计数器工作否?设立标志位。此按键按下后除K1外无法启动
  424.          {
  425.                  delayms(5);
  426.                  if(key6==0)
  427.                  {
  428.                          while(!key6);
  429.                          //置位,保证后续操作正常。
  430.                          
  431.                          
  432.                          
  433.                          EA=0;                                //总中断关
  434.                          motor_init();                //电机关
  435.                          lcd_init();
  436.                          Guan();
  437.                                                            
  438.                  }
  439.          }
  440. }

  441. /*主函数*/
  442. void main()
  443. {

  444.         ZhongDuanKaiQi();//初始化
  445.         motor_init();                        //电机停止
  446.         lcd_init();
  447.         while(1)
  448.         {
  449.                 xianshi();
  450.                
  451.         }
  452. }
复制代码

所有资料51hei提供下载:
lyp22.zip (84.34 KB, 下载次数: 23)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:750208 发表于 2020-5-15 12:47 来自触屏版 | 只看该作者
你的D4连在哪里啊,图中没有
回复

使用道具 举报

板凳
ID:800205 发表于 2020-7-9 10:13 | 只看该作者
你是用51做的啊
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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