找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机控制直流电机启动和正反转程序,按键的时候要按键好几次才启动

[复制链接]
跳转到指定楼层
楼主
这段程序是控制直流电机启动和正反转的,电路图我也放上了,程序不太对,按键的时候要按键好几次才启动,正反转按钮也不好使,有没有大佬给改改。


单片机源程序如下:

  1. #include"reg51.h"
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. void delay1(uint ms);
  6. sbit k1=P1^0;                                  //启停按键K1
  7. sbit k2=P1^1;                                  //正反转按键K2
  8. sbit up=P1^2;                                  //加速按键up
  9. sbit down=P1^3;                                  //减速按键down
  10. sbit in1=P1^5;                                  //正反转输入口
  11. sbit in2=P1^6;
  12. sbit ENA=P1^7;                                  //PWM信号输入口
  13. sbit LED1=P2^3;                                   //绿灯正转
  14. sbit LED2=P2^4;                                   //红灯反转
  15. uchar a=1;
  16. uchar count=40;                              //速度上限
  17. uchar t=0;
  18. char speed=20;                              //初始速度

  19. /*-----------------------端口命名------------------------*/
  20. sbit rs=P2^0;                 //LCD的数据/命令选择端
  21. sbit rw=P2^1;                  //LCD的读写选择端
  22. sbit e=P2^2;                   //LCD的使能信号端  
  23. /*-------------------------------------------------------*/
  24. /*-----------------------定义参数------------------------*/
  25. uint i,z,cou,zhuan,msec;     //定义参数
  26. uchar display[]={"speed=     r/min "};     //定义显示参数
  27. /*-------------------------------------------------------*/
  28. /*-----------------------正反转延时函数------------------*/
  29. void delay(void)
  30. {
  31.         uchar i,j,k;
  32.         for(i=50;i>0;i--)
  33.         {
  34.                 for(j=100;j>0;j--)
  35.                         for(k=230;k>0;k--);
  36.         }
  37. }
  38. /*------------------------------------------------------*/
  39. /*-----------------------启停函数------------------------*/
  40. void qiting()                                //b为启停标志
  41. {
  42.         if(k1==0)
  43.         {
  44.                                            delay1(20);
  45.              if(k1==0){

  46.                         LED1=1;
  47.                         LED2=0;
  48.                          ENA=1;



  49.         }}
  50.         else
  51.         {
  52.                 LED1=0;
  53.                 LED2=0;
  54.                 ENA=0;

  55.         }
  56. }         
  57. /*-------------------------------------------------------*/
  58. /*-----------------------正反转函数----------------------*/
  59. void zhengfan()
  60. {        if(k1==1)
  61.         {
  62.                                              
  63.                 ENA=0;
  64.         }
  65.         else if(k2==1)                       //正转
  66.         {
  67.                 LED1=1;
  68.                 LED2=0;
  69.                 delay();
  70.                 ENA=1;
  71.                 in1=1;
  72.                 in2=0;
  73.         }
  74.         else if(k2==0)                                  //开关按下反转
  75.         {
  76.                 LED1=0;
  77.                 LED2=1;
  78.                 delay();
  79.                 ENA=1;
  80.                 in1=0;
  81.                 in2=1;
  82.         }               
  83. }
  84. /*--------------------------------------------------------*/
  85. /*-----------------------增减速函数-----------------------*/
  86. void speed_control()
  87. {

  88.         if(up==0)                                         //增速
  89.         {
  90.                 speed++;
  91.                 while(up==0)                     //即时对计满数的speed值控制在设定范围之内
  92.                 if(speed>count)speed=count;
  93.         }
  94.         if(down==0)                                            //减速
  95.         {
  96.                 speed--;
  97.                 while(down==0)                 
  98.                 if(speed<0)speed=0;
  99.         }
  100. }
  101. /*----------------------------------------------------------------------------*/
  102. /*-------输出PWM的定时器中断(与增减函数配合输出PWM信号)---------------------*/
  103. void timer0_PWM() interrupt 3  //计满1ms跳一次,有speed个之后PWM跳变
  104. {
  105.         if(k1==0)
  106.         {
  107.                 if(t<speed)        ENA=1;
  108.                 else ENA=0;
  109.                 t++;
  110.                 if(t>=count)t=0;
  111.         }
  112. }
  113. /*-------------------------------------------------------*/
  114. /*-----------------------毫秒延时------------------------*/
  115. void delay1(uint ms)
  116. {  
  117.         uint i,j;               //为延时引入i,j两参数  
  118.         for (j=0;j<ms;j++)      //延时第一循环   
  119.         for (i=0;i<120;i++);    //延时第二循环  
  120. }
  121. /*-------------------------------------------------------*/
  122. /*--------------------向LCD1602写命令--------------------*/
  123. void write_command(uchar command)
  124. {
  125.         rs=0;           //数据、命令选择端0为命令
  126.         rw=0;           //读、写选择端0为写
  127.         P0=command;      //向LCD写命令
  128.         delay1(5);      //稍做延迟,代替检测忙状态  
  129.         e=1;             //信号使能端高电平
  130.         delay1(5);      //稍做延迟,代替检测忙状态  
  131.         e=0;            //信号使能端低电平
  132. }
  133. /*-------------------------------------------------------*/
  134. /*--------------------向LCD1602写数据--------------------*/
  135. void write_data(uchar data0)
  136. {
  137.         rs=1;       //数据、命令选择端 1为数据
  138.         rw=0;       //读、写选择端0为写
  139.         P0=data0;      //向LCD写数据
  140.         delay1(5);      //稍做延迟,代替检测忙状态
  141.         e=1;      //信号使能端高电平
  142.         delay1(5);     //稍做延迟,代替检测忙状态
  143.         e=0;      //信号使能端低电平
  144. }
  145. /*-------------------------------------------------------*/
  146. /*-------------------外部中断1计数程序-------------------*/
  147. void counter(void) interrupt 2
  148. {   

  149.         cou++;  
  150.         if(cou==2)      //2次循环为发动机转一圈  
  151.         {   
  152.                 cou=0;     //初始化计数   
  153.              z++;      //转圈计数加1
  154.           }   


  155. }
  156. /*-------------------------------------------------------*/
  157. /*------------------------LCD显示------------------------*/
  158. void displaytolcd()
  159. {  
  160.   write_command(0x80);     //向LCD1602写命令80H  
  161.   for (i=0;i<sizeof(display)-1;i++)   //循环要传输的字符个数次,每一次传一个字符  
  162.   {   
  163.     write_data(display[i]);   
  164.       delay1(5);  
  165.   }
  166. }
  167. /*-------------------------------------------------------*/  
  168. /*-----------------内部中断0计时计数程序-----------------*/
  169. void Timer_0(void) interrupt 1
  170. {  
  171.    TH0=0x3c;      //50ms定时  
  172.    TL0=0xb0;  
  173.    msec++;  
  174.    if(msec==20)      //50*20=1S  
  175.    {   
  176.         msec=0;
  177.         zhuan=60*z;        //每分钟转速
  178.         displaytolcd();   

  179.         z=0;

  180.    }
  181. }
  182. /*-------------------------------------------------------*/
  183. /*-----------------------数据处理------------------------*/
  184. void  disp_count()
  185. {  
  186. display[7]=(zhuan/1000+'0');    //转换转速的千位  
  187. display[8]=(zhuan/100%10+'0');    //转换转速的百位  
  188. display[9]=(zhuan/10%10+'0');    //转换转速的十位   
  189. display[10]=(zhuan%10+'0');    //转换转速的个位
  190. }
  191. /*-------------------------------------------------------*/
  192. /*----------------------端口初始化-----------------------*/
  193. void int_all()
  194. {  
  195.                   in1=1;                        //下面五行为启停、正反转初始化
  196.                 in2=0;                        //2
  197.                 LED1=0;                        //3
  198.                 LED2=0;                        //4
  199.                 ENA=0;                        //5
  200.         z=0;       //初始化z的值  
  201.         cou=0;      //初始化co的值  
  202.         zhuan=0;      //初始化转的值  
  203.         rw=0;       //选择LCD写数据指令  
  204.         delay1(15);      //延时15ms  
  205.         write_command(0x38);     //向LCD1602写命令38H  
  206.         delay1(5);      //延时5ms  
  207.         write_command(0x0e);     //向LCD1602写命令0EH  
  208.         delay1(5);      //延时5ms  
  209.         write_command(0x06);     //向LCD1602写命令06H
  210.         TMOD=0x21;      //内部中断定时器选择;定时器0工作在方式1,定时器1工作在方式2
  211.         TH0=0x3C;      //50ms定时  
  212.         TL0=0xb0;
  213.                 TR0=1;         //定时器0工作,用于测速
  214.                 TH1=0xA3;                  //1ms定时
  215.             TL1=0xA3;
  216.                 TR1=1;                  //定时器1工作,用于调速
  217.         EA=1;       //开中断总开关

  218.                 IT1=1;       //外部中断1为下降沿触发   
  219.                 ET1=1;                   //T1允许中断
  220.                 ET0=1;                        //T0允许中断
  221.                 EX1=1;                  //外部中断1允许中断

  222. }

  223. void main()
  224. {        
  225.         int_all();
  226.         ENA=0;
  227.         while(1)
  228.         {        
  229.                 qiting();
  230.                 zhengfan();
  231.                 if(k1==0)
  232.                 {
  233.                         speed_control();
  234.                 }
  235.                 disp_count();     //数据处理
  236.         displaytolcd();     //LCD显示
  237.         }
  238. }
复制代码


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

使用道具 举报

沙发
ID:525089 发表于 2019-4-30 13:55 | 只看该作者
好好学习一下
回复

使用道具 举报

板凳
ID:525089 发表于 2019-4-30 14:01 | 只看该作者
参考一下,谢谢楼主
回复

使用道具 举报

地板
ID:525068 发表于 2019-4-30 15:26 | 只看该作者
可以在按键那里加一个上拉电阻,使单片机引脚不用时处于高电平,然后把销抖的延时时间变短一点,五毫秒左右就行了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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