找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机步进电机定圈转动,正反转,速率内部可调 源程序

[复制链接]
跳转到指定楼层
楼主
步进电机定圈转动,正反转,速率内部可调



单片机源程序如下:
  1. /*-----------------------------------------------
  2.   名称:步进电机
  3.   内容:本程序用于测试4相步进电机常规驱动
  4.         使用1-2相励磁
  5.         1-2相激励功率增倍,步进角度减半,抖动减少
  6.         顺序如下 a-b-c-d  
  7. ------------------------------------------------*/
  8. #include <reg52.h>
  9. #include<intrins.h>
  10. #include<stdio.h>
  11. #include<string.h>
  12. sbit RS = P2^4;   //定义端口
  13. sbit RW = P2^5;
  14. sbit EN = P2^6;
  15. sbit A1=P1^0; //定义步进电机连接端口
  16. sbit B1=P1^1;
  17. sbit C1=P1^2;
  18. sbit D1=P1^3;
  19. #define RS_CLR RS=0
  20. #define RS_SET RS=1
  21. #define RW_CLR RW=0
  22. #define RW_SET RW=1
  23. #define EN_CLR EN=0
  24. #define EN_SET EN=1
  25. #define DataPort P0
  26. #define KeyPort P3
  27. #define Coil_AB1 {A1=1;B1=1;C1=0;D1=0;}//AB相通电,其他相断电
  28. #define Coil_BC1 {A1=0;B1=1;C1=1;D1=0;}//BC相通电,其他相断电
  29. #define Coil_CD1 {A1=0;B1=0;C1=1;D1=1;}//CD相通电,其他相断电
  30. #define Coil_DA1 {A1=1;B1=0;C1=0;D1=1;}//D相通电,其他相断电
  31. #define Coil_A1 {A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电
  32. #define Coil_B1 {A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电
  33. #define Coil_C1 {A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电
  34. #define Coil_D1 {A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电
  35. #define Coil_OFF {A1=0;B1=0;C1=0;D1=0;}//全部断电
  36. unsigned char count;
  37. unsigned char Speed;//正转速度
  38. unsigned char Speed1;//反转速度
  39. bit Flag;
  40. unsigned char code dofly_code[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//转换成液晶显示的字符

  41. /*------------------------------------------------
  42. uS延时函数,含有输入参数 unsigned char t,无返回值
  43. unsigned char 是定义无符号字符变量,其值的范围是
  44. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  45. 长度如下 T=tx2+5 uS
  46. ------------------------------------------------*/
  47. void DelayUs2x(unsigned char t)
  48. {   
  49. while(--t);
  50. }
  51. /*------------------------------------------------
  52. mS延时函数,含有输入参数 unsigned char t,无返回值
  53. unsigned char 是定义无符号字符变量,其值的范围是
  54. 0~255 这里使用晶振12M,精确延时请使用汇编
  55. ------------------------------------------------*/
  56. void DelayMs(unsigned char t)
  57. {
  58.      
  59. while(t--)
  60. {
  61.      //大致延时1mS
  62.      DelayUs2x(245);
  63.          DelayUs2x(245);
  64. }
  65. }
  66. /*------------------------------------------------
  67.               判忙函数
  68. ------------------------------------------------*/
  69. bit LCD_Check_Busy(void)
  70. {
  71. DataPort= 0xFF;
  72. RS_CLR;
  73. RW_SET;
  74. EN_CLR;
  75. _nop_();
  76. EN_SET;
  77. return (bit)(DataPort & 0x80);
  78. }
  79. /*------------------------------------------------
  80.               写入命令函数
  81. ------------------------------------------------*/
  82. void LCD_Write_Com(unsigned char com)
  83. {  
  84. // while(LCD_Check_Busy()); //忙则等待
  85. DelayMs(5);
  86. RS_CLR;
  87. RW_CLR;
  88. EN_SET;
  89. DataPort=com;
  90. _nop_();
  91. EN_CLR;
  92. }
  93. /*------------------------------------------------
  94.               写入数据函数
  95. ------------------------------------------------*/
  96. void LCD_Write_Data(unsigned char Data)
  97. {
  98. //while(LCD_Check_Busy()); //忙则等待
  99. DelayMs(5);
  100. RS_SET;
  101. RW_CLR;
  102. EN_SET;
  103. DataPort= Data;
  104. _nop_();
  105. EN_CLR;
  106. }


  107. /*------------------------------------------------
  108.                 清屏函数
  109. ------------------------------------------------*/
  110. void LCD_Clear(void)
  111. {
  112. LCD_Write_Com(0x01);
  113. DelayMs(5);
  114. }
  115. /*------------------------------------------------
  116.               写入字符串函数
  117. ------------------------------------------------*/
  118. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  119. {     
  120. if (y == 0)
  121.         {     
  122.          LCD_Write_Com(0x80 + x);     
  123.         }
  124. else
  125.         {     
  126.         LCD_Write_Com(0xC0 + x);     
  127.         }        
  128. while (*s)
  129.         {     
  130. LCD_Write_Data( *s);     
  131. s ++;     
  132.         }
  133. }
  134. /*------------------------------------------------
  135.               写入字符函数
  136. ------------------------------------------------*/
  137. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  138. {     
  139. if (y == 0)
  140.         {     
  141.         LCD_Write_Com(0x80 + x);     
  142.         }   
  143. else
  144.         {     
  145.         LCD_Write_Com(0xC0 + x);     
  146.         }        
  147. LCD_Write_Data( Data);  
  148. }
  149. /*------------------------------------------------
  150.               初始化函数
  151. ------------------------------------------------*/
  152. void LCD_Init(void)
  153. {
  154.    LCD_Write_Com(0x38);    /*显示模式设置*/
  155.    DelayMs(5);
  156.    LCD_Write_Com(0x38);
  157.    DelayMs(5);
  158.    LCD_Write_Com(0x38);
  159.    DelayMs(5);
  160.    LCD_Write_Com(0x38);  
  161.    LCD_Write_Com(0x08);    /*显示关闭*/
  162.    LCD_Write_Com(0x01);    /*显示清屏*/
  163.    LCD_Write_Com(0x06);    /*显示光标移动设置*/
  164.    DelayMs(5);
  165.    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  166.    }

  167. /*------------------------------------------------
  168. 按键扫描函数,返回扫描键值
  169. ------------------------------------------------*/
  170. unsigned char KeyScan(void)  //键盘扫描函数,使用行列反转扫描法
  171. {
  172. unsigned char cord_h,cord_l;//行列值中间变量
  173. KeyPort=0x0f;            //行线输出全为0
  174. cord_h=KeyPort&0x0f;     //读入列线值
  175. if(cord_h!=0x0f)    //先检测有无按键按下
  176. {
  177.   DelayMs(10);        //去抖
  178.   if((KeyPort&0x0f)!=0x0f)
  179.   {
  180.     cord_h=KeyPort&0x0f;  //读入列线值
  181.     KeyPort=cord_h|0xf0;  //输出当前列线值
  182.     cord_l=KeyPort&0xf0;  //读入行线值

  183.     while((KeyPort&0xf0)!=0xf0);//等待松开并输出

  184.     return(cord_h+cord_l);//键盘最后组合码值
  185.    }
  186.   }return(0xff);     //返回该值
  187. }
  188. ///*------------------------------------------------
  189. //          按键值处理函数,返回扫键值
  190. //           可以根据需要改变返回值

  191. //                          | 1 | 2 | 3 | A |  
  192. //                          | 4 | 5 | 6 | B |  
  193. //                          | 7 | 8 | 9 | C |  
  194. //                          | * | 0 | # | D |
  195. //------------------------------------------------*/

  196. unsigned char KeyPro(void)
  197. {
  198. switch(KeyScan())
  199. {
  200.   case 0x7e:return 10;break;//0 按下相应的键显示相对应的码值
  201.   case 0x7d:return 11;break;//1
  202.   case 0x7b:return 12;break;//2
  203.   case 0x77:return 13;break;//3
  204.   case 0xbe:return 3;break;//4
  205.   case 0xbd:return 6;break;//5
  206.   case 0xbb:return 9;break;//6
  207.   case 0xb7:return 14;break;//7
  208.   case 0xde:return 2;break;//8
  209.   case 0xdd:return 5;break;//9
  210.   case 0xdb:return 8;break;//a
  211.   case 0xd7:return 0;break;//b
  212.   case 0xee:return 1;break;//c
  213.   case 0xed:return 4;break;//d
  214.   case 0xeb:return 7;break;//e
  215.   case 0xe7:return 15;break;//f
  216.   default:return 0xff;break;
  217. }
  218. }
  219. /*------------------------------------------------
  220.                     主函数
  221. ------------------------------------------------*/
  222. main()
  223. {
  224.         unsigned int m=50;//旋转一周时间
  225.         unsigned int k,p,i;
  226.         unsigned char num;
  227.         unsigned char temp[8];
  228.         Speed=2;//正转速度       
  229.         Speed1=2;//反转速度

  230.        
  231.         LCD_Init();
  232.   LCD_Write_Com(0x0F);//光标开,光标闪烁开
  233.   LCD_Write_String(0,0,"Press the key   ");
  234.         LCD_Write_String(0,1,"*=zheng or #=fan ");
  235.        
  236.         Coil_OFF
  237.         i=0;
  238.         while(1)
  239.         {
  240.                
  241.                 Coil_OFF
  242.                 num=KeyPro();  
  243.                
  244.                 while(num!=10)
  245.                                         {
  246.                                                 Speed++;
  247.                                                 LCD_Clear();
  248.                                          LCD_print("U=            mV");
  249.                                           sprintf(Speed,"%3f",num);
  250.                                                
  251.                                         }
  252.                                        
  253.                         if(num==15)
  254.                         {
  255.                                 DelayMs(10);
  256.                                 if(num==15)
  257.                                 {                                 
  258. //                                         LCD_Write_String(0,1,"Speed=         ");
  259. //                             sprintf(1,"%1d",1);  
  260.           LCD_Clear();
  261.                                         LCD_Write_String(0,0,"Zheng Zhuan:");
  262.                                         while(num!=14)
  263.                                         {
  264.                                                 num=KeyPro();
  265.                                                 if(num!=0xff)//如果扫描是按键有效值则进行处理
  266.                                                         {
  267.                                                                 if((num==10)||(num==11)||(num==12)||(num==13)||(num==14)||(num==15))
  268.                                                                 {
  269.                                                                         LCD_Write_String(0,1,"ERR,enter * or #");
  270.                                                                         DelayMs(4000);
  271.                                                                         DelayMs(4000);
  272.                                                                         DelayMs(4000);
  273.                                                                         DelayMs(4000);
  274.                                                                         DelayMs(4000);
  275.                                                                         DelayMs(4000);
  276.                                                                         DelayMs(4000);
  277.                                                                         DelayMs(4000);
  278.                                                                         DelayMs(4000);
  279.                                                                         LCD_Write_String(0,1,"                ");
  280.                                                                         i=0;
  281.                                                                         break;
  282.                                                                 }
  283.                                                                
  284.                                                                 if(i==0)   
  285.                                                                         LCD_Write_String(0,1,"                ");//清除该行               
  286.                                                                 if(i<2)     //密码是8位,大于8位时不再输入按键值
  287.                                                                         {//num=KeyPro();
  288.                                                                                 if(num==10)
  289.                                                                         Speed++;
  290.                                                                                 temp[i]=num;
  291.                                                                                 LCD_Write_Char(i,1,num+'0');
  292.                                                                         }
  293.                                                                         i++;
  294.                                                                         if(i==2)//8位后的按键不输入数值,相当于确认按键(任意按键即可)
  295.                                                                                 {
  296.                                                                                         LCD_Write_String(0,1,"waiting");
  297.                                                                                         i=0;  //计数器复位
  298.                                                                                         p=(temp[0]*512/*+temp[1]*100+temp[2]*10+temp[3]*/);/*****************************************************/
  299.                                                                                         for(k=0;k<p;k++)
  300.                                                                                         {          
  301.                                                                                                
  302.                                                                                                 Coil_A1      
  303.                                                                                                 DelayMs(Speed);     //遇到Coil_AB1  用{A1=1;B1=1;C1=0;D1=0;}代替
  304.                                                             //改变这个参数可以调整电机转速 ,
  305.                               //数字越小,转速越大,力矩越小
  306.                                                                                                 Coil_B1      
  307.                                                                                                 DelayMs(Speed);
  308.                                                                                                 Coil_C1      
  309.                                                                                                 DelayMs(Speed);
  310.                                                                                                 Coil_D1      
  311.                                                                                                 DelayMs(Speed);
  312.                                                                                         }
  313.                                                                                         p=0;
  314.                                                                                         LCD_Write_String(0,1,"                ");
  315.                                                                                 }
  316.                                                         }
  317.                                         }
  318.                                         i=0;
  319.                                 }
  320.                         }
  321.                         if(num==14)
  322.                         {
  323.                                 DelayMs(10);
  324.                                 if(num==14)
  325.                                 {
  326.                                         LCD_Clear();
  327.                                         LCD_Write_String(0,0,"Fan Zhuan:");
  328.                                         while(num!=15)
  329.                                         {
  330.                                                 num=KeyPro();
  331.                                                 if(num!=0xff)  //如果扫描是按键有效值则进行处理
  332.                                                         {
  333.                                                                 if((num==10)||(num==11)||(num==12)||(num==13)||(num==15)||(num==14))
  334.                                                                 {
  335.                                                                         LCD_Write_String(0,1,"ERR,enter * or #");
  336.                                                                         DelayMs(4000);
  337.                                                                         DelayMs(4000);
  338.                                                                         DelayMs(4000);
  339.                                                                         DelayMs(4000);
  340.                                                                         DelayMs(4000);
  341.                                                                         DelayMs(4000);
  342.                                                                         DelayMs(4000);
  343.                                                                         DelayMs(4000);
  344.                                                                         DelayMs(4000);
  345.                                                                         LCD_Write_String(0,1,"                ");
  346.                                                                         i=0;
  347.                                                                         break;
  348.                                                                 }
  349.                                                                 if(i==0)    //输入是第一个字符的时候需要把改行清空,方便观看密码
  350.                                                                         LCD_Write_String(0,1,"                ");//清除该行               
  351.                                                                 if(i<2)     //密码是8位,大于8位时不再输入按键值
  352.                                                                         {
  353.                                                                                 temp[i]=num;
  354.                                                                                 LCD_Write_Char(i,1,num+'0');
  355.                                                                         }
  356.                                                                         i++;
  357.                                                                         if(i==2)//8位后的按键不输入数值,相当于确认按键(任意按键即可)
  358.                                                                                 {
  359.                                                                                         LCD_Write_String(0,1,"waiting");
  360.                                                                                         i=0;  //计数器复位
  361.                                                                                         p=(temp[0]*512/*+temp[1]*10+temp[2]*/);/*****************************************************************/
  362.                                                                                         for(k=0;k<p;k++)
  363.                                                                                         {          
  364.                                                                                                 Coil_A1      
  365.                                                                                                 DelayMs(Speed1);     //遇到Coil_AB1  用{A1=1;B1=1;C1=0;D1=0;}代替
  366.                                                                            //改变这个参数可以调整电机转速 ,
  367.                                              //数字越小,转速越大,力矩越小
  368.                                                                                                 Coil_D1      
  369.                                                                                                 DelayMs(Speed1);
  370.                                                                                                 Coil_C1      
  371.                                                                                                 DelayMs(Speed1);
  372.                                                                                                 Coil_B1      
  373.                                                                                                 DelayMs(Speed1);
  374.                                                                                         }
  375.                                                                                         p=0;       
  376.                                                                                         LCD_Write_String(0,1,"                ");                                                                                       
  377.                                                                                 }
  378.                                                         }
  379.                                         }
  380.                                         i=0;
  381.                                 }
  382.                         }
  383.         }

  384. }
复制代码

以上51hei提供下载:
步进电机LED显示按键控制转动圈数,速度程序内部可调.zip (36.7 KB, 下载次数: 76)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:811317 发表于 2020-9-18 16:37 | 只看该作者
////**************单片机开发板对应按键      杜邦线反接***************//
//        case 0x7e:return 1;break;//1 按下相应的键显示相对应的码值  按一次输入值0-9,按两次确定
//  case 0x7d:return 2;break;//2
//  case 0x7b:return 3;break;//3
//  case 0x77:return 15;break;//zheng zhuan
//  case 0xbe:return 4;break;//4
//  case 0xbd:return 5;break;//5
//  case 0xbb:return 6;break;//6
//  case 0xb7:return 14;break;//fan zhuan
//  case 0xde:return 7;break;//7
//  case 0xdd:return 8;break;//8
//  case 0xdb:return 9;break;//9
//  case 0xd7:return 10;break;//x
//  case 0xee:return 0;break;//0
//  case 0xed:return 11;break;//.
//  case 0xeb:return 12;break;//=
//  case 0xe7:return 13;break;//  /
//  default:return 0xff;break;
回复

使用道具 举报

板凳
ID:624831 发表于 2021-4-27 09:51 来自手机 | 只看该作者
15936083907 发表于 2020-9-18 16:37
////**************单片机开发板对应按键      杜邦线反接***************//
//        case 0x7e:return 1;break ...

楼主有求原理图
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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