HC_SR04超声波测距模块是一个很常见的模块,瑞萨的驱动还不多见,就写了这个文章,当然这个模块使用起来是比较简单的,但大多数情况下大家都使用了阻塞性的代码如while(ECHO)什么的,这样看起了有点不优雅。这篇文章介绍一个无阻塞的实现方式。
使用了两个定器一个100us的间隔定时器用于计算ECHO高电平时间当然这样只能精确到330*0.0001 = 0.033M = 3.3CM,如果你想要更高的精度你可以用一个更精确的间隔定时器。另一个定时器为一毫秒间隔定时器,作为全局时间变量。用了一个外部中断配置为both模式,上升沿下降沿多触发中断。用于检测echo高电平时间。开P13.0口用来调试。
//引脚接线TRIG 接P0.0ECHO 接外部中断INTP0(P13.7)VCC-VCCGND-GND
下图是代码生成器的配置:
下面是主函数代码,主要作用
就是每隔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.1extern 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 + 对中文支持不好。
代码工程链接不明白的地方可以下来工程看看