• 基于51单片机PWM调速L298芯片控制两选一直流电机正反运转的项目工程


    #include"reg52.h"//单片机头文件
    #define uchar unsigned char//宏定义,用uchar表示unsigned char,叫无符号字符型数据类型,取值范围为:0到255。
    #define uint unsigned int//宏定义,用uint表示unsigned int,叫无符号整数型数据类型,取值范围为:0到65535。
    sbit qitingjian=P1^0;//位定义启停键
    sbit zhengzhuan=P1^1;//位定义正转键
    sbit fanzhuan=P1^2;//位定义反转键
    sbit jiasujian=P1^3;//位定义加速键
    sbit jiansujian=P1^4;//位定义减速键
    sbit xuanze=P1^5;//位定义选择键
    sbit IN1=P2^0;//位定义L298M芯片IN1端口
    sbit IN2=P2^1;//位定义L298M芯片IN2端口
    sbit IN3=P2^2;//位定义L298M芯片IN3端口
    sbit IN4=P2^3;//位定义L298M芯片IN4端口
    sbit ENA=P2^4;//位定义L298M芯片使能端ENA
    sbit ENB=P2^5;//位定义L298M芯片使能端ENB
    //sbit duan=P3^0;//位定义L298M芯片控制端IN1
    //sbit wei=P3^1;//位定义L298M芯片控制端IN2
    sbit qitingled=P3^4;//位定义启停指示灯
    sbit zhengzhuanled=P3^5;//位定义正转指示灯
    sbit fanzhuanled=P3^6;//位定义反转指示灯
    sbit xuanzeled=P3^7;//位定义选择指示灯
    uchar xuanzenum;//选择次数变量
    uchar motor1flag;//电机1启动标志位变量
    uchar motor2flag;//电机2启动标志位变量
    uchar motor1_pwm_flag;//电机1脉冲宽度调制标志位变量
    uchar motor2_pwm_flag;//电机2脉冲宽度调制标志位变量
    //sbit waibuzhongduanling=P3^2; //外部中断0端口
    //uint qian,bai,shi,ge,zhuansu;//数码管千位变量、百位变量、十位变量、个位变量以及转速变量
    //uint maichongcount,Time0num,Time1num,pwm,qitingnum,zhengzhuanflag,fanzhuanflag;//脉冲计数变量、定时器0定时计数变量、定时器1定时计数变量、脉冲宽度调制变量、启停键按下数次变量、正转标志位变量、反转标志位变量
    uint Time0num,pwm,qitingnum,zhengzhuanflag,fanzhuanflag;//定时器0定时计数变量、脉冲宽度调制变量、启停键按下数次变量、正转标志位变量、反转标志位变量
    //uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x27,0x7f,0x6f,0x40,0x7c,0x39,0x5e,0x79,0x71,0x00};//共阴数码管段码,高电平点亮段码,低电平熄灭段码。
    //uchar code weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};//共阴数码管位码,低电平点亮位码,高电平熄灭位码。
    //void delay(uint jishi);//毫秒延时函数
    //void TimerInit();//定时器初始化函数
    //void Time0();//定时器0定时函数
    //void Time1();//定时器1定时函数
    //void KeyScan();//按键扫描函数
    //void waibuzhongduanlingjishu();//外部中断0计数函数
    //void shumaguandisplay(uint qian,uint bai,uint shi,uint ge);//数码管显示函数
    //void shumaguannodisplay(uint qian,uint bai,uint shi,uint ge);//数码管无显示函数
      void delay(uint jishi)//延时函数
    {
       uint i,j;
       for(i=jishi;i>0;i--)
        for(j=110;j>0;j--);
      }
      void TimerInit()//定时器初始化函数
    {
       TMOD=0x01;//设定定时器为定时器0和定时器1,工作模式都为1。
       TH0=(65536-1000)/256;//TH0装初值为65536-1000=64536,即定时1000微妙,相当于1毫秒。
       TL0=(65536-1000)%256;//TL0装初值为65536-1000=64536
    // TH1=(65536-50000)/256;//TH1装初值为65536-50000=15536,即定时50000微妙,相当于50毫秒。
    // TL1=(65536-50000)%256;//TL1装初值为65536-50000=15536
       EA=1;//全局中断允许
       ET0=1;//打开定时器0中断允许
       TR0=0;//关定时器0       
    // EX0=1;//开外部中断0允许
    // IT0=1;//设置外部中断0下降触发中断
    // ET1=1;//打开定时器1中断允许
    // TR1=1;//开定时器1
     }
      void Time0() interrupt 1//定时器0定时函数,每1毫秒产生PWM波一次。
    {       
       TH0=(65536-1000)/256;//TH0重装初值为65536-1000=64536,即定时1000微妙,相当于1毫秒。
       TL0=(65536-1000)%256;//TH0重装初值为65536-1000=64536
       Time0num++;//定时器0定时计数变量先赋值再自加
       if(motor1_pwm_flag==1&&motor2_pwm_flag==0)
     {
        if(Time0num==20)//判断定时器0定时计数变量是否大于等于20,PWM波完整周期为20ms,定时器0定时计数变量Time0num数值越大,电机运转越快。
      {
         Time0num=0;//定时器0定时计数变量等于0
        }
        if(Time0num<pwm)//判断定时器0定时计数变量还否小于脉冲宽度调制变量       
      {                               
         ENA=1;//L298M芯片使能端ENA置高电平,电机运转。
    //   zhuansuled=0;//开转速指示灯
        }
        else
      {
         ENA=0;//L298M芯片使能端ENA置低电平,电机不运转。
    //   zhuansuled=1;//关转速指示灯
        }
       }
       if(motor1_pwm_flag==0&&motor2_pwm_flag==1)
     { 
        if(Time0num==20)//判断定时器0定时计数变量是否大于等于20,PWM波完整周期为20ms,定时器0定时计数变量Time0num数值越大,电机运转越快。
       {
         Time0num=0;//定时器0定时计数变量等于0
        }
        if(Time0num<pwm)//判断定时器0定时计数变量还否小于脉冲宽度调制变量       
       {                               
         ENB=1;//L298M芯片使能端ENA置高电平,电机运转。
    //   zhuansuled=0;//开转速指示灯
        }
        else
       {
         ENB=0;//L298M芯片使能端ENA置低电平,电机不运转。
    //   zhuansuled=1;//关转速指示灯
        }
       }
     }
    //  void Time1() interrupt 3//定时器1定时函数,定时50ms,采集电机转速。       
    //{       
    //   TH1=(65536-50000)/256;//TH1装初值为65536-50000=15536,即定时50000微妙,相当于50毫秒。
    //   TL1=(65536-50000)%256;//TH1装初值为65536-50000=15536
    //   Time1num++;//定时器1定时计数变量先赋值再自加
    //   if(Time1num==20)//判断定时器1定时计数变量是否等于20,即每1秒测速一次。
    //  {       
    //    Time1num=0;//定时器1定时计数变量等于0
    //    EX0=0;//关外部中断0
    //    zhuansu=55*maichongcount/24;//电机转速=每分钟X脉冲计数变量/每转一圈需要的脉冲个数,即55*maichongcount/24,其中的55表示55秒,为什么不是一分钟60秒?由于Protues仿真电路图中的MOTOR-ENCODER仿真件存在误差,为了让MOTOR-ENCODER仿真件显示的转速达到数码管显示转速的效果,进行了一定秒数的修改,不过实际运用要以一分钟60秒为准,maichongcount为单片机从外部中断0端口处获取MOTOR-ENCODER仿真件旋转生产的脉冲计数变量,24为MOTOR-ENCODER仿真件每旋转一圈产生的脉冲个数。
    //    qian=zhuansu/1000;//数码管千位显示
    //    bai=zhuansu%1000/100;//数码管百位显示
    //    shi=zhuansu%100/10;//数码管十位显示
    //    ge=zhuansu%10;//数码管个位显示
    //    maichongcount=0;//脉冲计数变量归零
    //    EX0=1;//开外部中断0
    //   }
    //}
    //  void waibuzhongduanlingjishu() interrupt 0  using 1//外部中断0计数函数,外部脉冲计数。
    //{
    //   maichongcount++ ;//脉冲计数变量先赋值再自加
    //  }
      void KeyScan()//按键扫描函数
    {
       if(qitingjian==0)//判断启停键是否按下
     {
    //  shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
        delay(5);
        if(qitingjian==0)//再次判断启停键是否按下
      {
    //   shumaguandisplay(qian,bai,shi,ge);//数码管显示函数
         qitingnum++;//启停键按下数次变量先赋值再加加
         qitingled=0;//开启停指示灯
         while(!qitingjian);//启停键释放
         if(qitingnum==2)//判断启停键按下数次变量是否为2
        {
          TR0=0;
          qitingnum=0;//启停键按下数次变量归零
          xuanzenum=0;//选择次数变量清0
          Time0num=0;//定时器0定时计数变量清0
          pwm=0;//脉冲宽度调制变量清0
          qitingled=1;//关启停指示灯
          zhengzhuanled=1;//关正转指示灯
          fanzhuanled=1;//关反转指示灯
          xuanzeled=1;//关选择指示灯
          zhengzhuanflag=0;//正转标志位变量为0
          fanzhuanflag=0;//反转标志位变量为0
          motor1flag=0;//电机1启动标志位变量置0
          motor2flag=0;//电机2启动标志位变量置0
          motor1_pwm_flag=0;//电机1脉冲宽度调制标志位变量
          motor2_pwm_flag=0;//电机2脉冲宽度调制标志位变量
          IN1=0;//L298M芯片控制端IN1置低电平,电机不运转。
          IN2=0;//L298M芯片控制端IN2置低电平,电机不运转。
          IN3=0;//L298M芯片控制端IN3置低电平,电机不运转。
          IN4=0;//L298M芯片控制端IN4置低电平,电机不运转。
    //    shumaguannodisplay(qian,bai,shi,ge);//数码管无显示函数
         }
        }
       }
       if(qitingnum==1)//判断启停键是否第一次按下
     {     
        if(xuanze==0)//判断选择键是否第一次按下
      {
            delay(5);
         if(xuanze==0)//再次判断选择键是否按下
       {
          TR0=1;
          xuanzeled=0;//选择指示灯
          xuanzenum++;//选择次数变量自加
          motor1flag=1;//电机1启动标志位变量置1
          motor2flag=0;//电机2启动标志位变量置0
          motor1_pwm_flag=1;//电机1脉冲宽度调制标志位变量置1
          motor2_pwm_flag=0;//电机1脉冲宽度调制标志位变量置0
          zhengzhuanled=1;//关正转指示灯
          fanzhuanled=1;//关反转指示灯
          IN3=0;//L298M芯片控制端IN3置低电平,电机不运转。
          IN4=0;//L298M芯片控制端IN4置低电平,电机不运转。
          while(!xuanze);//选择键释放
         }
        }
         if(xuanzenum==2)//判断选择次数变量是否为2 
       {  
    //    TR0=0;
    //    Time0num=0;//定时器0定时计数变量清0
    //    pwm=0;//脉冲宽度调制变量清0
          xuanzenum=0;//选择次数变量清0
          motor1flag=0;//电机1启动标志位变量置1
          motor2flag=1;//电机2启动标志位变量置0
          motor1_pwm_flag=0;//电机1脉冲宽度调制标志位变量置0
          motor2_pwm_flag=1;//电机1脉冲宽度调制标志位变量置1
          xuanzeled=1;//关选择指示灯
          zhengzhuanflag=0;//正转标志位变量为0
          fanzhuanflag=0;//反转标志位变量为0
          zhengzhuanled=1;//关正转指示灯
          fanzhuanled=1;//关反转指示灯
          IN1=0;//L298M芯片控制端IN1置低电平,电机不运转。
          IN2=0;//L298M芯片控制端IN2置低电平,电机不运转。
         }     
         if(motor1flag==1&&motor2flag==0&&motor1_pwm_flag==1)//判断电机1启动标志位变量是否置1,电机2启动标志位变量是否置0 ,电机1脉冲宽度调制标志位变量置1,此处为电机1正反转。
       {
          if(zhengzhuan==0)//判断是否按下正转键
        {
    //     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
           delay(5);
           if(zhengzhuan==0)//再次判断是否按下正转
         {
    //      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
            zhengzhuanled=0;//开正转指示灯
            fanzhuanled=1;//关反转指示灯
            zhengzhuanflag=1;//正转标志位变量为1
            fanzhuanflag=0;//反转标志位变量为0
            IN1=0;//L298N芯片控制端IN1置高电平
            IN2=1;//L298N芯片控制端IN2置低电平
            while(!zhengzhuan);//正转键释放
           }
          }
          if(fanzhuan==0)//判断是否按下反转键
        {
    //     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
           delay(5);
           if(fanzhuan==0)//再次判断是否按下反转键
         {
    //      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
            zhengzhuanled=1;//关正转指示灯
            fanzhuanled=0;//开反转指示灯
            zhengzhuanflag=0;//正转标志位变量为0
            fanzhuanflag=1;//反转标志位变量为1
            IN1=1;//L298N芯片控制端IN1置低电平
            IN2=0;//L298N芯片控制端IN2置高电平
            while(!fanzhuan);//反转键释放
           }
          }
         }
         if(motor1flag==0&&motor2flag==1&&motor2_pwm_flag==1)//判断电机1启动标志位变量是否置0,电机2启动标志位变量是否置1 ,电机2脉冲宽度调制标志位变量置1,此处为电机2正反转。
       {
          if(zhengzhuan==0)//判断是否按下正转键
        {
    //     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
           delay(5);
           if(zhengzhuan==0)//再次判断是否按下正转
         {
    //      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
            zhengzhuanled=0;//开正转指示灯
            fanzhuanled=1;//关反转指示灯
            zhengzhuanflag=1;//正转标志位变量为1
            fanzhuanflag=0;//反转标志位变量为0
            IN3=0;//L298N芯片控制端IN3置高电平
            IN4=1;//L298N芯片控制端IN4置低电平
            while(!zhengzhuan);//正转键释放
           }
          }
          if(fanzhuan==0)//判断是否按下反转键
        {
    //      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
           delay(5);
           if(fanzhuan==0)//再次判断是否按下反转键
         {
    //      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
            zhengzhuanled=1;//关正转指示灯
            fanzhuanled=0;//开反转指示灯
            zhengzhuanflag=0;//正转标志位变量为0
            fanzhuanflag=1;//反转标志位变量为1
            IN3=1;//L298N芯片控制端IN3置低电平
            IN4=0;//L298N芯片控制端IN4置高电平
            while(!fanzhuan);//反转键释放
           }
          }
         }
         if(zhengzhuanflag==1||fanzhuanflag==1)//判断电机是否为正转或反转
       {
         if(jiasujian==0)//判断是否按下加速键
        {
    //   shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
          delay(5);
          if(jiasujian==0)//再次判断是否按下加速键
         {
    //     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
           if(pwm < 20)//判断脉冲宽度调制变量是否小于20
           pwm++;//脉冲宽度调制变量先赋值再加加 
           if(pwm >= 20)//判断脉冲宽度调制变量是否大于等于20
           pwm = 19;//脉冲宽度调制变量等于20 
           while(!jiasujian);//加速键释放                                 
          }
         }
         if(jiansujian==0) //判断是否按下减速键
        {
    //    shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
          delay(5);
          if(jiansujian==0)//再次判断是否按下减键
         {
    //     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
           if(pwm > 0)//判断脉冲宽度调制变量是否大于0
           pwm--;//脉冲宽度调制变量先赋值再减减 
           if(pwm <= 0)//判断脉冲宽度调制变量是否小于等于0
           pwm = 0;//脉冲宽度调制变量等于0 
           while(!jiansujian);//减速键释放
          }
         }
        }
       }
      }
    //  void shumaguandisplay(uint qian,uint bai,uint shi,uint ge)//数码管显示函数
    //{
    //   duan=1;//开数码管段码端口                      
    //   P0=table[qian];//数码千位显示
    //   duan=0;//关数码管段码端口
    //   P0=0x00;//关数码管段码显示
    //   wei=1;//开数码管位码端口
    //   P2=weima[0];//第1位数码管显示
    //   wei=0;//关数码管位码端口
    //   delay(1);//延时
    //   
    //   duan=1;//开数码管段码端口                      
    //   P0=table[bai];//数码百位显示
    //   duan=0;//关数码管段码端口
    //   P0=0x00;//关数码管段码显示
    //   wei=1;//开数码管位码端口
    //   P2=weima[1];//第2位数码管显示
    //   wei=0;//关数码管位码端口
    //   delay(1);//延时
    //
    //   duan=1;//开数码管段码端口                  
    //   P0=table[shi];//数码管十位显示
    //   duan=0;//关数码管段码端口
    //   P0=0x00;//关数码管段码显示
    //   wei=1;//开数码管位码端口
    //   P2=weima[2];//第3位数码管显示
    //   wei=0;//关数码管位码端口
    //   delay(1);//延时
    //
    //   duan=1;//开数码管段码端口                        
    //   P0=table[ge];//数码管个位显示
    //   duan=0;//关数码管段码端口
    //   P0=0x00;//关数码管段码显示
    //   wei=1;//开数码管位码端口
    //   P2=weima[3];//第4位数码管显示
    //   wei=0;//关数码管位码端口
    //   delay(1);//延时     
    // }
    //  void shumaguannodisplay(uint qian,uint bai,uint shi,uint ge)//数码管显示函数
    //{
    //   duan=1;//开数码管段码端口  
    //   P0=table[qian];//数码千位显示
    //   duan=1;//关数码管段码端口
    //   P0=0x00;//关数码管段码显示
    //   wei=1;//开数码管位码端口
    //   P2=weima[0];//第1位数码管显示
    //   wei=1;//关数码管位码端口
    //   delay(1);//延时
    //   
    //   duan=1;//开数码管段码端口                      
    //   P0=table[bai];//数码百位显示
    //   duan=1;//关数码管段码端口
    //   P0=0x00;//关数码管段码显示
    //   wei=1;//开数码管位码端口
    //   P2=weima[1];//第2位数码管显示
    //   wei=1;//关数码管位码端口
    //   delay(1);//延时
    //
    //   duan=1;//开数码管段码端口                  
    //   P0=table[shi];//数码管十位显示
    //   duan=1;//关数码管段码端口
    //   P0=0x00;//关数码管段码显示
    //   wei=1;//开数码管位码端口
    //   P2=weima[2];//第3位数码管显示
    //   wei=1;//关数码管位码端口
    //   delay(1);//延时
    //
    //   duan=1;//开数码管段码端口                        
    //   P0=table[ge];//数码管个位显示
    //   duan=1;//关数码管段码端口
    //   P0=0x00;//关数码管段码显示
    //   wei=1;//开数码管位码端口
    //   P2=weima[3];//第4位数码管显示
    //   wei=1;//关数码管位码端口
    //   delay(1);//延时     
    // }
      void main()//主函数
    {
       TimerInit();//定时器初始化函数
       ENA=0;
       ENB=0;
       IN1=0;//L298M芯片控制端IN1置低电平,电机不运转。
       IN2=0;//L298M芯片控制端IN2置低电平,电机不运转。
       IN3=0;//L298M芯片控制端IN3置低电平,电机不运转。
       IN4=0;//L298M芯片控制端IN4置低电平,电机不运转。
       while(1)//死循环
     {
        KeyScan();//按键扫描函数
    //  if(qitingnum==1)//判断启停键是否第一次按下
    //  shumaguandisplay(qian,bai,shi,ge);//数码管显示函数
      }
     }

  • 相关阅读:
    装饰器的进阶
    Django admin组件应用
    AJAX
    Cookie、Session和自定义分页
    Django中ORM介绍和字段及字段参数
    Django 框架
    Django之视图
    Django之路由系统
    Django ORM相关操作
    Django 模板语言
  • 原文地址:https://www.cnblogs.com/AChenWeiqiangA/p/12919752.html
Copyright © 2020-2023  润新知