找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 48935|回复: 23
收起左侧

用51单片机控制步进电机运动详解

  [复制链接]
ID:381462 发表于 2018-7-31 22:19 | 显示全部楼层 |阅读模式
本来接触单片机挺久了的,但是一直只是停留在非常初级的认识阶段,本科的时候上过几门课,但是从来没有自己捣鼓过单片机,这次突然来了兴趣,感觉一下子学到了好多东西,在这里好好整理一下。这篇文章只适合于入门阶段的小白阅读,高手请绕道。
12年年初的时候购买了一套普中科技的“单片机开发试验仪”,好多次想好好学学,结果每一次都半途而废,主要原因还是周围的人都不会用,有问题都不知道找谁问,结果锁到箱子里一直到现在。因为最近需要用到一个步进电机,而这个步进电机需要用PWM波控制。以前也用过电机,直流无刷的、交流伺服等等,但是都是RS232、RS485或者Can总线协议,从来没有用PWM波控制过。废话不多说,直接入正题。
硬件单片机型号:STC90C516RD+
步进电机型号:39HS4012A4 1.8° 1.2A
1.jpg
步进电机驱动器型号:M415B 1.5A
2.jpg
代码源代码
  1. #include <reg52.h>

  2. unsigned char timer1;
  3. sbit DIR=P1^0; //位定义DIR为P1.0口
  4. sbit ENA=P1^1; //位定义ENA为P1.1口
  5. sbit PWM=P1^2; //位定义PWM为P1.2口

  6. void system_Ini()
  7. {
  8.     TMOD|= 0x11;
  9.     TH1 = 0xfe; //11.0592MHz 0.5ms定时
  10.     TL1 = 0x33;
  11.     TR1 = 1; //启动T1定时
  12.     IE =0x8A; //开T0,T1中断,开总中断
  13. }

  14. main()
  15. {
  16.     system_Ini(); //调用子函数,初始化定时器T1
  17.     while(1)
  18.     {
  19.         if(timer1>100)
  20.         {
  21.             timer1=0; //输出占空比0.7的PWM脉冲
  22.         }
  23.         if(timer1<30)
  24.         {
  25.             PWM=0;
  26.         }
  27.         else
  28.         {
  29.             PWM=1;
  30.         }
  31.     }
  32. }

  33. /*************************************
  34. [ t1 (0.5ms)中断] 中断中做 PWM 输出
  35. ------------1000/(0.02ms*250)=200Hz
  36. *************************************/
  37. void T1zd(void) interrupt 3 //3 为定时器1的中断号 1 定时器0的中断号 0 外部中断1 2 外部中断2 4 串口中断
  38. {
  39.     TH1 = 0xfe; //11.0592 初始化定时器
  40.     TL1 = 0x33;
  41.     timer1++; //计数+1
  42. }
复制代码
  1. #include <reg52.h> //包含了单片机系统的头文件
  2. unsigned char timer1; //定义一个无符号字符常量timer1,用来给定时器计数用

  3. sbit DIR=P1^0; //位定义DIR为P1.0口,用来控制步进电机的方向
  4. sbit ENA=P1^1; //位定义ENA为P1.1口,用来控制步进电机的使能
  5. sbit PWM=P1^2; //位定义PWM为P1.1口,用来输出PWM波

  6. TMOD = 0x11;
  7. //这一句代码比较费解,因为对单片机的控制字不熟悉,仔细翻看了单片机的手册,原来这是控制定时器的,共有两位,前一位控制定时器1,后一位控制定时器0。因为控制只使用了一个定时器1,所以其实定时器0所在的位其实无关紧要。控制位的定义如下图所示,共4位,组成一个16进制数,所以代码中的1其实铺开了二进制应该是0001,对应下面的16位定时器,TL1、TH1全用。
复制代码

3.jpg
TH1 = 0xfe; //11.0592MHz 0.5ms定时
TL1 = 0x33;
//这句代码非常的费解,刚开始的时候完全不懂这两个数索要表示的意思是什么,旁边还有个注释,也是没看懂。好在实验室有一位大神,分分钟帮我讲懂了。先看芯片手册上给出的例子:

1.jpg 2.jpg 0.png

  1. //也就是说实际的定时器定时464.6ms,这里终于解释清楚了为什么上面的定时器数据应该那么写


  2. TR1 = 1; //启动T1定时,这里比较好理解

  3. IE =0x8A; //开T0,T1中断,开总中断
  4. //这里继续翻出芯片的技术手册来解释,有了前面的基础,后面看起来自然一目了然,必须允许定时器溢出中断,定时器每溢出一次就产生一次中断,总中断是必须打开的,用了定时器1,因此定时器1的中断也需要打开,而定时器0的中断其实开不开无所谓的,因为根本就没有用定时器0。
复制代码

1.jpg

  1. main()
  2. {
  3.     system_Ini(); //调用子函数,初始化定时器T1
  4.     while(1) //无限循环
  5.     {
  6.         if(timer1>100)
  7.         {
  8.             timer1=0; //输出占空比0.7的PWM脉冲
  9.         }
  10.         if(timer1<30)
  11.         {
  12.             PWM=0;
  13.         }
  14.         else
  15.         {
  16.             PWM=1;
  17.         }
  18.     }
  19. }


  20. /*************************************
  21. [ t1 (0.5ms)中断] 中断中做 PWM 输出 1000/(0.02ms*250)=200Hz
  22. *************************************/

  23. void T1zd(void) interrupt 3 //3为定时器1的中断号; 1为定时器0的中断号; 0为外部中断1的中断号; 2为外部中断2的中断号; 4为串口中断的中断号,这是芯片规定的

  24. {
  25.     TH1 = 0xfe; //11.0592 初始化定时器,让定时器复位继续定时
  26.     TL1 = 0x33;
  27.     timer1++; //计数+1
  28. }
复制代码


回复

使用道具 举报

ID:162757 发表于 2018-12-25 21:04 | 显示全部楼层
真厉害  我学了 10年了 没学会
回复

使用道具 举报

ID:451441 发表于 2018-12-26 08:20 | 显示全部楼层
正好学学东西,在工作中再找机会实践下
回复

使用道具 举报

ID:162757 发表于 2018-12-26 19:16 | 显示全部楼层
昨天来过 楼主说的对 不练不行呀 我英语不好 不会语言
回复

使用道具 举报

ID:440142 发表于 2019-1-4 09:03 | 显示全部楼层
timer1=0是怎么实现占空比为0.7的PWM脉冲的呢?
回复

使用道具 举报

ID:440142 发表于 2019-1-4 09:06 | 显示全部楼层
关于占空比的问题我明白了,谢谢资料分享!
回复

使用道具 举报

ID:283906 发表于 2019-3-8 20:33 | 显示全部楼层
频率为什么是200hz???0.5ms中断一次timer1++,timer计100次,0.5*100==50ms,1/50==20hz啊?频率是怎么算的啊
回复

使用道具 举报

ID:483402 发表于 2019-3-20 00:24 | 显示全部楼层

timer1=0是怎么实现占空比为0.7的PWM脉冲的呢?
下面的语句 指示标注错地方了
        if(timer1<30)
        {
            PWM=0;
        }
        else
        {
            PWM=1;
频率为什么是200hz???0.5ms中断一次timer1++,timer计100次,0.5*100==50ms,1/50==20hz啊?频率是怎么算的啊  
同问 我也想知道 这数是怎么算出来的还是写错了
回复

使用道具 举报

ID:483402 发表于 2019-3-20 00:24 | 显示全部楼层
不能发帖吗
回复

使用道具 举报

ID:538990 发表于 2019-5-15 16:06 | 显示全部楼层
有用单片机开发控制器的吗?  就是单片机系统直接驱动步进电机,  省去了步进电机控制器。,求高手赐教
回复

使用道具 举报

ID:540088 发表于 2019-5-16 18:20 | 显示全部楼层
楼主 能给个联系方式吗  我用单片机控制28byj-4电机,但是程序一直出错,能不能帮我看看是什么情况?单片机也是用的STC90C516RD+
回复

使用道具 举报

ID:582255 发表于 2019-8-13 16:44 | 显示全部楼层
up主可以分享一下不?56003418@qq.com
回复

使用道具 举报

ID:564157 发表于 2019-12-11 18:42 | 显示全部楼层
无常 发表于 2019-3-8 20:33
频率为什么是200hz???0.5ms中断一次timer1++,timer计100次,0.5*100==50ms,1/50==20hz啊?频率是怎么 ...

可以用软件算 有一个软件可以算
回复

使用道具 举报

ID:298008 发表于 2020-1-6 23:24 | 显示全部楼层
谢谢楼主分享!!!
回复

使用道具 举报

ID:140644 发表于 2020-1-7 10:23 | 显示全部楼层
普中也就51搞搞,STM32服务都没有,搞个BBS瘫痪的,回复一直要划图像还发不出,普中最垃圾了。
回复

使用道具 举报

ID:298008 发表于 2020-2-22 10:13 | 显示全部楼层
谢谢楼主分享!!!
回复

使用道具 举报

ID:710053 发表于 2020-3-17 17:57 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:695749 发表于 2020-3-17 22:23 | 显示全部楼层
认真学习,努力思考,谢谢分享!
回复

使用道具 举报

ID:707309 发表于 2020-3-18 15:42 | 显示全部楼层
有没有带加减速的例子,谢谢分享
回复

使用道具 举报

ID:695749 发表于 2020-3-18 21:21 | 显示全部楼层
“3为定时器1的中断号; 1为定时器0的中断号; 0为外部中断1的中断号; 2为外部中断2的中断号; 4为串口中断的中断号,这是芯片规定的”
明白了一些,主要在实践,谢谢分享!
回复

使用道具 举报

ID:727456 发表于 2020-4-26 08:45 | 显示全部楼层
厉害,确实清楚
回复

使用道具 举报

ID:282095 发表于 2020-5-13 22:53 | 显示全部楼层
楼上思路清晰,蛮值得学习的。
回复

使用道具 举报

ID:748312 发表于 2020-5-18 16:20 | 显示全部楼层
这个详细适合我学习,谢谢
回复

使用道具 举报

ID:732581 发表于 2020-5-18 21:24 来自手机 | 显示全部楼层
不错不错
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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