找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6509|回复: 8
收起左侧

单片机PWM直流电机调速显示转速 PCB封装库+程序+电路

  [复制链接]
ID:396159 发表于 2019-1-4 19:48 | 显示全部楼层 |阅读模式
PWM直流电机调速仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
E11V1WL1[%1_$@HCBPJMK_A.png

Altium Designer画的PWM直流电机调速原理图和PCB图如下:(51hei附件中可下载工程文件)
0.png 0.png

里面包含PCB封装库文件:
0.png

PWM直流电机调速单片机程序如下
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #include "LCD1602.h"

  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. /**********端口分配*******************************/
  7. sbit add_key=P1^0;  //占空比加
  8. sbit dec_key=P1^1;  //占空比减
  9. sbit z_key=P1^2;  //正转键
  10. sbit f_key=P1^3;  //反转键
  11. sbit run_key=P1^4; //启动/停止键
  12.                   
  13. sbit beep=P3^2;
  14. //电机驱动相关
  15. sbit ENA=P3^5;
  16. sbit IN1=P3^7;
  17. sbit IN2=P3^4;
  18. /**********变量定义*******************************/
  19. //电机相关定义
  20. bit Rotation_f=0;  //步进电机旋转状态标志  为0正转  1反转

  21. bit power_flag=0;  //总开关标志

  22. #define  PWM_cnt_LEN 100  //计数全长
  23. #define PWM_ON  1        //开  
  24. #define PWM_OFF 0        //关
  25. uint PWM_cnt;  //PWM计数
  26. uchar PWM_duty;  //PWM占空比

  27. uint speed_cnt=0;  //转速
  28. uint speed_value;
  29. bit dis_speed_flag=0;
  30. uint delay_cnt;
  31. uchar dis_buf[6];
  32. uchar dis_cnt;
  33. uchar dis_buf1[4];
  34. uchar dis_cnt1;
  35. /*********定义延时1ms子程序************************/
  36. void delay1ms(uint t)//1ms延时子程序
  37. {
  38.     uint k,j;
  39.         for(k=0;k<t;k++)
  40.                 for(j=0;j<120;j++);
  41. }
  42. /**************************************************/
  43. /**********蜂鸣器报警**********************/
  44. void beep_alarm()
  45. {
  46.         beep=0;
  47.         delay1ms(100);
  48.         beep=1;
  49. }
  50. /*******************************************/
  51. /**********电机停止********************/
  52. void motor_stop()
  53. {
  54.         IN1=1;
  55.         IN2=1;
  56. }
  57. /***************************************/
  58. /*******电机正转********************/
  59. void motor_foreward()
  60. {
  61.         IN1=1;
  62.         IN2=0;
  63. }
  64. /************************************/
  65. /********电机反转**********************/
  66. void motor_reversal()
  67. {
  68.         IN1=0;
  69.         IN2=1;
  70. }
  71. /*****************************************/
  72. /************显示转速*********************/
  73. void dis_speed()
  74. {
  75.         dis_cnt=0;
  76.         if(speed_value/10000!=0)
  77.         {
  78.                 dis_buf[dis_cnt]=speed_value/10000+0x30;
  79.                 dis_cnt++;
  80.                 dis_buf[dis_cnt]=speed_value%10000/1000+0x30;
  81.                 dis_cnt++;
  82.                 dis_buf[dis_cnt]=speed_value%1000/100+0x30;
  83.                 dis_cnt++;
  84.                 dis_buf[dis_cnt]=speed_value%100/10+0x30;
  85.                 dis_cnt++;
  86.                 dis_buf[dis_cnt]=speed_value%10+0x30;
  87.                 dis_cnt++;
  88.         }
  89.         else if(speed_value%10000/1000!=0)
  90.         {
  91.                 dis_buf[dis_cnt]=' ';
  92.                 dis_cnt++;
  93.                 dis_buf[dis_cnt]=speed_value%10000/1000+0x30;
  94.                 dis_cnt++;
  95.                 dis_buf[dis_cnt]=speed_value%1000/100+0x30;
  96.                 dis_cnt++;
  97.                 dis_buf[dis_cnt]=speed_value%100/10+0x30;
  98.                 dis_cnt++;
  99.                 dis_buf[dis_cnt]=speed_value%10+0x30;
  100.                 dis_cnt++;
  101.         }
  102.         else if(speed_value%1000/100!=0)
  103.         {
  104.                 dis_buf[dis_cnt]=' ';
  105.                 dis_cnt++;
  106.                 dis_buf[dis_cnt]=' ';
  107.                 dis_cnt++;
  108.                 dis_buf[dis_cnt]=speed_value%1000/100+0x30;
  109.                 dis_cnt++;
  110.                 dis_buf[dis_cnt]=speed_value%100/10+0x30;
  111.                 dis_cnt++;
  112.                 dis_buf[dis_cnt]=speed_value%10+0x30;
  113.                 dis_cnt++;
  114.         }
  115.         else if(speed_value%100/10!=0)
  116.         {
  117.                 dis_buf[dis_cnt]=' ';
  118.                 dis_cnt++;
  119.                 dis_buf[dis_cnt]=' ';
  120.                 dis_cnt++;
  121.                 dis_buf[dis_cnt]=' ';
  122.                 dis_cnt++;
  123.                 dis_buf[dis_cnt]=speed_value%100/10+0x30;
  124.                 dis_cnt++;
  125.                 dis_buf[dis_cnt]=speed_value%10+0x30;
  126.                 dis_cnt++;
  127.         }
  128.         else
  129.         {
  130.                 dis_buf[dis_cnt]=' ';
  131.                 dis_cnt++;
  132.                 dis_buf[dis_cnt]=' ';
  133.                 dis_cnt++;
  134.                 dis_buf[dis_cnt]=' ';
  135.                 dis_cnt++;
  136.                 dis_buf[dis_cnt]=' ';
  137.                 dis_cnt++;
  138.                 dis_buf[dis_cnt]=speed_value%10+0x30;
  139.                 dis_cnt++;
  140.         }
  141.         dis_buf[dis_cnt]='\0';
  142.         LCD1602_Print(2,0,dis_buf);        //显示转速
  143. }
  144. /*****************************************/
  145. /**********显示占空比*********************/
  146. void dis_duty()
  147. {
  148.     dis_cnt1=0;
  149.         if(PWM_duty/100!=0)
  150.         {
  151.                 dis_buf1[dis_cnt1]=PWM_duty/100+0x30;
  152.                 dis_cnt1++;
  153.                 dis_buf1[dis_cnt1]=PWM_duty%100/10+0x30;
  154.                 dis_cnt1++;
  155.                 dis_buf1[dis_cnt1]=PWM_duty%10+0x30;
  156.                 dis_cnt1++;
  157.         }
  158.         else if(PWM_duty%100/10!=0)
  159.         {
  160.                 dis_buf1[dis_cnt1]=' ';
  161.                 dis_cnt1++;
  162.                 dis_buf1[dis_cnt1]=PWM_duty%100/10+0x30;
  163.                 dis_cnt1++;
  164.                 dis_buf1[dis_cnt1]=PWM_duty%10+0x30;
  165.                 dis_cnt1++;
  166.         }
  167.         else
  168.         {
  169.                 dis_buf1[dis_cnt1]=' ';
  170.                 dis_cnt1++;
  171.                 dis_buf1[dis_cnt1]=' ';
  172.                 dis_cnt1++;
  173.                 dis_buf1[dis_cnt1]=PWM_duty%10+0x30;
  174.                 dis_cnt1++;
  175.         }
  176.         dis_buf1[dis_cnt1]='\0';
  177.         LCD1602_Print(9,1,dis_buf1);        //显示占空比
  178. }
  179. /*****************************************/
  180. /*************定时器初始化程序*******************/
  181. void timer_init(void)  
  182. {
  183.         TMOD=0x11; //设置定时器0,1为16位模式
  184.         TH0=0xD8;  //10ms定时初值         10ms  D8F0           
  185.         TL0=0xF0;
  186.         ET0=1;     //定时器0中断开
  187.         TR0=1;     //开定时器0

  188.         TH1=0xFF;  //100us定时初值
  189.         TL1=0x9C;
  190.         ET1=1;     //定时器1中断开
  191.         TR1=1;     //开定时器1
  192.         EA=1;      //总中断开
  193. }
  194. /*************************************************/
  195. /***********定时器0中断服务程序*******************/
  196. void timer0(void) interrupt 1  
  197. {
  198.         TH0=0xD8;  //10ms定时初值 10ms  D8F0
  199.         TL0=0xF0;
  200.         delay_cnt++;
  201.         if(delay_cnt>=200)  //2S计时
  202.         {
  203.                 delay_cnt=0;
  204.                 speed_value=speed_cnt*30;  //30  将两秒内的计数乘以30得到转每分          (还要除2  因为有两片磁铁)  30/2=15
  205.                 speed_cnt=0;
  206.                 dis_speed_flag=1;
  207.         }
  208. }
  209. /*************************************************/
  210. /**********外部中断1服务程序**************/
  211. void int1() interrupt 2
  212. {
  213.         speed_cnt++;  //转速
  214. }
  215. /*****************************************/
  216. /***********定时器1中断服务程序*******************/
  217. void timer1(void) interrupt 3  
  218. {
  219.         TH1=0xFF;  //100us定时初值
  220.         TL1=0x9C;
  221.         if(++PWM_cnt==PWM_cnt_LEN)
  222.         {
  223.                 PWM_cnt=0;
  224.                 if(power_flag==1)
  225.                         ENA=PWM_ON;
  226.                 else ENA=PWM_OFF;

  227.         }
  228.         if(PWM_cnt==PWM_duty)
  229.         {
  230.                 ENA=PWM_OFF;
  231.         }
  232. }
  233. /*************************************************/
  234. /*******按键处理程序******************************/
  235. void key_check()
  236. {
  237.         if(add_key==0)  //占空比加
  238.         {
  239.                 delay1ms(50);
  240.                 if(add_key==0)
  241.                 {
  242.                     beep_alarm(); //蜂鸣器报警
  243.                         PWM_duty++;
  244.                         if(PWM_duty>100)
  245.                                 PWM_duty=100;
  246.                         dis_duty(); //显示占空比
  247.                 }
  248.         }
  249.         if(dec_key==0)  //占空比减
  250.         {
  251.                 delay1ms(50);
  252.                 if(dec_key==0)
  253.                 {
  254.                     beep_alarm(); //蜂鸣器报警
  255.                         PWM_duty--;
  256.                         if(PWM_duty>100)
  257.                                 PWM_duty=0;
  258.                         dis_duty(); //显示占空比
  259.                 }
  260.         }
  261.         if(z_key==0)  //正转键
  262.         {
  263.                 delay1ms(50);
  264.                 if(z_key==0)
  265.                 {
  266.                     beep_alarm(); //蜂鸣器报警
  267.                         Rotation_f=0;  //步进电机旋转状态标志  为0正转  1反转
  268.                         LCD1602_Print(12,0,"pros");
  269.                         motor_stop();//电机停止
  270.                         delay1ms(1);
  271.                         motor_foreward();  //电机正转
  272.                 }
  273.         }
  274.         if(f_key==0)  //反转键
  275.         {
  276.                 delay1ms(50);
  277.                 if(f_key==0)
  278.                 {
  279.                     beep_alarm(); //蜂鸣器报警
  280.                     Rotation_f=1;  //步进电机旋转状态标志  为0正转  1反转
  281.                         LCD1602_Print(12,0,"cons");
  282.                         motor_stop();//电机停止
  283.                         delay1ms(1);
  284.                         motor_reversal(); //电机反转
  285.                 }
  286.         }
  287.     if(run_key==0) //启动/停止键
  288.         {
  289.                 delay1ms(50);
  290.                 if(run_key==0)
  291.                 {
  292.                     beep_alarm(); //蜂鸣器报警
  293.             power_flag=~power_flag;  //总开关标志
  294.                         if(power_flag==1)
  295.                         {
  296.                             if(Rotation_f==0)  //步进电机旋转状态标志  为0正转  1反转
  297.                                 {
  298.                                         motor_stop();//电机停止
  299.                                         delay1ms(1);
  300.                                         motor_foreward();  //电机正转
  301.                                 }
  302.                                 else
  303.                                 {
  304.                                         motor_stop();//电机停止
  305.                                         delay1ms(1);
  306.                                         motor_reversal(); //电机反转
  307.                                 }
  308.                         }
  309.                         else motor_stop();  //电机停止
  310.                         while(!run_key);//等待按键释放
  311.                 }
  312.         }
  313. }
  314. /*************************************************/
  315. /**********************主函数*********************/
  316. void main()
  317. {
  318.     PWM_duty=50;  //PWM占空比
  319.     timer_init();  //定时器初始化程序
  320.         EX1=1;
  321.         IT1=1;
  322.         LCD1602_init(); //LCD1602液晶初始化
  323.         LCD1602_Print(0,0,"V:    0rpm  pros");
  324.         LCD1602_Print(0,1,"PWM_duty:  0    ");      
  325.         dis_duty(); //显示占空比
  326.         while(1)
  327.         {
  328.             key_check(); //按键处理程序
  329.                 if(dis_speed_flag==1)
  330.                 {
  331.                         dis_speed(); //显示转速
  332.                         dis_speed_flag=0;
  333.                 }

  334.         }
  335. }
  336. /**************************************************/
复制代码

0.png

全部资料51hei下载地址:
PWM直流电机调速显示转速.7z (11.63 MB, 下载次数: 435)

评分

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

查看全部评分

回复

使用道具 举报

ID:665669 发表于 2019-12-16 22:30 | 显示全部楼层
哇,刚好找到,太棒了
回复

使用道具 举报

ID:657088 发表于 2019-12-17 10:43 来自手机 | 显示全部楼层
厉害,大佬求指教
回复

使用道具 举报

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

使用道具 举报

ID:697141 发表于 2020-3-20 11:05 | 显示全部楼层
太棒了
回复

使用道具 举报

ID:741655 发表于 2020-4-30 13:35 | 显示全部楼层
proteus仿真文件夹中的文件怎么打开啊,我用proteus好像打开不了
回复

使用道具 举报

ID:745048 发表于 2020-5-7 08:29 | 显示全部楼层
proteus仿真文件夹中的文件怎么打开啊,我用proteus好像打开不了
回复

使用道具 举报

ID:741333 发表于 2020-5-7 14:35 | 显示全部楼层
测速传感器在哪呢
回复

使用道具 举报

ID:684850 发表于 2020-6-1 18:57 | 显示全部楼层
测速的原理是什么,我不太懂

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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