找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机PID+PWM直流电机转速闭环控制源码(12864液晶显示)

  [复制链接]
跳转到指定楼层
#
ID:320610 发表于 2018-5-2 18:29 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
设计内容及要求
内容包括:
1.        查找文献资料,学习直流电机控制的工作原理;
2.        转速控制系统方案设计
3.        硬件电路设计,绘制电路原理图和PCB图;
4.        设计软件,并调试
5.        综合调试,测试、分析误差原因
6.        撰写设计报告
要求:
1.矩阵键盘设定并显示转速,实时显示实际转速
2.按键控制电机起停、正反转
3.PWM转速闭环控制。
4.用lcd12864液晶屏显示相关内容
设计
参数
1.转速调节范围:1500转/分--3000转/分
2.测速误差<10%


制作完成的pid直流电机转速控制系统实物图:


51单片机源程序如下:
  1. #include<reg51.h>
  2. #include "intrins.h"
  3. #include <lcd.H>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define GPIO_KEY P2
  7. sbit PWM=P1^4;                  
  8. sbit P10=P1^0;
  9. sbit P12=P1^2;
  10. uchar speed1[4]={"0000"};//设定转速
  11. uchar speed2[3]={"000"};//占空比        
  12. uchar speed[]={"0000"};//当前转速
  13. uchar KeyValue=0;
  14. uint AA,count=0,flag;

  15. float pid_p=0.003,pid_i=0.003,pid_d=0.002;        //PID三个参数 初值
  16. uint SpeedSet=3000,CurrentSpeed;//设定转速 当前转速
  17. unsigned char pid_val_mid;//pid_val_mid脉冲宽度
  18. unsigned int lastError=0;
  19. long int sumError=0;//sum偏差和
  20.         
  21.         
  22. void delay1(unsigned int i)
  23. {
  24.    unsigned int j;
  25.          for(;i>0;i--)
  26.          for(j=0;j<333;j++)
  27.          {;}
  28. }        


  29. /********************* 键盘扫描*************/
  30. void KeyDown(void)               
  31. {
  32.         GPIO_KEY=0x0f;
  33.                 delay1(10);
  34.         if(GPIO_KEY!=0x0f)
  35.         {
  36.                 delay1(10);
  37.                 if(GPIO_KEY!=0x0f)
  38.                 {
  39.                                 //测试列
  40.                         GPIO_KEY=0X0F;
  41.                         delay1(10);
  42.                         switch(GPIO_KEY)
  43.                         {
  44.                                 case(0X07):        KeyValue=0;break;
  45.                                 case(0X0b):        KeyValue=1;break;
  46.                                 case(0X0d): KeyValue=2;break;
  47.                                 case(0X0e):        KeyValue=3;break;
  48.                         }
  49.                         //测试行
  50.                         GPIO_KEY=0XF0;
  51.                         delay1(10);
  52.                         switch(GPIO_KEY)
  53.                         {
  54.                                 case(0X70):        KeyValue=KeyValue;break;
  55.                                 case(0Xb0):        KeyValue=KeyValue+4;break;
  56.                                 case(0Xd0): KeyValue=KeyValue+8;break;
  57.                                 case(0Xe0):        KeyValue=KeyValue+12;break;
  58.                         }
  59.                         
  60.                 }

  61.         }
  62. }

  63. void timer()
  64. {
  65.   
  66.          TMOD=0x11;//定时器0工作方式1.16位,定时器1工作方式1,16位定时;
  67.          TH0=0x4b;//50ms初值
  68.          TL0=0xfe;
  69.          
  70.          TH1=0xfc;//1msPWM控制
  71.          TL1=0x66;
  72.          
  73.          TR1=1;          //启动定时器1
  74.          ET1=1;           //定时器1中断使能
  75.          IT0=1;//外部中断下降沿触发
  76.          TR0=1;        //定时器启动标志
  77.          ET0=1;        //定时器中断使能
  78.          EX0=1;        //外部中断使能
  79.          EA=1;        //全局中断
  80. }


  81. /***********************lcd显示*************/
  82. void  display()
  83. {   
  84.    
  85.           speed[0]=CurrentSpeed/1000+0x30; //当前转速
  86.                 speed[1]=CurrentSpeed/100%10+0x30;
  87.                 speed[2]=CurrentSpeed/10%10+0x30;
  88.                 speed[3]=CurrentSpeed%10+0x30;  
  89.                
  90.                
  91.                 speed1[0]=SpeedSet/1000+0x30;//设定转速
  92.                 speed1[1]=SpeedSet/100%10+0x30;
  93.                 speed1[2]=SpeedSet/10%10+0x30;
  94.                 speed1[3]=SpeedSet%10+0x30;  
  95.                
  96.                 speed2[0]=pid_val_mid/100+0x30;
  97.           speed2[1]=pid_val_mid/10%10+0x30;//占空比
  98.                 speed2[2]=pid_val_mid%10+0x30;
  99.                
  100.         
  101.           DispHanzi(0,0,5,"当前转速:");
  102.                 DispZimu(0,5,4,speed);        
  103.                 DispHanzi(1,0,5,"设定转速:");
  104.                 DispZimu(1,5,4,speed1);

  105.                 DispHanzi(3,0,4,"占空比:");//占空比        
  106.                 DispZimu(3,4,3,speed2);
  107.                 DispHanzi(3,6,1,"%");//占空比        
  108.                
  109. }



  110. /************************电机控制*************/
  111. void keyKZ()
  112. {
  113.                          if(KeyValue==4)//正转
  114.                          {
  115.                           P10=1;
  116.                     P12=0;
  117.                                 }
  118.                          if(KeyValue==5)//反转
  119.                          {
  120.                           P10=0;
  121.                     P12=1;
  122.                                 }
  123.                                 if(KeyValue==6)//停车
  124.                          {
  125.                           P10=0;
  126.                     P12=0;
  127.                                 }
  128.                         
  129.                         if(KeyValue==12)//设定速度加50
  130.                           SpeedSet+=50;
  131.                         if(KeyValue==13)//设定速度减50
  132.                                 SpeedSet-=50;
  133.                         if(KeyValue==14)//设定速度加1
  134.                           SpeedSet+=1;
  135.                         if(KeyValue==15)//设定速度减1
  136.                                 SpeedSet-=1;
  137.         KeyValue=0;
  138.                                 
  139. }


  140. /************************PID控制算法*************/
  141. unsigned int PID()
  142. {  

  143.   int dError=0,Error=0,B;
  144.         
  145.         Error=SpeedSet-CurrentSpeed;//当前误差
  146.    sumError=Error+sumError;//误差和
  147.    dError=Error-lastError;//误差偏差
  148.    lastError=Error;
  149.   B=pid_p*Error+pid_i*sumError+pid_d*dError;
  150.         
  151.         if(B>100) pid_val_mid=100;
  152.    if(B<0) pid_val_mid=0;
  153.         if(B>=0&&B<=100)
  154.    pid_val_mid=B;
  155.          return(0);
  156. }


  157. void Timer0_isr() interrupt 1  //定时器0中断
  158. {
  159.          AA++;
  160.          TH0=0x4b;
  161.          TL0=0xfe;
  162.          if(AA==20)
  163.          {               
  164.            CurrentSpeed=count*3;//一分钟的转速
  165.                                 count=0;
  166.                                 AA=0;
  167.                                 PID();
  168.          }

  169. }


  170. void key_int() interrupt 0         //外部中断P32口
  171. {
  172.         count++;
  173. }

  174. void Timer1() interrupt 3
  175. {
  176.    static int c=0;
  177.                  TH1=0xfc;
  178.                   TL1=0x66;
  179.                  c++;    //每次定时器溢出加1                  
  180.          
  181.           if(c<=pid_val_mid) PWM=1;
  182.             
  183.           if(c>pid_val_mid)  PWM=0;
  184.             
  185.                 if(c>=100)         c=0;
  186. }
  187.         
  188. void main()
  189. {
  190.                 timer();//定时器初始化
  191.                 InitLCD();//LCD初始化
  192.                 while(1)
  193.                 {
  194.                    KeyDown();        //键盘扫描
  195. ……………………

  196. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
51单片机电机控速.zip (41.03 KB, 下载次数: 1826)


评分

参与人数 7黑币 +92 收起 理由
zbfdyw + 9 程序很好,就是缺少电路图,这是一个缺点!
aifengdian + 10 赞一个!
随缘ing + 5 很给力!
18463411235 + 5 很给力!
直流电机实验 + 5
lixinren45 + 8 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

来自 120#
ID:320610 发表于 2018-5-6 12:37 | 只看该作者
只有原理图和PCB的截图了,给需要的小伙伴们参考!

原理图加PCB.docx

89.02 KB, 下载次数: 457, 下载积分: 黑币 -5

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

来自 119#
ID:1009113 发表于 2022-3-22 17:54 | 只看该作者
frankieeeeee 发表于 2020-6-22 01:40
void Timer0_isr() interrupt 1  //定时器0中断
{
         AA++;

萌新也是这句没看懂。。。。请问这位师兄你理解了吗?方便解释一下吗?
回复

使用道具 举报

118#
ID:56665 发表于 2022-6-23 10:57 | 只看该作者
没有编码器,你怎么计算速度的,count++,外部中断接的是什么信号。
回复

使用道具 举报

117#
ID:1036099 发表于 2022-6-21 10:34 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

116#
ID:941205 发表于 2022-3-25 16:53 | 只看该作者
好东西,感谢楼主无私奉献。
回复

使用道具 举报

115#
ID:153676 发表于 2021-8-18 20:18 | 只看该作者
程序有bug12864. 没显示
回复

使用道具 举报

114#
ID:588322 发表于 2020-10-15 23:30 | 只看该作者
刚好项目要用到电机调速方面的东西,很有帮助
回复

使用道具 举报

113#
ID:815648 发表于 2020-10-9 15:35 | 只看该作者
感谢大佬的分享,对我很有帮助。
回复

使用道具 举报

112#
ID:371965 发表于 2020-6-22 14:15 | 只看该作者
楼主 您这个PID里面  最后检测B是否大于100这个  有问题吧  不应该是判断是否大于设定值吗
回复

使用道具 举报

111#
ID:702874 发表于 2020-6-22 01:41 | 只看该作者
CurrentSpeed=count*3;//一分钟的转速

代码里TIMER0()中断程序里得一行,为什么 乘以3呢,谢谢师兄提点
回复

使用道具 举报

110#
ID:702874 发表于 2020-6-22 01:40 | 只看该作者
void Timer0_isr() interrupt 1  //定时器0中断
{
         AA++;
         TH0=0x4b;
         TL0=0xfe;
         if(AA==20)
         {               
           CurrentSpeed=count*3;//一分钟的转速
                                count=0;
                                AA=0;
                                PID();
         }

}

CurrentSpeed=count*3;//一分钟的转速
        这句代码不太理解,希望师兄提点,谢谢
回复

使用道具 举报

109#
ID:777876 发表于 2020-6-14 10:04 | 只看该作者
程序写的规范,就是缺少电路图,这是一个缺点
回复

使用道具 举报

108#
ID:777876 发表于 2020-6-14 10:03 | 只看该作者
        程序很好,就是缺少电路图,这是一个缺点
回复

使用道具 举报

107#
ID:320610 发表于 2020-5-17 10:36 | 只看该作者
馒头好不好 发表于 2019-1-17 23:03
楼主,你好,请问你这个速度稳定吗?我自己写了一个pid速度调节,直流电机的速度波动很大,波动范围都有25% ...

这个还是当时在学校做的,还是很稳的;波动只有百分之几的样子!
回复

使用道具 举报

106#
ID:736988 发表于 2020-5-16 18:18 | 只看该作者
压缩包有仿真图吗?
回复

使用道具 举报

105#
ID:447180 发表于 2020-5-12 15:40 | 只看该作者
什么芯片驱动的电机
回复

使用道具 举报

104#
ID:748312 发表于 2020-5-10 16:32 | 只看该作者
学习了,资料很受益
回复

使用道具 举报

103#
ID:413380 发表于 2020-5-8 23:35 | 只看该作者
需要做一个位置闭环的电机控制,参考楼主的转速闭环,很有帮助感谢!
回复

使用道具 举报

102#
ID:740787 发表于 2020-4-29 12:10 | 只看该作者
赞一个,有电路图就更好了
回复

使用道具 举报

101#
ID:710871 发表于 2020-4-27 12:54 | 只看该作者
谢谢分享,正好想看看关于PWM和pid
回复

使用道具 举报

100#
ID:642957 发表于 2020-4-22 13:23 | 只看该作者
感觉理解起来有一定难度,要吃透这得花功夫。先下了,以后有用得上的地方。
回复

使用道具 举报

99#
ID:630251 发表于 2020-4-15 22:35 | 只看该作者
很棒,顶一个
回复

使用道具 举报

98#
ID:720149 发表于 2020-4-8 09:45 | 只看该作者
为什么打不开
回复

使用道具 举报

97#
ID:70662 发表于 2020-3-28 23:12 | 只看该作者
谢谢分享
回复

使用道具 举报

96#
ID:693716 发表于 2020-3-2 15:39 | 只看该作者
读了你的这个程序非常有启发,谢谢楼主分享,不过我试过用外部终端进行统计电机的转速,传感器有抖动(并不是理论的波形)我用的是定时器定时读取判断的方式。
回复

使用道具 举报

95#
ID:693716 发表于 2020-3-2 14:17 | 只看该作者
很给力,学习一下,谢谢楼主分享
回复

使用道具 举报

94#
ID:298008 发表于 2020-2-17 20:50 | 只看该作者
谢谢楼主分享!!!
回复

使用道具 举报

93#
ID:399111 发表于 2020-2-9 13:30 | 只看该作者
来看看PID的用法如何
回复

使用道具 举报

92#
ID:691305 发表于 2020-2-9 12:00 | 只看该作者
感谢分享
回复

使用道具 举报

91#
ID:673644 发表于 2019-12-25 15:59 | 只看该作者
有图吗
回复

使用道具 举报

90#
ID:617260 发表于 2019-12-24 00:06 | 只看该作者
好的参考资料,力顶一下
回复

使用道具 举报

89#
ID:671756 发表于 2019-12-23 20:38 | 只看该作者
原理图带上就好
回复

使用道具 举报

88#
ID:669918 发表于 2019-12-21 16:36 | 只看该作者
有原理图没。。。
回复

使用道具 举报

87#
ID:563670 发表于 2019-12-21 14:11 | 只看该作者
有原理图吗
回复

使用道具 举报

86#
ID:667984 发表于 2019-12-19 09:03 | 只看该作者
谢谢大佬
回复

使用道具 举报

85#
ID:667984 发表于 2019-12-19 09:02 | 只看该作者
谢谢大佬
回复

使用道具 举报

84#
ID:653751 发表于 2019-12-15 18:11 | 只看该作者
大佬,有LCD显示屏这样的步进电机PID 控制转速的吗,急需,谢谢啦
回复

使用道具 举报

83#
ID:653751 发表于 2019-12-15 18:11 | 只看该作者
有LCD 显示屏的这样的步进电机PID 控制转速的hex文件吗,谢谢,急需,感谢楼主
回复

使用道具 举报

82#
ID:651053 发表于 2019-12-13 17:20 | 只看该作者
请问测速是怎么测的呢,实物图看不大清楚
回复

使用道具 举报

81#
ID:498602 发表于 2019-12-8 19:02 | 只看该作者
太强了
回复

使用道具 举报

80#
ID:653000 发表于 2019-11-30 16:10 | 只看该作者
顶一个
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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