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
下图是代码生成器的配置:
下面是主函数代码,主要作用
就是每隔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 + 工程