精华内容
下载资源
问答
  • 测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程测速 汇编程...
  • 本文介绍的速度与里程表设计以单片机光电传感器为核心。传感器将不同车速转变成的不同频率的脉冲信号输入到单片机进行控制与计算,再采用led模块进行显示,使得电动自行车的速度与里程数据能直观的显示给使用者。
  •  本文介绍的速度与里程表设计以单片机光电传感器为核心。传感器将不同车速转变成的不同频率的脉冲信号输入到单片机进行控制与计算,再采用led模块进行显示,使得电动自行车的速度与里程数据能直观的显示给使用者...
  • 本文介绍的速度与里程表设计以单片机光电传感器为核心。传感器将不同车速转变成的不同频率的脉冲信号输入到单片机进行控制与计算,再采用LED模块进行显示,使得电动自行车的速度与里程数据能直观的显示给使用者。...
  •  本文介绍的速度与里程表设计以单片机光电传感器为核心。传感器将不同车速转变成的不同频率的脉冲信号输入到单片机进行控制与计算,再采用LED模块进行显示,使得电动自行车的速度与里程数据能直观的显示给使用者...
  • 基于单片机光电传感器的显示电动自行车速度里程表设计,还是比较具体的。。
  • 本文介绍的速度与里程表设计以单片机光电传感器为核心。传感器将不同车速转变成的不同频率的脉冲信号输入到单片机进行控制与计算,再采用LED模块进行显示,使得电动自行车的速度与里程数据能直观的显示给使用者。
  • 本文介绍的速度与里程表设计以单片机光电传感器为核心。传感器将不同车速转变成的不同频率的脉冲信号输入到单片机进行控制与计算,再采用LED模块进行显示,使得电动自行车的速度与里程数据能直观的显示给使用者。 ...
  • 本系统由信号预处理电路、单片机AT89C2051、系统化LED显示模块、串口数据存储电路和系统软件组成。
  • 基于光电传感器的转速测量系统设计 单片机 光电转速传感器 转速测量 数据处理。。
  • 反射式红外光电传感器检测引导线,使机器人沿轨道自主行走;使用霍尔集成片,通过计车轮转过的圈数完成机器人行走路程测量;接近开关可探测到轨道下埋藏的金属片,发出声光信息进行指示,并能实时显示金属片距起点的...
  • 采用Freescale公司的MC9SDG128单片机进行控制,使用ROHM公司生产的发送接收一体化反射型光电传感器RPR220,设计了一种新型迷宫机器人。该迷宫机器人能够在程序中严格控制光电传感器的开关,同时用软件消除外界干扰,...
  • 光电传感器.zip

    2021-03-03 12:17:58
    简单的单片机控制
  • 用89c51单片机控制的 用tcrt5000红外反射式光电传感器寻迹
  • 最近在做一个单片机小车,其中需要使用测速,于是在TT马达上加了一个20格的光栅,另外购买了对射式光电传感器。 光栅:;对射式光电传感器:; 光电传感器原理是在没有遮挡物时灯亮、高电平;有遮挡物时等灭、低...

    最近在做一个单片机小车,其中需要使用测速,于是在TT马达上加了一个20格的光栅,另外购买了对射式光电传感器。

    光栅:;对射式光电传感器:

    光电传感器原理是在没有遮挡物时灯亮、高电平;有遮挡物时等灭、低电平。

    一、初步的设计思路是采用外部上升沿或者下降沿中断来进行计数,从而达到测速目的

    当把光电传感器加到电路中时,发现在每次高低电平之间会产生几百个中断。检查了程序没问题,并用其他边沿信号测试中断无误后使用示波器测量传感器的信号。经查传感器信号在一次沿线时脉冲如下:

    实际波形就已经是有很多毛刺。

    二、增加CD40106施密特触发器来防止信号在临界状态时的抖动

    CD40106原理图如下:

    将电源和地接好之后把信号接入1脚,2脚为输出。实测波形如下:以下黄色信号为信号源,绿色信号为信号源过了施密特触发器后的信号(反向触发)。

    三、依然存在着抖动,并联电容进行对信号源滤波

    在信号源上并联一0.1uF电容对地(电容白条为负极,接地;电容另一条为正极,接信号)。

    经过电容滤波后的信号如下:(下图为2个输入信号,一起测量了)

    四、在未增加滤波电容之前和增加0.1uF电容后波形对比。

    2个视频我上传至B站,可供参考查看

    1.未增加电容滤波时输入信号和输出信号:

    对射式光电传感器增加电容过施密特触发器消抖

    2.增加电容滤波时输入信号和输出信号:

    对射式光电传感器增加电容过施密特触发器消抖

    这两个视频仅看通道1和通道2。通道3是把2出来的信号又过一次触发器出来的3;4是把3又过一次触发器出来的4。

    本人新建了个QQ群,如想进一步沟通可添加:947187213。

    展开全文
  • 引言  本文主要设计的是一辆自主识别道路的智能车。整个系统采用了16位单片机mc9s12dg128,模型车本身带有差速器和后轮驱动,需要设计完成基于单片机的自动...设计的两大重点,一是光电传感器的布局和电路设计,一是
  • 光电传感器测速仿真

    2013-03-12 13:33:45
    我的其他资源都是免费的,是对于c语言初学者的帮助比较大的,其中有单片机,ARM,数据结构,window编程。我也在学c语言,每当我写完一个程序,我都会免费发上来。
  •  车模与控制器构成一个自动控制系统,如图1,系统硬件以单片机为,配有传感器、执行机构以及它们的驱动电路,而信息处理与控制算法由单片机软件完成[1]。系统设计要求单片机把路径的迅速判断、相应的转向伺服电机...
  • 博文 详细介绍如何从零开始制作51单片机控制的智能小车(三)———用超声波模块和漫反射光电传感器实现小车的自动避障 的附件 包含博文介绍的完整的keil文件
  • 本设计主要针对现有测速系统结构复杂、价格贵以及稳定性不够等问题,采用槽型光电传感器,通过采样其产生的与直流电动小车齿轮相对应的脉冲信号,计算每分钟内脉冲信号的数目,即电机对应的转速值,直流电机驱动采用...
  •  对于红外光电传感器来说,相应于不同的路面条件(主要是黑白度),接收管接收到地面漫反射红外线后其两端电压将有所不同,即传感器接收管正对白色路面,则其电压较高,若正对黑色的路径标记线,则电压较低。...
  • 引言  本文主要设计的是一辆自主识别道路的智能车。整个系统采用了16位单片机mc9s12dg128,模型车本身带有差速器和后轮驱动,需要设计完成基于单片机的自动控制...设计的两大重点,一是光电传感器的布局和电路设计,
  • 本文是根据第三届全国大学生“飞思卡尔”...整个系统采用了组委会提供的16位单片机mc9s12dg128为核心,模型车本身带有差速器和后轮驱动,需要设计完成基于单片机的自动控制系统使得模型车在封闭的跑道上自主循线运行。
  •    我会通过本系列文章,详细介绍如何从零开始用51单片机去实现智能小车的控制,在本系列的上一篇文章中介绍了3种可用来让小车实现避障的传感器,本文作为本系列的第三篇文章,主要介绍如何让车实现自动避障。...

       我会通过本系列文章,详细介绍如何从零开始用51单片机去实现智能小车的控制,在本系列的上一篇文章中介绍了3种可用来让小车实现避障的传感器,本文作为本系列的第三篇文章,主要介绍如何让车实现自动避障。

    本系列文章链接:

    -----------------------------------------------------------------------------

       详细介绍如何从零开始制作51单片机控制的智能小车(一)———让小车动起来
       详细介绍如何从零开始制作51单片机控制的智能小车(二)———超声波模块、漫反射光电管、4路红外传感器的介绍和使用
       详细介绍如何从零开始制作51单片机控制的智能小车(三)———用超声波模块和漫反射光电传感器实现小车的自动避障
       详细介绍如何从零开始制作51单片机控制的智能小车(四)———通过蓝牙模块实现数据传输以及通过手机蓝牙实现对小车运动状态的控制
       详细介绍如何从零开始制作51单片机控制的智能小车(五)———对本系列第四篇文章介绍的手机蓝牙遥控加减速异常的错误的介绍及纠正

    -----------------------------------------------------------------------------

    一、避障思路及传感器的选择

       1、利用4路红外寻迹避障传感器模块实现避障

       可以让一路传感器检测左边的障碍物,一路传感器检测右边的障碍物,两路传感器检测前方的障碍物,如下图所示:

       这种方法呢实现起来是最简单的,对于0基础的可以尝试一下,障碍物检测距离一般在20cm左右,在车速不太快,而且在室内(也就是无阳光直射)时是可行的,也可以很好的实现避障。

       缺点呢或者说不足之处,也就很明确了,在室外(或者阳光直射时)传感器受阳光干扰可能不能正常工作,检测距离20cm左右,车速过快时,在检测到障碍物时,不能直接转弯(因为车速过快,还没来得及转弯可能就撞上了),需要往回倒一下,再转弯。

       2、利用4个漫反射光电传感器模块实现避障

       可以让一个传感器检测左边的障碍物,一个传感器检测右边的障碍物,两路传感器检测前方的障碍物。就像上面的4路红外寻迹避障传感器的摆放方向一样

       这种方法呢,避障思路跟利用4路红外寻迹避障传感器模块实现避障是相同的,只是换了传感器类型而已,但是漫反射光电传感器抗阳光干扰能力强,克服了4路红外寻迹避障传感器模块在室外(或者阳光直射时)传感器受阳光干扰可能不能正常工作的缺点。

       缺点呢或者说不足之处,检测距离也在20cm附近,依然没能克服车速过快时,在检测到障碍物时,不能直接转弯的不足,而且呢漫反射光电传感器模块体积、重量、价格都要高一些。

       3、利用超声波模块和舵机云台实现避障

       避障思路呢大体是这样的,正常情况下超声波模块检测前方障碍物,当检测到障碍物时,小车停止前行,舵机云台转动,让超声波模块分别转向小车的左右两侧检测左右两侧是否有障碍物,来决定下一步的转向,超声波模块重新超前,开始转向。

       这种方法呢,利用超声波模块测距远,一般常见的超声波模块测距最远在4.5米左右,完全不用担心车速过快来不及反应的情况,而且基本不受阳光干扰(当环境温度升高时,声音的传播速度会加快,对测距产生一定的误差,但是误差很小很小,对于超声波模实现避障来说完全可以忽略)也就是说超声波模块很好的解决了以上两个问题

       缺点呢或者说不足之处,也很明确,从避障思路我们可以看出这种方案小车不能连续的运动,当遇到障碍物时,小车就会停下来判断下一步该往哪个方向转弯,除此之外,超声波模块用起来比前两种难一些

       4、利用超声波模块和2个漫反射光电传感器实现避障(也就是本文采用的方法)

       避障思路呢就是利用超声波模块检测前面的障碍物,两个漫反射光电传感器分别检测左右两侧的障碍物。

       这种思路结合了这两种传感器的优点,互补了他们的不足,即同时克服阳光直射时传感器不能正常工作、车速过快时,在检测到障碍物时,不能直接转弯、遇到障碍物需要停车判断 这三种不足可以说是一种比较理想的方案。唯一的缺点呢,就是超声波模块本身用起来难度要大一些,当然对富有挑战精神的人,也就不算缺点了

    二、超声波测距程序的编写

       1、概述

       我将在本系列第一篇博文中介绍的程序的基础上进行超声波测距程序的编写的介绍,前提是理解超声波模块的测距的工作流程(不明白的可以去看本系列第二篇文章的介绍),我们需要用到两个定时器,而STC89C52单片机只有两个定时器,前面呢我们已经把定时器0中断用来控制电机的PWM输出,所以我们把超声波测距的启动信号也合并到定时器0里面,让定时器1来检测超声波模块有无信号返回。

       2、I/O口触发测距的实现程序的编写

       超声波模块工作的第一步呢就是让块Trig 管脚所接的单片机I/O口置为高电平,而且需要持续10us以上,(本例中我采用的是让单片机P14 I/O口 接在了超声波模块的Trig 管脚上,让单片机P15 I/O口 接在了超声波模块的Echo管脚上,大家可以根据实际情况自己选择,只要跟程序对应起来就行),此处有一点需要注意就是为了避免下一次超声波模块发出的信号,对上一次的返回信号产生影响,超声波模块发出信号的时间间隔要在60ms以上,本例中我配置的定时器0是每1ms产生一次中断,设置一个变量HC_SR04_time,定时器0每产生一次中断,该变量累加1,每当加到250时,让该变量清零,同时让超声波模块发出检测信号,也就是说每250ms 超声波模块发出一次检测信号(数值呢大家可以自行调节),发出检测信号只需要让Trig为高电平并且持续10us以上 ,再让Trig为低电平,这样超声波模块就会自动发出一次检测信号了,我把这个过程写在函数StartModule() 里面本部分相关程序如下:
    sbit Trig= P1^4; //产生脉冲引脚
    sbit Echo= P1^5; //回波引脚
    
    void  StartModule() 		         //启动超声波模块
      {
    	  Trig=1;			                
    	  _nop_();     //此语句是空语句,用来延时,也就是满足高电平持续10us以上的要求
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_();
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_();
    	  Trig=0;
      }
    
    void Timer0Init()      //定时器0初始化函数
    {
    	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
    
    	TH0=0XFC;	//给定时器赋初值,定时1ms
    	TL0=0X18;	
    	ET0=1;//打开定时器0中断允许
    	EA=1;//打开总中断
    	TR0=1;//打开定时器			
    }
    
    void timer0()interrupt 1 using 2   //定时器0中断函数
    { 
    TH0=0XFC;	//给定时器赋初值,定时1ms
    TL0=0X18;
    time++; 
    pwm_val_left++; 
    pwm_val_right++; 
    pwm_out_left_moto(); 
    pwm_out_right_moto(); 
    	
    //以下内容是新加的:
    HC_SR04_time++;
    if(HC_SR04_time>=250)   //250ms 启动一次超声波测距
    {
    	HC_SR04_time=0;
    	StartModule();
    }
    } 
    

       3、检测有无障碍物的程序编写以及检测距离的调节方法

       上面呢我们已经利用定时器0来通过 Trig口让超声波模块每250ms发出一次检测信号,接下来我们需要用定时器1来检测有没有信号返回,也就是前方有没有障碍物,怎么实现呢,通过前面的介绍我们知道,只要Echo管脚为高电平就有信号返回,通过定时器1来测量高电平持续的时间,通过公式:测试距离=(高电平时间*声速(340M/s)/2) 就可以计算障碍物距离传感器的距离了,当Echo变为高电平时,就让定时器1清零,并打开定时器1,开始计数,当Echo变为0时,利用公式计算障碍物距离,计算完后令定时器1清零 并关闭定时器1 这样只要有信号返回,即只要Echo被置为1 定时器1就会被及时的清零,也就不会触发定时器1溢出中断,若是没有信号返回(也就是没有障碍物,或者障碍物超出了传感器的测量范围,本文用的传感器测量最大值为4.5米),Echo就不会被置1,定时器1也就不会被清零,从而产生溢出中断,在溢出中断里放一个变量flag ,若产生中断则让其置1,这样就通过定时器是否产生溢出中断,即flag是否为1,来判断是否检测到障碍物了。
       有一点需要注意,这样检测的是距离传感器最大检测距离内有无障碍物,但是我们把它用来让小车避障,我不能距离障碍物4.5米就让小车转弯吧,这就需要通过程序调节检测距离了,只需要增加一个判断条件就行了,我们利用公式算出来障碍物的距离S ,将flag=1或者S>我们设定的检测距离,都视为没有障碍物处理就可以了,如 if(flag==1||S>50) 就是把50cm作为检测距离,检测的是50cm内有无障碍物,50呢是暂定的,在后期调车的时候,根据实际情况进行调节
       本部分有关程序如下(完整的工程文件会在介绍完避障程序后一并给出):
    void Timer1Init()   //定时器1初始化
    {
    	TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。
    	TH1=0;	
    	TL1=0;	
    	ET1=1;//打开定时器1中断允许
    	EA=1;//打开总中断
    	TR1=1;//打开定时器			
    }
    
    void Timer1() interrupt 3   //定时器1溢出中断
    {
    	flag=1;    //若定时器1溢出则flag置1
    }
    
    
     void Conut(void)    //计算障碍物距离函数
    	{
    	 measure_time=TH1*256+TL1;
    	 TH1=0;
    	 TL1=0;
    	 S=(measure_time*1.87)/100;     //这就是计算距离的公式,参数1.87根据实际情况调节,算出来是CM
    	 if(flag==1||S>50)		    //超出测量或者超出设定的距离
    	 {
    	  flag=0;
    	 LED=1;         //此处是测试用的,我用的单片机在P00上接了个LED
    	 }
       else 
    	 LED=0;         
    	
    	}	
    
    void main()    //主函数
    	{
    	Timer0Init();
    	Timer1Init();	
    	Left_Speed_Ratio=5;   //设置左电机车速为最大车速的50%
    	Right_Speed_Ratio=5;	设置右电机车速为最大车速的50%
    	while(1)
    		{
    		
    			if(Echo==1)
    			{
    				TH1=0;	
    	            TL1=0;
    				TR1=1;			    //开启计数	
    				while(Echo);			//当RX为1计数并等待	
    				TR1=0;				//关闭计数	
    			    Conut();			//计算			
    		    }			
    //	run();
    //	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();				
    		}
    }
    

    三、自动避障的实现

       目前呢我们用于避障的传感器有检测左右两侧障碍物的漫反射光电管,检测前方障碍物的超声波模块,大体思路是这样的,当超声波模块没有检测到设定距离内的障碍物时,小车直行,当检测到前方障碍物时,若此时左边漫反射传感器没有检测到障碍物,则左转,当此时左边有障碍物时,若右边没有障碍物则右转,若右边也有障碍物则后退,大家看的可能比较乱,我整理成如下的逻辑表:
       表格中的有代表有障碍物,无代表无障碍物,X代表可以有也可以没有障碍物 若前方有障碍物则 M_sensor=0 没有则 M_sensor=1,若左侧有障碍物 ,则 L_sensor=0 ,没有则 L_sensor=1 若右侧有障碍物则 R_sensor=0 没有则 R_sensor=1,程序如下:
     if(M_sensor==1)
    				{  run(); }
    		  else
    			  {
    			      if(L_sensor==1)
    				       {     left();       }
    			
    			      else if(R_sensor==1)
    				       {    right() ;      }
    			      else
    						   {    back();          }
    			
    			 }
    	
    
       在测试中我发现,当电池电量较低时,原来的转弯方式(一侧电机停转,另一侧电机前进)转弯效率较低,所以说把转弯的函数修改为一侧后退,另一侧前进,代码如下:
    void left(void)   //小车左转
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio;
    Right_moto_go(); 
    Left_moto_back();
    } 
    
     void right(void) //小车右转
    { 
    push_val_left =Left_Speed_Ratio;
    push_val_right =Right_Speed_Ratio;
    Right_moto_back();
    Left_moto_go();
    
       经过测试后,这种方案呢并没有理想的那么好,因为超声波模块存在一些缺陷,比如偶然会产生误判,明明前方什么障碍物都没有,会在一瞬间突然检测到障碍物,又突然消失,而且在以下两种情况下检测不到障碍物
       如上图的这种情况呢,超声波模块检测不到返回的信号,产生误判
       如上图的这种情况呢,超声波模块检测不到侧前方的细柱型障碍物,产生误判
        以上两种缺陷呢,是超声波模块固有的缺陷,是无法通过超声波模块本身去纠正的,解决方法呢,可以在超声波模块的两侧分别再加一个朝前的检测前方障碍物的漫反射光电传感器,这样呢可以克服以上的几个缺陷,经过我的实际测试,漫反射光电传感器几乎不会产生误判,除了检测距离有点短之外,可以说是比较好的,这样呢就是4路漫反射光电传感器为主,超声波模块呢只是辅助检测前方的较远的的障碍物,补充漫反射传感器检测距离有限的缺陷,这种方案呢我就不详细介绍了,有兴趣的可以自己尝试一下

    四、完整的各文件代码

       main.c文件

    #include <car.h>
    
    extern unsigned char Left_Speed_Ratio;
    extern unsigned char Right_Speed_Ratio;
    unsigned int time=0; 
    unsigned int HC_SR04_time=0;
    extern unsigned char pwm_val_left;
    extern unsigned char pwm_val_right;
     bit   flag =0;
    extern char M_sensor;  
     
    void delay1s(void)   
    {
        unsigned char a,b,c;
        for(c=167;c>0;c--)
            for(b=171;b>0;b--)
                for(a=16;a>0;a--);
        _nop_();  
    }
    void delay1ms(void)   
    {
        unsigned char a,b,c;
        for(c=1;c>0;c--)
            for(b=142;b>0;b--)
                for(a=2;a>0;a--);
    }
    
    void Timer0Init()
    {
    	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
    
    	TH0=0XFC;	//给定时器赋初值,定时1ms
    	TL0=0X18;	
    	ET0=1;//打开定时器0中断允许
    	EA=1;//打开总中断
    	TR0=1;//打开定时器			
    }
    
    void Timer1Init()
    {
    	TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。
    	TH1=0;	
    	TL1=0;	
    	ET1=1;//打开定时器1中断允许
    	EA=1;//打开总中断
    	TR1=1;//打开定时器			
    }
    
    void timer0()interrupt 1 using 2 
    { 
    TH0=0XFC;	//给定时器赋初值,定时1ms
    TL0=0X18;
    time++; 
    pwm_val_left++; 
    pwm_val_right++; 
    pwm_out_left_moto(); 
    pwm_out_right_moto(); 
    	
    HC_SR04_time++;
    if(HC_SR04_time>=300)   //300ms 启动一次超声波测距
    {
    	HC_SR04_time=0;
    	StartModule();
    }
    } 
    
    void Timer1() interrupt 3
    {
    	flag=1;    //若定时器1溢出则flag置1
    }
    
    
    
    void main()
    	{
    	Timer0Init();
    	Timer1Init();	
    	Left_Speed_Ratio=6;   //设置左电机车速为最大车速的50%
    	Right_Speed_Ratio=6;	设置右电机车速为最大车速的50%
    	while(1)
    		{
    		
    			if(Echo==1)
    				{
    				TH1=0;	
    	      TL1=0;
    				TR1=1;			    //开启计数	
    				while(Echo);			//当RX为1计数并等待	
    				TR1=0;				//关闭计数	
    			  Conut();			//计算		
    			}
    				
    		  if(M_sensor==1)
    				{  run(); }
    		  else
    			  {
    			      if(L_sensor==1)
    				       {     left();       }
    			
    			      else if(R_sensor==1)
    				       {    right() ;      }
    			      else
    						   {    back();          }
    			
    			 }
    	
    			
    			
    		}
    }
    
    
    

       motor_control.c文件

    #include <car.h>
    
    
    unsigned char pwm_val_left =0;
    unsigned char push_val_left =0; 
    unsigned char pwm_val_right =0;
    unsigned char push_val_right=0;
    unsigned char Left_Speed_Ratio;
    unsigned char Right_Speed_Ratio;
    
    bit Left_moto_stop =1;
    bit Right_moto_stop =1;
    
    
    void Left_moto_go()  //左电机正转
    {p34=0;p35=1;} 
    void Left_moto_back() //左电机反转
    {p34=1;p35=0;} 
    void Left_moto_stp()  //左电机停转
     {p34=1;p35=1;} 
    void Right_moto_go()  //右电机正转
    {p36=0;p37=1;} 
    void Right_moto_back() //右电机反转
    {p36=1;p37=0;}  
    void Right_moto_stp()  //右电机停转
    {p36=1;p37=1;} 
    
    
    void pwm_out_left_moto(void)    //左电机PWM
    { 
    if(Left_moto_stop) 
    { 
    if(pwm_val_left<=push_val_left) 
    Left_moto_pwm=1; 
    else 
    Left_moto_pwm=0; 
    if(pwm_val_left>=10) 
    pwm_val_left=0; 
    } 
    else 
    Left_moto_pwm=0; 
    } 
    
    void pwm_out_right_moto(void)    //右电机PWM
    { 
    if(Right_moto_stop) 
    { 
    if(pwm_val_right<=push_val_right) 
    Right_moto_pwm=1; 
    else 
    Right_moto_pwm=0; 
    if(pwm_val_right>=10) 
    pwm_val_right=0; 
    } 
    else 
    Right_moto_pwm=0; 
    } 
    
    
    void run(void)     //小车前行
    { 
    push_val_left =Left_Speed_Ratio;    
    push_val_right =Right_Speed_Ratio; 
    Left_moto_go(); 
    Right_moto_go(); 
     } 
    
     
    
    void back(void)   //小车后退
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_back();
    Right_moto_back();
     } 
    
    
    
    void left(void)   //小车左转
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio;
    Right_moto_go(); 
    Left_moto_back();
    } 
    
     void right(void) //小车右转
    { 
    push_val_left =Left_Speed_Ratio;
    push_val_right =Right_Speed_Ratio;
    Right_moto_back();
    Left_moto_go();
    } 
    
    void stop(void)  //小车停止
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_stp();
    Right_moto_stp();
     } 
    
    void rotate(void) //小车原地转圈
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_back();
    Right_moto_go();
     } 
    
    
    
    

       HC_SR04.c文件

    #include <car.h>
    
    float  S=0;
    extern bit  flag;
    unsigned int  measure_time;
    char M_sensor; 
     void  StartModule() 		         //启动超声波模块
      {
    	  Trig=1;			                
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_();
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_(); 
    	  _nop_();
    	  Trig=0;
      }
    	
     void Conut(void)
    	{
    	 measure_time=TH1*256+TL1;
    	 TH1=0;
    	 TL1=0;
    	 S=(measure_time*1.87)/100;     //算出来是CM
    	 if(flag==1||S>50||S<2)		    //超出测量
    	 {
    	  flag=0;
    	 LED=1;
    	 M_sensor=1;
    	 }
       else
    		 {
    	 LED=0;
    	 M_sensor=0;
    		 }
    	}	
    
    	
    
    
    

       car.h文件

    #ifndef __car_H
    #define __car_H
    
    #include <reg52.h>
    #include <intrins.h>
    
    sbit Left_moto_pwm=P1^6 ;
    sbit Right_moto_pwm=P1^7;
    sbit p34=P3^4;
    sbit p35=P3^5; 
    sbit p36=P3^6;
    sbit p37=P3^7;
    sbit Trig= P1^4; //产生脉冲引脚
    sbit Echo= P1^5; //回波引脚
    sbit LED=P0^0;
    sbit L_sensor=P2^0;
    sbit R_sensor=P2^1;
    void Left_moto_go() ;
    void Left_moto_back() ;
    void Left_moto_stp() ;
    void Right_moto_go();
    void Right_moto_back(); 
    void Right_moto_stp(); 
    void delay(unsigned int k) ;
    void delay1s(void) ;
    void delay1ms(void);
    void pwm_out_left_moto(void) ;
    void pwm_out_right_moto(void);
    void run(void);
    void back(void);
    void left(void);
    void right(void);
    void stop(void);
    void rotate(void);
    void  StartModule() ;
    void Timer1Init();
    void Timer0Init();
    void Conut(void);
    
    
    #endif
    

       本文到这里就结束了,本文介绍的内容的完整的keil文件会放在附件里,需要者自取,我放的时候都是免费的,但是过段时间它会自己涨…需要的在评论区留言我可以直接发给你,欢迎大家继续阅读本系列的后续文章“详细介绍如何从零开始制作51单片机控制的智能小车(四)———通过蓝牙模块实现数据传输以及对小车状态的控制”
       欢迎大家积极交流,本文未经允许谢绝转载

    展开全文
  • 测量电机的速度,同样可以作为测速使用。本程序原理是:在电机上安装个编码盘,通过光电管在转动的编码盘感应出一连串的脉冲,通过单片机计算每秒钟输入脉冲的个数就可以得出电机的转速。
  • 使用时把右手食指指肚放在st188反射式红外传感器上,放置合适时会看到指示灯随心跳同时闪动,如果没有闪烁请适当调节手指压力,调节完后在测试过程中手指压力不要变,保持稳定,当指示灯有规律闪烁时表示信号正确。...

    原文地址::http://www.51hei.com/bbs/dpj-156743-1.html

    相关文章

    1、ST188----https://wenku.baidu.com/view/e31e9c956bec0975f465e258.html

     

    使用时把右手食指指肚放在st188反射式红外传感器上,放置合适时会看到指示灯随心跳同时闪动,如果没有闪烁请适当调节手指压力,调节完后在测试过程中手指压力不要变,保持稳定,当指示灯有规律闪烁时表示信号正确。当单片机检测到大约第五次信号时开始显示这五次信号算出的平均心率。当超过大约1.5秒没有检测到信号,清除心率。
    如果手指抖动或者不稳定会看到指示灯乱闪,这样测得的数据不准,在测试过程中保持稳定!

    1:初始化液晶和定时器
    2:检测外部中断,并记录中断时间间隔
    3:当有超过5个符合要求的时间记录,算出5个时间的平均值和对应的60s的心率并显示
    4:当超过1.5s没有检测到中断发生停止显示
    2-3-4循环

    电路原理图如下:
    0.png

    单片机源程序如下:

    1. #include<reg52.h>
    2. #define uint unsigned int
    3. #define uchar unsigned char
    4. sbit rs=P1^0;                             //数据与命令选择控制引脚
    5. sbit rw=P1^1;                                 //读与写选择控制引脚
    6. sbit en=P1^2;                                 //使能择控制引脚
    7. sbit bf=P0^7;                                 //忙标志位
    8.  
    9. sbit P32=P3^2;
    10.  
    11. unsigned char i=0,timecount=0,displayOK=0,rate=0,aa=0;
    12. unsigned int time[6]={0};
    13.  
    14. /************ 延时函数  *****************/
    15. void delay(uint z)
    16. {
    17.    while(z--);
    18. }
    19. /************ 忙检测函数  *****************/
    20. void jiance()
    21. {
    22.   P0=0xff;
    23.   rs=0;rw=1;en=1;
    24.   while(bf);                        //如果BF==1表示液晶在忙
    25.   en=0;
    26. }
    27. /************ 写命令函数  *****************/
    28. void write_com(uchar com)
    29. {
    30.    jiance();
    31.    P0=com;
    32.    rs=0;rw=0;en=1;
    33.    delay(2);
    34.    en=0;
    35. }
    36. /************ 写数据函数  *****************/
    37. void write_dat(uchar dat)
    38. {
    39.    jiance();
    40.    P0=dat;
    41.    rs=1;rw=0;en=1;
    42.    delay(2);
    43.    en=0;
    44. }
    45. /************ 1602液晶初始化函数  *****************/
    46. void init_lcd()
    47. {
    48.    write_com(0x38);           // 设置16*2显示,5*7点阵,8位数据接口
    49.    write_com(0x0c);           // 开显示,不显示光标
    50.    write_com(0x06);           // 地址加1,当写入数据的时候光标右移
    51.    write_com(0x01);           //清屏
    52. }
    53.  
    54. /******************************************************************/
    55. /*                   在指定位置写字符                                 */
    56. /******************************************************************/
    57. void LCD_write_char(unsigned char x,unsigned char y,unsigned char Data)
    58. {     
    59.     if (y == 0)  
    60.     write_com(0x80 + x);     
    61.     else     
    62.     write_com(0xC0 + x);            
    63.     write_dat(Data);  
    64. }
    65. void DelayMs(unsigned int z)
    66. {
    67.    unsigned int x;
    68.    for(;z>0;z--)
    69.      for(x=110;x>0;x--);
    70. }         
    71. void main()
    72. {
    73.                 P32=1;
    74.                 init_lcd();//lcd初始化
    75.                 TCON=0x01;//设置外部中断0
    76.                 EX0=1;
    77.                 TMOD=0x01;//定时器0初始化
    78.                 TH0=(65536-50000)/256;//实测每50ms中断的定时值
    79.                 TL0=(65536-50000)%256;
    80.                 ET0=1;//开定时器中断
    81.                 //显示基本文字
    82.                 LCD_write_char(3,0,'H');
    83.                 LCD_write_char(4,0,'e');
    84.                 LCD_write_char(5,0,'a');
    85.                 LCD_write_char(6,0,'r');
    86.                 LCD_write_char(7,0,'t');
    87.                 LCD_write_char(8,0,' ');
    88.                 LCD_write_char(9,0,'R');
    89.                 LCD_write_char(10,0,'a');
    90.                 LCD_write_char(11,0,'t');
    91.                 LCD_write_char(12,0,'e');
    92.  
    93.                 LCD_write_char(8,1,'/');
    94.                 LCD_write_char(9,1,'m');
    95.                 LCD_write_char(10,1,'i');
    96.                 LCD_write_char(11,1,'n');
    97.                 TR0=0;//定时器停止
    98.                 EA=1;//开总中断
    99.                 while(1)
    100.                 {
    101.                                 
    102.                                 if(displayOK==1)
    103.                                 {
    104.                                                 rate=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5);
    105.                                                 LCD_write_char(5,1,rate/100+48);
    106.                                                 LCD_write_char(6,1,(rate%100)/10+48);
    107.                                                 LCD_write_char(7,1,rate%10+48);
    108.                                 }
    109.                                 DelayMs(300);
    110.                 }
    111. }
    112.  
    113. void ex0() interrupt 0
    114. {
    115.                 EX0=0;//暂时关外部中断
    116.                 if(timecount<8)   //当连续两次检测时间间隔小于8*50ms=400ms不处理
    117.                 {
    118.                                 TR0=1;//开定时器
    119.                 }
    120.                 else
    121.                 {
    122.                                 time[i]=timecount*50+TH0*0.256+TL0/1000;//算出间隔时间
    123.                                 TL0=(65536-50000)%256;//重新设置定时器
    124.                                 TH0=(65536-50000)/256;
    125.                                 timecount=0;//50ms计数清零
    126.                                 i++;
    127.                                 if(i==6)//记录到超过等于6次时间
    128.                                 {
    129.                                                 i=1;//计数从1开始
    130.                                                 displayOK=1;    //测得5次开始显示
    131.                                 }        
    132.                                 
    133.                 }
    134.                 EX0=1;
    135. }
    136. void et0() interrupt 1
    137. {
    138.                 TL0=(65536-50000)%256;
    139.                 TH0=(65536-50000)/256;
    140.                         
    141.                 timecount++;//每50ms一次计数
    142.                 if(timecount>25)     //当超过25*50ms=1.25s没有检测到信号停止显示
    143.                 {
    144.                                 i=0;//数据个数清零
    145.                                 timecount=0;//50ms计数清零
    146.                                 displayOK=0;//显示关
    147.                                 TR0=0;//定时器关
    148.                                 TH0=(65536-50000)/256;
    149.                                 TL0=(65536-50000)%256;
    150.                 }
    151. }
    152.  

    复制代码


    所有资料51hei提供下载:
     心率脉搏计源程序.rar (34.39 KB, 下载次数: 202)

     

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 522
精华内容 208
关键字:

单片机光电传感器