你好,你的cc2530做超声波测距实验的代码能给我看看吗?我自己弄半天了还是没法读出正确的计数值
展开全部
你好,可以。你发我邮箱吧。
超声波测距的原理是利用超声波在空气中的传播速度为已知,测量声波在发射后遇到障碍物反射回来的时间,根据发射和接收的时间差计算出发射点到障碍物的实际距离。超声波测距公式表示为:L=C×T
。
式中L为测量的距离长度;C为超声波在空气中的传播速度;T为测量距离传播的时间差(T为发射到接收时间数值的一半)。
其过程大致如下:
(1) 采用
IO 口
TRIG
触发测距,给最少
10us 的高电平信。
(2) 模块自动发送
8 个
40khz
的方波,自动检测是否有信号返回;
(3) 有信号返回
, 通过 IO
口 ECHO
输出一 个 高电平
, 高电平持续的时间就是超声
为了获得相对比较精确的时间T(返回信号ECHO为高电平持续时间),采用中断与计数器技术相结合的方法进行测量。
当返回信号ECHO为高电平时,配置并启动一个16位的计数器,配置返回信号引脚为外部中断触发方式(下降沿触发)。当返回信号由高电平变低时,进入相应的中断响应函数,读取相应计数寄存器的值。然后根据计数寄存器的值和微控制器的机器周期,计算出返回信号高电平的持续时间。
这个是当时的实验报告。估计对你有点用。程序回去帮你找找。
#ifndef ULTRASOUND_H
#define ULTRASOUND_H
#define uchar unsigned char
#define uint unsigned int
#define TRIG P1_2
#define ECHO P0_1
extern uchar RG;
extern uchar H1;
extern uchar L1;
extern uchar H2;
extern uchar L2;
extern uchar H3;
extern uchar L3;
extern uint data;
extern float distance;
extern uchar LoadRegBuf[4];
//void Delay(uint n);
void Delay_1us(uint microSecs);
void Delay_10us(uint n);
void Delay_1s(uint n);
void SysClkSet32M();
void Init_UltrasoundRanging();
void UltrasoundRanging(uchar *ulLoadBufPtr);
__interrupt void P0_ISR(void);
void main(void)
{
while(1)
{
UltrasoundRanging(LoadRegBuf);
Delay_1s(1);
data=256*H2+L2-L1-256*H1;
distance=(float)data*340/10000;
Delay_1us(1);
};
}
#include <ioCC2530.h>
#include "Ultrasound.h"
uchar RG;
uchar H1;
uchar L1;
uchar H2;
uchar L2;
uchar H3;
uchar L3;
uint data;
float distance;
uchar LoadRegBuf[4];//全局数据,用以存储定时计数器的值。
void Delay_1us(uint microSecs)
{ while(microSecs--)
{ /* 32 NOPs == 1 usecs 因为延时还有计算的缘故,用了31个nop*/
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop");
}
}
void Delay_10us(uint n)
{ /* 320NOPs == 10usecs 因为延时还有计算的缘故,用了310个nop*/
uint tt,yy;
for(tt = 0;tt<n;tt++);
for(yy = 310;yy>0;yy--);
{asm("NOP");}
}
void Delay_1s(uint n)
{ uint ulloop=1000;
uint tt;
for(tt =n ;tt>0;tt--);
for( ulloop=1000;ulloop>0;ulloop--)
{
Delay_10us(100);
}
}
void SysClkSet32M()
{
CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定
CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ
//此时的CLKCONSTA为0x88。即普通时钟和定时器时钟都是32M。
}
void Init_UltrasoundRanging()
{
P1DIR = 0X04; //0为输入(默认),1为输出 00000100 TRIG P1_2
TRIG=0;
P0INP &= ~0X02; //有上拉、下拉 有初始化的左右
P0IEN |= 0X02; //P0_1 中断使能
PICTL |= 0X01; //设置P0_1引脚,下降沿触发中断
IEN1 |= 0X20; // P0IE = 1;
}
void UltrasoundRanging(uchar *ulLoadBufPtr)
{
SysClkSet32M();
Init_UltrasoundRanging();
EA = 0;
TRIG =1;
Delay_1us(10); //需要延时10us以上的高电平
TRIG =0;
T1CNTL=0;
T1CNTH=0;
while(!ECHO);
T1CTL = 0x09; //通道0,中断有效,32分频;自动重装模式(0x0000->0xffff);
L1=T1CNTL;
H1=T1CNTH;
*ulLoadBufPtr++=T1CNTL;
*ulLoadBufPtr++=T1CNTH;
EA = 1;
Delay_10us(60000);
Delay_10us(60000);
}
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
EA=0;
T1CTL = 0x00;
LoadRegBuf[2]=T1CNTL;
LoadRegBuf[3]=T1CNTH;
L2=T1CNTL;
H2=T1CNTH;
if(P0IFG&0x02) //按键中断
{
P0IFG = 0;
}
T1CTL = 0x09;
P0IF = 0; //清中断标志
EA=1;
}
//需要的花,完整的程序给你。程序没问题,已经出版书了,测试过的。
超声波测距的原理是利用超声波在空气中的传播速度为已知,测量声波在发射后遇到障碍物反射回来的时间,根据发射和接收的时间差计算出发射点到障碍物的实际距离。超声波测距公式表示为:L=C×T
。
式中L为测量的距离长度;C为超声波在空气中的传播速度;T为测量距离传播的时间差(T为发射到接收时间数值的一半)。
其过程大致如下:
(1) 采用
IO 口
TRIG
触发测距,给最少
10us 的高电平信。
(2) 模块自动发送
8 个
40khz
的方波,自动检测是否有信号返回;
(3) 有信号返回
, 通过 IO
口 ECHO
输出一 个 高电平
, 高电平持续的时间就是超声
为了获得相对比较精确的时间T(返回信号ECHO为高电平持续时间),采用中断与计数器技术相结合的方法进行测量。
当返回信号ECHO为高电平时,配置并启动一个16位的计数器,配置返回信号引脚为外部中断触发方式(下降沿触发)。当返回信号由高电平变低时,进入相应的中断响应函数,读取相应计数寄存器的值。然后根据计数寄存器的值和微控制器的机器周期,计算出返回信号高电平的持续时间。
这个是当时的实验报告。估计对你有点用。程序回去帮你找找。
#ifndef ULTRASOUND_H
#define ULTRASOUND_H
#define uchar unsigned char
#define uint unsigned int
#define TRIG P1_2
#define ECHO P0_1
extern uchar RG;
extern uchar H1;
extern uchar L1;
extern uchar H2;
extern uchar L2;
extern uchar H3;
extern uchar L3;
extern uint data;
extern float distance;
extern uchar LoadRegBuf[4];
//void Delay(uint n);
void Delay_1us(uint microSecs);
void Delay_10us(uint n);
void Delay_1s(uint n);
void SysClkSet32M();
void Init_UltrasoundRanging();
void UltrasoundRanging(uchar *ulLoadBufPtr);
__interrupt void P0_ISR(void);
void main(void)
{
while(1)
{
UltrasoundRanging(LoadRegBuf);
Delay_1s(1);
data=256*H2+L2-L1-256*H1;
distance=(float)data*340/10000;
Delay_1us(1);
};
}
#include <ioCC2530.h>
#include "Ultrasound.h"
uchar RG;
uchar H1;
uchar L1;
uchar H2;
uchar L2;
uchar H3;
uchar L3;
uint data;
float distance;
uchar LoadRegBuf[4];//全局数据,用以存储定时计数器的值。
void Delay_1us(uint microSecs)
{ while(microSecs--)
{ /* 32 NOPs == 1 usecs 因为延时还有计算的缘故,用了31个nop*/
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop");
}
}
void Delay_10us(uint n)
{ /* 320NOPs == 10usecs 因为延时还有计算的缘故,用了310个nop*/
uint tt,yy;
for(tt = 0;tt<n;tt++);
for(yy = 310;yy>0;yy--);
{asm("NOP");}
}
void Delay_1s(uint n)
{ uint ulloop=1000;
uint tt;
for(tt =n ;tt>0;tt--);
for( ulloop=1000;ulloop>0;ulloop--)
{
Delay_10us(100);
}
}
void SysClkSet32M()
{
CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定
CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ
//此时的CLKCONSTA为0x88。即普通时钟和定时器时钟都是32M。
}
void Init_UltrasoundRanging()
{
P1DIR = 0X04; //0为输入(默认),1为输出 00000100 TRIG P1_2
TRIG=0;
P0INP &= ~0X02; //有上拉、下拉 有初始化的左右
P0IEN |= 0X02; //P0_1 中断使能
PICTL |= 0X01; //设置P0_1引脚,下降沿触发中断
IEN1 |= 0X20; // P0IE = 1;
}
void UltrasoundRanging(uchar *ulLoadBufPtr)
{
SysClkSet32M();
Init_UltrasoundRanging();
EA = 0;
TRIG =1;
Delay_1us(10); //需要延时10us以上的高电平
TRIG =0;
T1CNTL=0;
T1CNTH=0;
while(!ECHO);
T1CTL = 0x09; //通道0,中断有效,32分频;自动重装模式(0x0000->0xffff);
L1=T1CNTL;
H1=T1CNTH;
*ulLoadBufPtr++=T1CNTL;
*ulLoadBufPtr++=T1CNTH;
EA = 1;
Delay_10us(60000);
Delay_10us(60000);
}
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
EA=0;
T1CTL = 0x00;
LoadRegBuf[2]=T1CNTL;
LoadRegBuf[3]=T1CNTH;
L2=T1CNTL;
H2=T1CNTH;
if(P0IFG&0x02) //按键中断
{
P0IFG = 0;
}
T1CTL = 0x09;
P0IF = 0; //清中断标志
EA=1;
}
//需要的花,完整的程序给你。程序没问题,已经出版书了,测试过的。
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
一般来说就是寄存器设置问题
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询