历史上的今天
返回首页

历史上的今天

今天是:2024年09月11日(星期三)

正在发生

2020年09月11日 | 基于51单片机PWM调速数码管显示测速

2020-09-11 来源:51hei

#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 IN1=P1^5;//位定义数码管段码端口

sbit IN2=P1^6;//位定义数码管位码端口

sbit ENA=P1^7;//位定义L298M芯片使能端ENA

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 zhuansuled=P3^7;//位定义转速指示灯

sbit waibuzhongduanling=P3^2; //外部中断0端口

uint qian,bai,shi,ge,zhuansu;//数码管千位变量、百位变量、十位变量、个位变量以及转速变量

uint maichongcount,Time0num,Time1num,pwm,qitingnum,zhengzhuanflag,fanzhuanflag;//脉冲计数变量、定时器0定时计数变量、定时器1定时计数变量、脉冲宽度调制变量、启停键按下数次变量、正转标志位变量、反转标志位变量

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 main()//主函数

{

   TimerInit();//定时器初始化函数

   IN1=0;//L298M芯片控制端IN1置低电平,电机不运转。

   IN2=0;//L298M芯片控制端IN2置低电平,电机不运转。

   while(1)//死循环

{

    KeyScan();//按键扫描函数

    if(qitingnum==1)//判断启停键是否第一次按下

    shumaguandisplay(qian,bai,shi,ge);//数码管显示函数

  }

}

  void delay(uint jishi)//延时函数

{

   uint i,j;

   for(i=jishi;i>0;i--)

    for(j=110;j>0;j--);

  }

  void TimerInit()//定时器初始化函数

{

   TMOD=0x11;//设定定时器为定时器0和定时器1,工作模式都为1。

   TH0=(65536-1000)/256;//TH0装初值为65536-100=65436,即定时100微妙,相当于0.1毫秒。

   TL0=(65536-1000)%256;//TL0装初值为65536-100=65436

   TH1=(65536-50000)/256;//TH1装初值为65536-50000=15536,即定时50000微妙,相当于50毫秒。

   TL1=(65536-50000)%256;//TL1装初值为65536-50000=15536

   EA=1;//全局中断允许

   ET0=1;//打开定时器0中断允许

   TR0=1;//开定时器0      

   EX0=1;//开外部中断0允许

   IT0=1;//设置外部中断0下降触发中断

   ET1=1;//打开定时器1中断允许

   TR1=1;//开定时器1

}

  void Time0() interrupt 1//定时器0定时函数,每0.1毫秒产生pwm波一次。

{      

   TH0=(65536-1000)/256;//TH0重装初值为65536-100=65436,即定时100微妙,相当于0.1毫秒。

   TL0=(65536-1000)%256;//TH0重装初值为65536-100=65436

   Time0num++;//定时器0定时计数变量先赋值再自加

   if(Time0num==20)//判断定时器0定时计数变量是否大于等于20,PWM波完整周期为20ms,定时器0定时计数变量Time0num数值越大,电机运转越快。

  {

    Time0num=0;//定时器0定时计数变量等于0

   }

   if(Time0num  {                              

    ENA=1;//L298M芯片使能端ENA置高电平,电机运转。

    zhuansuled=0;//开转速指示灯

   }

   else

  {

    ENA=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);//数码管显示函数做延时

    if(qitingjian==0)//再次判断启停键是否按下

   {

     while(!qitingjian)//启停键释放

     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数

     qitingnum++;//启停键按下数次变量先赋值再加加

     qitingled=0;//开启停指示灯

     if(qitingnum==2)//判断启停键按下数次变量是否为2

    {

      qitingnum=0;//启停键按下数次变量归零

      qitingled=1;//关启停指示灯

      zhengzhuanled=1;//关正转指示灯

      fanzhuanled=1;//关反转指示灯

      zhuansuled=1;//关转速指示灯

      zhengzhuanflag=0;//正转标志位变量为0

      fanzhuanflag=0;//反转标志位变量为0

      IN1=0;//L298M芯片控制端IN1置低电平,电机不运转。

      IN2=0;//L298M芯片控制端IN2置低电平,电机不运转。

      shumaguannodisplay(qian,bai,shi,ge);//数码管无显示函数

     }

    }

   }

   if(qitingnum==1)//判断启停键是否第一次按下

  {     

    if(zhengzhuan==0)//判断是否按下正转键

   {

     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时

     if(zhengzhuan==0)//再次判断是否按下正转

    {

      while(!zhengzhuan)//正转键释放

      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时

      zhengzhuanled=0;//开正转指示灯

      fanzhuanled=1;//关反转指示灯

      zhengzhuanflag=1;//正转标志位变量为1

      fanzhuanflag=0;//反转标志位变量为0

      IN1=1;//L298N芯片控制端IN1置高电平

      IN2=0;//L298N芯片控制端IN2置低电平

     }

    }

    if(fanzhuan==0)//判断是否按下反转键

   {

     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时

     if(fanzhuan==0)//再次判断是否按下反转键

    {

      while(!fanzhuan)//反转键释放

      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时

      zhengzhuanled=1;//关正转指示灯

      fanzhuanled=0;//开反转指示灯

      zhengzhuanflag=0;//正转标志位变量为0

      fanzhuanflag=1;//反转标志位变量为1

      IN1=0;//L298N芯片控制端IN1置低电平

      IN2=1;//L298N芯片控制端IN2置高电平

     }

    }

   }

    if(zhengzhuanflag==1||fanzhuanflag==1)//判断电机是否为正转或反转

   {

     if(jiasujian==0)//判断是否按下加速键

    {

      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时

      if(jiasujian==0)//再次判断是否按下加速键

     {

       while(!jiasujian)//加速键释放

       shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时

       if(pwm < 20)//判断脉冲宽度调制变量是否小于20

       pwm++;//脉冲宽度调制变量先赋值再加加

       if(pwm >= 20)//判断脉冲宽度调制变量是否大于等于20

       pwm = 19;//脉冲宽度调制变量等于20                                 

      }

     }

     if(jiansujian==0) //判断是否按下减速键

    {

      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时

      if(jiansujian==0)//再次判断是否按下减键

     {

       while(!jiansujian)//减速键释放

       shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时

       if(pwm > 0)//判断脉冲宽度调制变量是否大于0

       pwm--;//脉冲宽度调制变量先赋值再减减

       if(pwm <= 0)//判断脉冲宽度调制变量是否小于等于0

       pwm = 0;//脉冲宽度调制变量等于0

      }

     }

    }

   }

  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];//数码百位显示

推荐阅读

史海拾趣

捷嘉电子(Chequers Electronic)公司的发展小趣事

捷嘉电子在成立初期面临着巨大的挑战。那是一个智能电子产品刚刚开始兴起的时代,市场竞争激烈。公司创始人余文跃凭借对电子行业的深刻理解和对技术创新的执着追求,决定投身于智能控制器的研发与生产。在初创阶段,资金紧张、人才短缺、市场推广困难重重。但余文跃凭借着坚韧不拔的毅力,带领团队攻克了一个又一个技术难题,逐渐在市场上站稳了脚跟。

Elpakco Inc公司的发展小趣事

Elpakco Inc公司的创立,源于创始人对电子行业未来趋势的敏锐洞察。在电子科技日新月异的时代,创始人凭借在半导体封装领域的丰富经验和深厚技术积累,决定创立一家专注于高精度电子元件封装的公司。初创时期,资金紧张、技术难度大、市场竞争激烈,但创始人带领团队夜以继日地研发,不断突破技术瓶颈,终于成功研制出第一款高精度、高可靠性的电子封装产品,为公司的发展奠定了坚实的基础。

Freqtech Ohg公司的发展小趣事

随着全球对环保和可持续发展的重视,Freqtech Ohg公司积极响应,将绿色生产理念融入企业运营的每一个环节。公司引入先进的环保设备和生产工艺,减少生产过程中的能源消耗和废弃物排放。同时,Freqtech还加大了对可再生能源的投资力度,如建设太阳能发电站等,以降低企业运营对环境的影响。这些举措不仅提升了公司的社会形象,还为公司的长期发展奠定了坚实的环保基础。

Dynex公司的发展小趣事

面对电子行业快速迭代的市场环境,Freqtech Ohg公司敏锐地察觉到传统业务面临的挑战。公司果断决定进行业务转型升级,从单一的高频电子元件生产向系统解决方案提供商转变。通过整合上下游产业链资源,Freqtech成功开发出了一系列针对特定应用场景的高频电子系统解决方案,如5G通信基站、卫星导航系统等。这一转型不仅为公司带来了新的增长点,还进一步巩固了其在行业内的领先地位。

Delphi Connection Systems公司的发展小趣事

Delphi Connection Systems公司自创立之初,就致力于在电子行业中的连接器技术上进行创新。公司投入大量研发资源,开发出一种新型的高性能连接器,这种连接器具有更小的体积、更高的可靠性和更低的传输损耗。这一创新成果迅速获得了市场的认可,为公司带来了大量的订单和合作机会。

Fremont_Micro_Devices_USA公司的发展小趣事

面对日益激烈的市场竞争和客户需求的变化,Delphi Connection Systems公司积极推进数字化转型。公司引入先进的生产管理系统和智能化设备,实现了生产过程的自动化和智能化。这不仅提高了生产效率和质量稳定性,也降低了生产成本和人力需求。数字化转型使公司更加灵活和高效地应对市场变化,为未来的发展奠定了坚实基础。

问答坊 | AI 解惑

800米四通道遥控接收模块

手持式微型无线编码遥控模块的使用距离一般为50~100m,对某些需要四五百米甚至更远操作距离的应用场合,这类遥控模块便显得无能为力。     这里介绍一种800米四通道遥控接收模块,它的特点是:发射器内部采用了声表面谐振稳频 ...…

查看全部问答>

触摸屏增长迅速,魅力难挡

触摸屏增长迅速,正在激起激烈的竞争、推动着技术发展,以及引起OEM的兴趣。iSuppli公司曾经预测,2012年全球主要触摸屏技术的出货额将从2006年的24亿美元上升到44亿美元。面对如此高速增长、竞争和技术多样性,触摸屏产业正在快速进化。   ...…

查看全部问答>

6N137中VCC与VDD如何隔离

请哪位大虾告知下,6N137高速光电隔离芯片中的VCC与VDD在同一块PCB中如何进行隔离? 有没有简单的方法?或者专门的芯片?谢谢!…

查看全部问答>

PCB走线!

1:我的PCB设置了地层,主要是为了分开数字地和模拟地,那么我布放在顶层和底层的元件的地,还可以在顶层和底层走线么,这样走的话是不是地层的设置就没用了,还有如果在顶底层走线的话,我想加宽线宽,但是会和顶层和底层的信号线宽出现不一致,DR ...…

查看全部问答>

单片机入门教材

单片机入门教材…

查看全部问答>

准备做一个高度表,不过看来赶不上显摆了。

前一段开始跟大家一起骑车玩,出去几次突然想做一个可以利用气压传感器做的高度表 ,另外加上温湿度传感器。时间就不用了有码表。这样出去后就可以知道温度湿度还有大概的一个海拔高度。虽然气压传感器来做这个误差要大一点,不过银子有限还是就用 ...…

查看全部问答>

郁闷,网站图片、资料都杆儿屁了!

论坛内的旧帖,前辈们辛苦上穿的图片,压缩文件,全部 404 了啊!!! 搜索以前的资料,配图片的全部是 x ,看得一头雾水啊!!!怎么搞的嘛!…

查看全部问答>

你好,香版

                                 我看到STM32有VFQFPN36封装,但是我都没有见到过VFQFPN36封装是啥样子,能否给俺一个protel99的pcb封装图???&nb ...…

查看全部问答>

《STM32系列ARMCortex-M3微控器原理与实践》封面

书终于出来了,先把封面发给大家,我们拿到书后会给大家来申请。而且我们最新会做一个活动,详情请留意www.mxchip.com.…

查看全部问答>

【征文】学51经历

【征文】国庆学51经历  首先我的非常抱歉的说下,我竟然还不知道eeworld这个网站,实属抱歉,以后课余多关注下。国庆节都在协会学习51,正好看见上面一个帖子说可以 分享下学51感受,就来瞧瞧,跟大家分享!!  谈起我学51的经历,不得 ...…

查看全部问答>