662
社区成员




我在采用cc2530mini开发板进行sr-04超声波模块的实验,我希望能够实现按下按钮触发模块测距。模块触发条件是trig引脚高电平10us以上触发。我将trig引脚连接到p0_5引脚,采用timer3定时延迟,timer1捕获echo的信号。在写了逻辑代码后始终没有响应。通过逻辑分析仪测试发现按下按钮,p0_5引脚第一次为9.5us,连续按3下按钮,第一次为9.5us,后续为6.5us。当我修改延时长度,修改为30us时,按下按钮实验现象不变,仍为第一次为9.5us,后续为6.5us。但是当我将延时改为5时,变为6.4us。当延时数字大于10的时候均为9.5。请问这是怎么回事,我应该怎么修改。以下是我的部分代码
超声波触发代码
void SR04_Trigger(void)
{
TRIG_LOW();
Delay_us(2);
TRIG_HIGH();
Timer3_Delay_us(20);
TRIG_LOW();
}
// 测量距离(单位:cm)
float SR04_CaptureDistance_cm(void)
{
uint16 duration;
float distance;
echo_done = 0;
SR04_Trigger();
TRIG_LOW();
// 等待捕获完成(最多等待30ms)
uint16 timeout = 30000;
while (!echo_done && timeout--) Delay_us(1);
if (!echo_done)
return -1.0; // 超时,无回波
if (echo_end >= echo_start)
duration = echo_end - echo_start;
else
duration = (0xFFFF - echo_start + echo_end); // 溢出处理
// 每tick = 0.5us,duration单位为tick
// 距离 = 时间(us) × 0.0343 / 2
distance = (duration * 0.5f * 0.0343f);
return distance; // 单位cm
}
延时代码
#pragma optimize=none
void Timer3_Delay_us(uint16 us)
{
// 设置 Timer3 为模模式,tick=1us(F/1),手动装载
T3CTL = 0x08; // 模式,F/1,无溢出中断
T3CNT = 0;
T3CTL |= 0x10; // 启动 Timer3
while (T3CNT < (us / 4)); // 等待满足 us
T3CTL &= ~0x10; // 停止 Timer3
}
按钮触发代码
static void zclSampleSw_HandleKeys( byte shift, byte keys )
{
if(keys & HAL_KEY_SW_6)
{
sendSyncSignalAndUltrasound(); // 调用超声波函数
}
}
void sendSyncSignalAndUltrasound(void)
{
float distance;
SR04_Init();
distance = SR04_CaptureDistance_cm();
if (distance > 0)
printf("Distance = %.2f cm\r\n", distance);
else
{
printf("No Echo Detected.\r\n");
HalLcdWriteString("No Echo Detected.",HAL_LCD_DEBUG_LINE_1);
}
}
zcl_sampleloop中部分代码
if ( events & SYS_EVENT_MSG )
{
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleSw_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
case ZCL_INCOMING_MSG:
{
xxx
}
break;
case KEY_CHANGE:
zclSampleSw_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
case ZDO_STATE_CHANGE:
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}