瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块

    HC_SR04超声波测距模块是一个很常见的模块,瑞萨的驱动还不多见,就写了这个文章,当然这个模块使用起来是比较简单的,但大多数情况下大家都使用了阻塞性的代码如while(ECHO)什么的,这样看起了有点不优雅。这篇文章介绍一个无阻塞的实现方式。

    使用了两个定器一个100us的间隔定时器用于计算ECHO高电平时间当然这样只能精确到330*0.0001 = 0.033M = 3.3CM,如果你想要更高的精度你可以用一个更精确的间隔定时器。另一个定时器为一毫秒间隔定时器,作为全局时间变量。用了一个外部中断配置为both模式,上升沿下降沿多触发中断。用于检测echo高电平时间。开P13.0口用来调试。

//引脚接线
TRIG 接P0.0
ECHO 接外部中断INTP0(P13.7)
VCC-VCC
GND-GND

下图是代码生成器的配置:

瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块_第1张图片

瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块_第2张图片

瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块_第3张图片

瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块_第4张图片

瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块_第5张图片

瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块_第6张图片

瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块_第7张图片

下面是主函数代码,主要作用

就是每隔500MS触发一次,超声波传感器。

/***********************************************************************************************************************
* File Name    : r_main.c
* Version      : CodeGenerator for RL78/G13 V2.00.00.07 [22 Feb 2013]
* Device(s)    : R5F100LE
* Tool-Chain   : CA78K0R
* Description  : This file implements main function.
* Creation Date: 2015/7/13
***********************************************************************************************************************/

/***********************************************************************************************************************
Pragma directive
***********************************************************************************************************************/
/* Start user code for pragma. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */

/***********************************************************************************************************************
Includes
***********************************************************************************************************************/
#include "r_cg_macrodriver.h"
#include "r_cg_cgc.h"
#include "r_cg_port.h"
#include "r_cg_intc.h"
#include "r_cg_timer.h"
/* Start user code for include. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
#include "r_cg_userdefine.h"

/***********************************************************************************************************************
Global variables and functions
***********************************************************************************************************************/
/* Start user code for global. Do not edit comment generated here */
#define TRIG P0.0
//#define ECHO P0.1

extern uint32_t GlobalTime;//全局时间变量,每隔1ms加一,由1ms间隔定时器触发。

void delayMs(uint16_t ms);
/* End user code. Do not edit comment generated here */
void R_MAIN_UserInit(void);

/***********************************************************************************************************************
* Function Name: main
* Description  : This function implements main function.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void main(void)
{
    /* Start user code. Do not edit comment generated here */
	uint32_t nowTime=0, lastTime = 0;
	uint32_t yourTime=0, beginTime=0;
	
	uint16_t dist = 0;
	R_MAIN_UserInit();
	R_TAU0_Channel0_Start();	
    R_INTC0_Start();
	while (1U)
    {
		nowTime = GlobalTime;
        if((nowTime-lastTime)>500)//每隔500ms触发一次模块
		{
			lastTime = GlobalTime;
			P13.0 = ~P13.0;//

			TRIG = 1;
			delayMs(2);
			TRIG = 0;
		}
    }
    /* End user code. Do not edit comment generated here */
}

/***********************************************************************************************************************
* Function Name: R_MAIN_UserInit
* Description  : This function adds user code before implementing main function.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void R_MAIN_UserInit(void)
{
    /* Start user code. Do not edit comment generated here */
    EI();
    /* End user code. Do not edit comment generated here */
}

/* Start user code for adding. Do not edit comment generated here */
void delayMs(uint16_t ms)
{
	uint32_t Tim = GlobalTime + ms;
	while((Tim - GlobalTime)>0);
}
/* End user code. Do not edit comment generated here */

定时器用户文件,主要就是全局计时,HCSR04CNT 用于ECHO高电平计时,在外部中断中被触发计数。

/***********************************************************************************************************************
* File Name    : r_cg_timer_user.c
* Version      : CodeGenerator for RL78/G13 V2.00.00.07 [22 Feb 2013]
* Device(s)    : R5F100LE
* Tool-Chain   : CA78K0R
* Description  : This file implements device driver for TAU module.
* Creation Date: 2015/7/13
***********************************************************************************************************************/

/***********************************************************************************************************************
Pragma directive
***********************************************************************************************************************/
#pragma interrupt INTTM00 r_tau0_channel0_interrupt
#pragma interrupt INTTM01 r_tau0_channel1_interrupt
/* Start user code for pragma. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */

/***********************************************************************************************************************
Includes
***********************************************************************************************************************/
#include "r_cg_macrodriver.h"
#include "r_cg_timer.h"
/* Start user code for include. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
#include "r_cg_userdefine.h"

/***********************************************************************************************************************
Global variables and functions
***********************************************************************************************************************/
/* Start user code for global. Do not edit comment generated here */
uint32_t GlobalTime=0;
uint32_t HCSR04CNT=0;//用于ECHO高电平计时
/* End user code. Do not edit comment generated here */

/***********************************************************************************************************************
* Function Name: r_tau0_channel0_interrupt
* Description  : This function is INTTM00 interrupt service routine.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
__interrupt static void r_tau0_channel0_interrupt(void)
{
    /* Start user code. Do not edit comment generated here */
	++GlobalTime;
    /* End user code. Do not edit comment generated here */
}

/***********************************************************************************************************************
* Function Name: r_tau0_channel1_interrupt
* Description  : This function is INTTM01 interrupt service routine.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
__interrupt static void r_tau0_channel1_interrupt(void)
{
    /* Start user code. Do not edit comment generated here */
	++HCSR04CNT;
    /* End user code. Do not edit comment generated here */
}

/* Start user code for adding. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */

外部中断用户文件。外部中断被配置为both模式,上升沿和下降沿触发中断,用于简单状态机处理这个逻辑。状态0是ECHO刚变为高电平触发了中断,状态0中开启100us定时器开始计时ECHO高电平时间,状态1是ECHO由高电平变为低电平触发中断,这是关闭中断并且取出HCSR04CNT的计数值计算距离单位为cm。

/***********************************************************************************************************************
* File Name    : r_cg_intc_user.c
* Version      : CodeGenerator for RL78/G13 V2.00.00.07 [22 Feb 2013]
* Device(s)    : R5F100LE
* Tool-Chain   : CA78K0R
* Description  : This file implements device driver for INTC module.
* Creation Date: 2015/7/13
***********************************************************************************************************************/

/***********************************************************************************************************************
Pragma directive
***********************************************************************************************************************/
#pragma interrupt INTP0 r_intc0_interrupt
/* Start user code for pragma. Do not edit comment generated here */

/* End user code. Do not edit comment generated here */

/***********************************************************************************************************************
Includes
***********************************************************************************************************************/
#include "r_cg_macrodriver.h"
#include "r_cg_intc.h"
/* Start user code for include. Do not edit comment generated here */
#include "r_cg_timer.h"
/* End user code. Do not edit comment generated here */
#include "r_cg_userdefine.h"

/***********************************************************************************************************************
Global variables and functions
***********************************************************************************************************************/
/* Start user code for global. Do not edit comment generated here */
extern uint32_t GlobalTime;
extern uint32_t HCSR04CNT;
uint16_t Distance=0;
/* End user code. Do not edit comment generated here */

/***********************************************************************************************************************
* Function Name: r_intc0_interrupt
* Description  : This function is INTP0 interrupt service routine.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
__interrupt static void r_intc0_interrupt(void)
{
    /* Start user code. Do not edit comment generated here */
	static uint8_t state=0;
	static uint16_t pro=0;
	
	
	switch(state)
	{
		case 0:
		{
			if(P13.7)
			{
				state = 1; 
				R_TAU0_Channel1_Start();//上升沿中断触发100us间隔定时器计数
			}
			else
				state = 0;
		}break;
		case 1:
		{
			if(!P13.7)
			{
				state = 0; 
				R_TAU0_Channel1_Stop();//下降沿中断关闭100us间隔定时器
				pro = HCSR04CNT;
				HCSR04CNT = 0;
				if(pro<200)
				{
					Distance = pro*3.3/2;//计算距离100us == 3.3cm
				}
			}
			else
				state = 0;
		}break;
		default:state=0;break;
	}

	
    /* End user code. Do not edit comment generated here */
}

/* Start user code for adding. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */


注意:使用时去掉中文注释。cutesuite + 对中文支持不好。

代码工程链接不明白的地方可以下来工程看看


瑞萨单片机(R5F100LE)利用中断和定时器HC_SR04超声波测距模块Cubesuite + 工程


你可能感兴趣的:(定时器,外部中断,HC_SR04超声波测距模块,R5F100LE,瑞萨单片机)