找回密码
 立即注册

QQ登录

只需一步,快速开始

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

Proteus仿真步进电机 数码管+1602 有仿真图和单片机源码

[复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. /*  步进电机程序              */
  2. /*P1^0 为四相单四拍, P1^1 为四相双四拍, P1^2 为四相八拍  */
  3. /*P1^3 为启动 / 停止控制、 P1^4 方向控制、 P1^5 加速、 P1^6 减速  */
  4. /* 用 4 位 LED 数码管显示工作步数。                */
  5. /* 用 3 个发光二极管显示状态  */
  6. /* 正转时红灯亮,反转时黄灯亮,不转时绿灯亮      */
  7. /* 编写人:  */
  8. /* 时间: 2013-06-26 */
  9. /***********************************************************/
  10. #include<reg51.h>
  11. #define uchar unsigned char
  12. #define uint unsigned int
  13. #define SegData P0        // 数码管数据口
  14. #define KeyData P1        // 按键控制数据口
  15. #define MotorData P2        // 电机控制数据口
  16. #define dula P0     //段选
  17. sbit wela1=P3^0; // 数码管位选 1
  18. sbit wela2=P3^1; // 数码管位选 2
  19. sbit wela3=P3^3; // 数码管位选 3
  20. sbit wela4=P3^7; // 数码管位选 4
  21. sbit wela5=P2^4; // 数码管位选 5
  22. sbit wela6=P2^5; // 数码管位选 6
  23. sbit wela7=P2^6; // 数码管位选 7
  24. sbit wela8=P2^7; // 数码管位选 8
  25. sbit RS=P2^6;
  26. sbit RW=P2^5;
  27. sbit E=P2^7;
  28. #define LCD_data  P0     
  29. uchar   code  table2[13]={"RAOZU:Y90S-2"};
  30. uchar   code  table3[25]={"DZ:0X200 ZS:75"};
  31. sbit LedGreen=P3^4;// 控制绿灯-停止
  32. sbit LedRed=P3^5;  // 控制红灯-停止
  33. sbit LedYellow=P3^6;// 控制黄灯-停止
  34. uchar PositiveSingleFour[]={0xf1,0xf4,0xf2,0xf8}; // 步进电机正相单四拍数表 ;
  35. uchar PositiveDoubleFour[]={0xf5,0xf6,0xfa,0xf9}; // 步进电机正相双四拍数表 ;
  36. uchar PositiveEight[]={0xf1,0xf5,0xf4,0xf6,0xf2,0xfa,0xf8,0xf9};// 步进电机正相八拍数表 ;
  37. uchar NegitiveSingleFour[]={0xf1,0xf8,0xf2,0xf4}; // 步进电机反相单四拍数表 ;
  38. uchar NegitiveDoubleFour[]={0xf9,0xfa,0xf6,0xf5}; // 步进电机反相双四拍数表 ;
  39. uchar NegitiveEight[]={0xf1,0xf9,0xf8,0xfa,0xf2,0xf6,0xf4,0xf5};// 步进电机反相八拍数表 ;
  40. uchar table[]={   
  41. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  42. 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
  43. 0x40,0x76,0x38};//数码管显示
  44. uchar Flag=0; // 用来控制拍数循环;  
  45. uchar Mode=0; // 用来标志工作模式;
  46. uchar Way=0; // 用来标志运转方向
  47. uchar Num=0; // 用来定时计数
  48. uchar Delay=0; // 用来标志延时时间到
  49. uchar Move=0; // 用来标志启动或停止
  50. uint Step=0; // 用来计算步数的;
  51. char Speed=12;  // 用来表示速度
  52. char SpeedMax=2; // 最大速度 - 参数为时间
  53. char SpeedMin=22; // 最小速度
  54. char SpeedChang=1; // 速度每次改变量
  55. uint Pulse=0;  //计数
  56. uint Period=0 ; //周期计数
  57. uint real_speed=0;  //实际转速
  58. uint lilun_speed=0;  //理论转速
  59. /****************** 函数声明部分 **********************/
  60. void Init();
  61. //void Display(uint);
  62. void DelayMs(uint);
  63. void KeyScan();
  64. void Motor();
  65. void display(uint first,uint second,uint third,uint forth);
  66. void display2(uint first,uint second,uint third,uint forth);
  67. /****************** 主函数 **********************/
  68. /********************************/
  69. void delay_us(); //18us
  70. void delay_ms(uint);
  71. void lcd_init();
  72. void lcd_write_com(uchar com);
  73. void lcd_write_dat(uchar dat);
  74. void lcd_init();
  75. void lcd_display(uchar add,uchar dat);
  76. /***********************************/
  77. void delay_us()
  78. {
  79. uchar x;
  80. for(x=0;x<5;x++);
  81. }
  82. void delay_ms(uint z)
  83. {
  84. uint x,y;
  85. for(x=0;x<z;x++)
  86.   for(y=0;y<123;y++);
  87. }
  88. void lcd_write_com(uchar com)
  89. {
  90.   E=0;
  91.   RS=0;
  92.   RW=0;
  93.   delay_us();
  94.   LCD_data=com;
  95.   E=1;    //高脉冲写入数据
  96.   delay_us();
  97.   E=0;
  98. }
  99. void lcd_write_dat(uchar dat)
  100. {
  101.   E=0;
  102.   RS=1;
  103.   RW=0;
  104.   delay_us();
  105.   LCD_data=dat;
  106.   E=1;    //高脉冲写入数据
  107.   delay_us();
  108.   E=0;
  109. }
  110. void lcd_init()    //lcd初始化
  111. {
  112. delay_ms(15);
  113. lcd_write_com(0x38);
  114. delay_ms(10);
  115. lcd_write_com(0x0c);
  116. lcd_write_com(0x06);
  117. lcd_write_com(0x01);
  118. delay_ms(2);


  119. }
  120. void lcd_display(uchar add,uchar dat)    //lcd显示(地址,数据)
  121. {
  122. lcd_write_com(add);

  123. lcd_write_dat(dat);
  124. delay_us();
  125. }
  126. void main()
  127. {
  128. char i;
  129.   lcd_init();
  130. for(i=0;i<12;i++)
  131. {
  132.   lcd_display(0x80+i,table2[i]);
  133. }
  134. for(i=0;i<14;i++)
  135. {
  136.   lcd_display(0x80+0x40+i,table3[i]);
  137. }
  138.    Init();
  139. while(1)
  140. {
  141.    KeyScan();
  142.    Motor();
  143.   // display(real_speed/1000,real_speed%1000/100,real_speed%100/10,real_speed%10) ;
  144.    display(lilun_speed/1000,lilun_speed%1000/100,lilun_speed%100/10,lilun_speed%10) ;
  145. }
  146. }
  147. //显示函数
  148. void display(uint first,uint second,uint third,uint forth)   
  149. {
  150.   wela1 = 0;
  151. dula = table[first];   //显示第一个
  152. DelayMs(1);
  153. wela1 = 1;
  154. dula = 0x00;    //一定要加,否则不稳定
  155. wela2 = 0;
  156. dula = table[second];  //显示第二个
  157. DelayMs(1);
  158. wela2 = 1;
  159. dula = 0x00;
  160. wela3 = 0;
  161. dula = table[third];  //显示第三个
  162. DelayMs(1);
  163. wela3 = 1;
  164. dula = 0x00;
  165. wela4 = 0;
  166. dula = table[forth];   //显示第4个
  167. DelayMs(1);
  168. wela4 = 1;
  169. dula = 0x00;
  170. }
  171.   //显示函数
  172. void display2(uint first,uint second,uint third,uint forth)   
  173. {
  174.     wela5 = 0;
  175. dula = table[first];   //显示第一个
  176. DelayMs(1);
  177. wela5 = 1;
  178. dula = 0x00;    //一定要加,否则不稳定
  179. wela6 = 0;
  180. dula = table[second];  //显示第二个
  181. DelayMs(1);
  182. wela6 = 1;
  183. dula = 0x00;
  184. wela7 = 0;
  185. dula = table[third];  //显示第三个
  186. DelayMs(1);
  187. wela7 = 1;
  188. dula = 0x00;
  189. wela8 = 0;
  190. dula = table[forth];   //显示第4个
  191. DelayMs(1);
  192. wela8 = 1;
  193. dula = 0x00;
  194. }
  195. /****************** 电机运转函数 **********************/
  196. void Motor()
  197. {
  198. if(Move==1)
  199. {
  200.      LedGreen=0;
  201.    if(Delay==1)
  202.    {
  203.      Delay=0;
  204.      if(Way==0)
  205.      {
  206.       LedRed=0;
  207.     LedYellow=1;
  208.        switch(Mode)
  209.        {
  210.            /* 电机步进拍数表数据送到电机控制口;判断一周拍数是否完成;步数加 1*/
  211.          case 1:MotorData=PositiveSingleFour[Flag++];if(Flag>=4) Flag=0;Step++;break;
  212.          case 2:MotorData=PositiveDoubleFour[Flag++];if(Flag>=4) Flag=0;Step++;break;
  213.          case 3:MotorData=PositiveEight[Flag++];if(Flag>=8) Flag=0;Step++;break;
  214.          default:  ;
  215.        }
  216.      }
  217.      else
  218.      {
  219.      LedRed=1;
  220.     LedYellow=0;
  221.        switch(Mode)
  222.        {
  223.          case 1:MotorData=NegitiveSingleFour[Flag++];if(Flag>=4) Flag=0;Step++;break;
  224.          case 2:MotorData=NegitiveDoubleFour[Flag++];if(Flag>=4) Flag=0;Step++;break;
  225.          case 3:MotorData=NegitiveEight[Flag++];if(Flag>=8) Flag=0;Step++;break;
  226.          default:  ;
  227.        }
  228.      }
  229.    }
  230. }
  231. else
  232. {
  233.    MotorData=0xef;
  234.    LedGreen=1;
  235. }
  236. }
  237. /****************** 初始化函数 **********************/
  238. void Init()
  239. {
  240. Move=0;
  241. LedGreen=1;
  242. Step=0;
  243. MotorData=0xef;
  244. IT0=1;//跳变沿出发方式(下降沿)
  245. EX0=1;//打开INT0的中断允许。
  246. EA=1;//打开总中断  
  247. TMOD=0x11;        // 定时器 0 初始化
  248. TH0=(65536-2000)/256;
  249. TL0=(65536-2000)%256;
  250. EA=1;          // 开总中断
  251. ET0=1;          // 开定时器 0 中断
  252. TR0=1;          // 开始计时
  253. }
  254. /****************** 按键检测函数 **********************/
  255. void KeyScan()
  256. {
  257. uchar Temp,Over=0;
  258. Temp=KeyData;
  259. Temp=Temp&0x08;
  260.   if(Temp!=0x08)   // 启动键按下
  261. {
  262.     Move=1;
  263.    Temp=KeyData;
  264.    Temp=Temp&0x60;
  265.    if(Temp!=0x60)
  266.    {
  267.       DelayMs(2);          // 按键软件消抖
  268.       Temp=KeyData;
  269.      Temp=Temp&0x60;
  270.      if(Temp!=0x60)
  271.      {  
  272.         Over=1;        // 有键按下则不扫描后续按键
  273.         if(Temp==0x40)    // 加速键按下
  274.        {
  275.           while(Temp!=0xe7)  // 按键松开检测
  276.          {
  277.            Temp=KeyData;
  278.            Temp=Temp&0xe7;
  279.          }
  280.          Speed=Speed-SpeedChang;   
  281.          if(Speed<=SpeedMax)
  282.          {
  283.             Speed=SpeedMax;  // 一直按加速键则保持到最大速度
  284.          }
  285.        }
  286.         else if(Temp==0x20)          // 减速键按下
  287.        {  
  288.           while(Temp!=0xe7)
  289.          {
  290.            Temp=KeyData;
  291.            Temp=Temp&0xe7;
  292.          }
  293.          Speed=Speed+SpeedChang;
  294.          if(Speed>=SpeedMin)
  295.          {
  296.            Speed=SpeedMin;
  297.          }
  298.        }
  299.      }
  300.    }
  301.     if(Over==0)              // 判断前是否有键按下
  302.    {
  303.       Temp=KeyData;
  304.      Temp=Temp&0x10;
  305.      if(Temp!=0x10)
  306.      {
  307.        DelayMs(2);
  308.        Temp=KeyData;
  309.        Temp=Temp&0x10;
  310.        if(Temp!=0x10)
  311.        {
  312.           Way=0;          // 方向按键按下,电机顺时针转动
  313.        }
  314.      }
  315.       else
  316.      {
  317.        Way=1;
  318.      }
  319.    }
  320.    if(Over==0)
  321.    {
  322.      Temp=KeyData;
  323.      Temp=Temp&0x07;
  324.      if(Temp!=0x07)
  325.      {
  326.        DelayMs(2);
  327.        Temp=KeyData;
  328.        Temp=Temp&0x07;
  329.        if(Temp!=0x07)
  330.        {
  331.          switch(Temp)
  332.          {
  333.             case 0x06:  Mode=1;break;// 电机四相单四拍运行
  334.             case 0x05:  Mode=2;break;// 电机四相双四拍运行
  335.             case 0x03:  Mode=3;break;// 电机四相八拍运行
  336.          }
  337.        }
  338.      }
  339.    }
  340. }
  341.   else
  342. {
  343.     Move=0;              // 电机停止
  344. }
  345. }
  346. /**************** 毫秒延时 ***************/
  347. void DelayMs(uint z)
  348. {
  349. uint t1,y;
  350. for(t1=z;t1>0;t1--)
  351.    for(y=110;y>0;y--);
  352. }
  353. /**************** 定时器 0 中断函数 ***************/
  354. void T0_time() interrupt 1
  355. {
  356. // TH0=(65536-45872)/256;
  357. // TL0=(65536-45872)%256;
  358. TH0=(65536-2000)/256;
  359. TL0=(65536-2000)%256;
  360. Num++;
  361. Period++;
  362. if(Num>=Speed)
  363. {
  364.     Num=0;
  365.     Delay=1;      // 延时时间到
  366. }
  367.   if(Period >= 500)
  368.   {  
  369.     real_speed=Pulse*60;   //实际转速
  370.     lilun_speed =Step*15;  //理论转速
  371. Step=0;
  372.     Pulse=0;
  373. Period=0;
  374.   }
  375. }
  376. /*外部中断0的中断函数*/
  377. void Int0()        interrupt 0               
  378. {
  379.   Pulse++;//脉冲++
  380. }
复制代码
全部资料51hei下载地址:
步进电机1602 数码管.rar (155.69 KB, 下载次数: 86)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:143767 发表于 2020-10-23 19:40 | 只看该作者
仿真看了一下1602显示的数据没有任何变化,无论按哪个按键1602都无任何变化,不知为何?楼主能否告诉是什么原因,谢谢!
回复

使用道具 举报

板凳
ID:143767 发表于 2020-10-30 16:26 | 只看该作者
帖子都沉了也没人回答
回复

使用道具 举报

地板
ID:675166 发表于 2020-11-9 10:04 | 只看该作者

仿真看了一下1602显示的数据没有任何变化,无论按哪个按键1602都无任何变化,不知为何?楼主能否告诉是什么原因,谢谢!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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