[51单片机] 上位机控制单片机控制步进电机

[复制链接]
2239|2
 楼主| fhyxihuan1314 发表于 2017-5-25 13:16 | 显示全部楼层 |阅读模式
最近用上位机发一串数据控制单片机,主要是控制步进电机的起停,转向,脉冲数,频率,输入的数据如A1000C1000D1E1.2F1,第一个1000为脉冲数,第二个1000为频率,D后面的1代表转向,E后面的1.2代表占空比,F后面的1代表起停,程序写好后用串口助手发过去,数据能发送,没问题,但是步进电机不能运行,求解,求解。
  1. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
  2. //#include<stdio.h>
  3. typedef unsigned int u16;         
  4. typedef unsigned char u8;
  5. unsigned char timer1;
  6. void timerint(void);
  7. int T;
  8. int c;
  9. int z;
  10. int i;
  11. double aa;int cc;double dd;float ee;         double ff;
  12. sbit DIR=P1^0; //换向DIR为P1.0口
  13. sbit ENA=P1^1; //使能ENA为P1.1口
  14. sbit CP=P1^2; //脉冲CP为P1.2口
  15. sbit K1=P1^3;//外部控制正转
  16. sbit K3=P1^4;//外部控制反转
  17. sbit K2=P1^5; //外部停止
  18. sbit CP1=P1^6; //控制电压脉冲为P1.6口
  19. sbit p1=P2^1;
  20. char receiveData[18];
  21. /*******************************************************************************
  22. * 函数名         :UsartInit()
  23. * 函数功能                   :设置串口
  24. * 输入           : 无
  25. * 输出                  : 无
  26. *******************************************************************************/
  27. void UsartInit()
  28. {
  29.         SCON=0X50;                        //设置为工作方式1
  30.         TMOD=0X20;                        //设置计数器工作方式2
  31.         PCON=0X80;                        //波特率加倍
  32.         TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的
  33.         TL1=0XF3;
  34.         ES=1;                                                //打开接收中断
  35.         EA=1;                                                //打开总中断
  36.         TR1=1;                                        //打开计数器
  37. }
  38. void system_Ini()                 //T0
  39. {
  40.     TMOD=0X01;
  41.     TH0 =0XFF;                         //0.05ms定时
  42.     TL0 =0XCE;
  43.     EA = 1;
  44.     ET0 = 1;
  45.     TR0 = 1;
  46. }
  47. // void delay(u16 j)
  48. //{
  49. //        while(j--);       
  50. //}
  51. /*******************************************************************************
  52. * 函 数 名       : main
  53. * 函数功能                 : 主函数
  54. * 输    入       : 无
  55. * 输    出             : 无
  56. *******************************************************************************/
  57. void main()
  58. {       
  59.         UsartInit();  //        串口初始化       
  60.         ENA=0;
  61.         if(i>17)
  62.                     i=0;
  63.                 if(receiveData[0]=='A')
  64.                 {
  65.                  if(receiveData[1]<='0'||receiveData[1]>='9')
  66.                         {receiveData[1]='0';}
  67.                     if(receiveData[2]<='0'||receiveData[2]>='9')
  68.                         {receiveData[2]='0';}
  69.                         if(receiveData[3]<='0'||receiveData[3]>='9')
  70.                         {receiveData[3]='0';}
  71.                         aa=1000*(receiveData[1]-'0')+100*(receiveData[2]-'0')+10*(receiveData[3]-'0')+(receiveData[4]-'0');
  72.                         if(receiveData[6]<='0'||receiveData[6]>='9')
  73.                         {receiveData[6]='0';}
  74.                     if(receiveData[7]<='0'||receiveData[7]>='9')
  75.                         {receiveData[7]='0';}
  76.                         if(receiveData[8]<='0'||receiveData[8]>='9')
  77.                         {receiveData[8]='0';}
  78.                         cc=1000*(receiveData[6]-'0')+100*(receiveData[7]-'0')+10*(receiveData[8]-'0')+(receiveData[9]-'0');
  79.                    dd=receiveData[11]-'0';
  80.                    ee=(receiveData[13]-'0')+(receiveData[15]-'0')*0.1;
  81.                    ff=receiveData[17]-'0';         }
  82.         system_Ini();//初始化定时器T0                        
  83.          while(1)       
  84.          {         if(10*T<aa)
  85.          {
  86.                 if(K1==0||dd==1&&K3==1)
  87.                                 {ENA=1;
  88.                                 DIR=1;
  89.                                 dd=0;}
  90.                                 if(K2==0||ff==0)
  91.                                 {ENA=0;}
  92.                                 if(K3==0||dd==0&&K1==1)
  93.                                 {ENA=1;
  94.                                 DIR=0;
  95.                                 dd=1;}                                                               
  96.                                 if(timer1>20000/cc)
  97.                                 {
  98.                                         timer1=0; //输出占空比0.7的脉冲
  99.                                 }
  100.                                 if(timer1<10000/cc)
  101.                                 {
  102.                                         CP=0;
  103.                                 }
  104.                                 else
  105.                                 {
  106.                                         CP=1;
  107.                                 }
  108.                                 if(timer1<ee*5) //占空比可变的脉冲,控制电压
  109.                                 {CP1=1;}
  110.                                 else
  111.                                 {CP1=0;}
  112.                                 if(p1==0)
  113.                                  {c++;}       
  114.                                  }       
  115.          }                 
  116. }
  117. /*******************************************************************************
  118. * 函数名         : Usart() interrupt 4
  119. * 函数功能                  : 串口通信中断函数
  120. * 输入           : 无
  121. * 输出                  : 无
  122. *******************************************************************************/
  123. void Usart() interrupt 4
  124. {
  125.          while (!RI); //等待接收数据
  126.         receiveData[i]=SBUF;//出去接收到的数据
  127.          if(receiveData[i]=='A'         )
  128.         { i=0;
  129.          receiveData[0]='A';       
  130.         }
  131.         i++;
  132.         RI = 0;//清除接收中断标志位
  133. //if(i==18)
  134. //   {SBUF=c;//将接收到的数据放入到发送寄存器
  135. //        while(!TI);                         //等待发送数据完成
  136. //        TI=0;}                                                 //清除发送完成标志位
  137. }
  138. void T0zd() interrupt 1 //3 为定时器1的中断号; (1 定时器0的中断号; 0 外部中断1; 2 外部中断2; 4 串口中断),脉冲中断
  139. {       
  140.     TH0 =0XFF;
  141.     TL0 =0XCE;
  142.     timer1++; //计数+1
  143.         T++;//计周期
  144. }
xuyaqi 发表于 2017-5-25 14:05 | 显示全部楼层
串口中断里不能有这个“while (!RI); //等待接收数据”。
 楼主| fhyxihuan1314 发表于 2017-5-28 17:48 | 显示全部楼层
这两天又改了下,发现TMOD不一样,所以改了下TMOD设置,然后稍微变动了下,结果是用串口助手输入数据后,小灯过4秒左右才亮,而且步进电机也没动。。。。请问为啥啊,下面上代码
  1. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
  2. //#include<stdio.h>
  3. typedef unsigned int u16;         
  4. typedef unsigned char u8;
  5. unsigned char timer1;
  6. void timerint(void);
  7. int T;
  8. int c;
  9. int z;
  10. int i;
  11. double aa;double cc;double dd;double ee;         double ff;
  12. sbit DIR=P1^0; //换向DIR为P1.0口
  13. sbit ENA=P1^1; //使能ENA为P1.1口
  14. sbit CP=P1^2; //脉冲CP为P1.2口
  15. sbit K1=P1^3;//外部控制正转
  16. sbit K3=P1^4;//外部控制反转
  17. sbit K2=P1^5; //外部停止
  18. sbit CP1=P1^6; //控制电压脉冲为P1.6口
  19. sbit p1=P2^1;
  20. char receiveData[18];
  21.   sbit led=P2^2;
  22. /*******************************************************************************
  23. * 函数名         :UsartInit()
  24. * 函数功能                   :设置串口
  25. * 输入           : 无
  26. * 输出                  : 无
  27. *******************************************************************************/
  28. void UsartInit()
  29. {
  30.         SCON=0X50;                        //设置为工作方式1
  31.         TMOD=0X21;                        //设置计数器工作方式2
  32.         PCON=0X80;                        //波特率加倍
  33.         TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的
  34.         TL1=0XF3;
  35.         ES=1;                                                //打开接收中断
  36.         EA=1;                                                //打开总中断
  37.         TR1=1;                                        //打开计数器
  38. }
  39. void system_Ini()                 //T0
  40. {
  41.     TMOD=0X21;
  42.     TH0 =0XFF;                         //0.05ms定时
  43.     TL0 =0XCE;
  44.     EA = 1;
  45.     ET0 = 1;
  46.    
  47. }
  48. // void delay(u16 j)
  49. //{
  50. //        while(j--);       
  51. //}
  52. /*******************************************************************************
  53. * 函 数 名       : main
  54. * 函数功能                 : 主函数
  55. * 输    入       : 无
  56. * 输    出             : 无
  57. *******************************************************************************/
  58. void main()
  59. {       
  60.         IP=0X10;
  61.         UsartInit();  //        串口初始化
  62.         system_Ini();//初始化定时器T0        
  63.         ENA=0;
  64.         while(1)       
  65.          {
  66.         if(i>17)
  67.                     i=0;
  68.                 if(receiveData[0]=='A')
  69.                 {
  70.                  if(receiveData[1]<='0'||receiveData[1]>='9')
  71.                         {receiveData[1]='0';}
  72.                     if(receiveData[2]<='0'||receiveData[2]>='9')
  73.                         {receiveData[2]='0';}
  74.                         if(receiveData[3]<='0'||receiveData[3]>='9')
  75.                         {receiveData[3]='0';}
  76.                         aa=1000*(receiveData[1]-'0')+100*(receiveData[2]-'0')+10*(receiveData[3]-'0')+(receiveData[4]-'0');
  77.                         if(receiveData[6]<='0'||receiveData[6]>='9')
  78.                         {receiveData[6]='0';}
  79.                     if(receiveData[7]<='0'||receiveData[7]>='9')
  80.                         {receiveData[7]='0';}
  81.                         if(receiveData[8]<='0'||receiveData[8]>='9')
  82.                         {receiveData[8]='0';}
  83.                         cc=1000*(receiveData[6]-'0')+100*(receiveData[7]-'0')+10*(receiveData[8]-'0')+(receiveData[9]-'0');
  84.                    dd=receiveData[11]-'0';
  85.                    ee=(receiveData[13]-'0')+(receiveData[15]-'0')*0.1;
  86.                    ff=receiveData[17]-'0';         }
  87.         T=0;
  88.         if(aa==1000&&cc==1000&&dd==1&&ee==1.2&&ff==1)//灯作为测试用       
  89.         {
  90.            led=1;
  91.         }
  92.         else
  93.         {led=0;}                                                               
  94.                   if(20000*T/cc<=aa)
  95.                  {
  96.                         if(dd==1)
  97.                                 {ENA=1;
  98.                                 DIR=1;
  99.                                  TR0 = 1;}
  100.                                 if(K2==0||ff==0)
  101.                                 {ENA=0;}
  102.                                 if(dd==0)
  103.                                 {ENA=1;
  104.                                 DIR=0;
  105.                                  TR0 = 1;}                                                               
  106.                                 if(timer1>20000/cc)
  107.                                 {
  108.                                         timer1=0; //输出占空比0.7的脉冲
  109.                                 }
  110.                                 if(timer1<10000/cc)
  111.                                 {
  112.                                         CP=0;
  113.                                 }
  114.                                 else
  115.                                 {
  116.                                         CP=1;
  117.                                 }
  118.                                 if(timer1<ee*10000/cc) //占空比可变的脉冲,控制电压
  119.                                 {CP1=1;}
  120.                                 else
  121.                                 {CP1=0;}
  122.                                 if(p1==0)
  123.                                  {c++;}       
  124.                 }
  125.                         else
  126.                         {TR0=0;
  127.                         T=0;}//计周期       
  128.          }                 
  129. }
  130. /*******************************************************************************
  131. * 函数名         : Usart() interrupt 4
  132. * 函数功能                  : 串口通信中断函数
  133. * 输入           : 无
  134. * 输出                  : 无
  135. *******************************************************************************/
  136. void Usart() interrupt 4
  137. {
  138.          while (!RI); //等待接收数据
  139.         receiveData[i]=SBUF;//出去接收到的数据
  140.          if(receiveData[i]=='A'         )
  141.         { i=0;
  142.          receiveData[0]='A';       
  143.         }
  144.         i++;
  145.         RI = 0;//清除接收中断标志位
  146. //if(i==18)
  147. //   {SBUF=c;//将接收到的数据放入到发送寄存器
  148. //        while(!TI);                         //等待发送数据完成
  149. //        TI=0;}                                                 //清除发送完成标志位
  150. }
  151. void T0zd() interrupt 1 // 1 定时器0的中断号; 0 外部中断1; 2 外部中断2; 4 串口中断),脉冲中断
  152. {       
  153.     TH0 =0XFF;
  154.     TL0 =0XCE;
  155.     timer1++; //计数+1
  156.         if(20000*T/cc<=aa)
  157.         {T++;}       
  158. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

7

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部