MSP430F5529之捕获模式下的HCSR04超声测距(粗略)

前段时间需要用MSP430F5529,因为是个菜鸟,很多都不会,遇到了很多问题,百度好多东西都是千篇一律的,好些东西都是Ctrl+c,Ctrl+v。而有很多老鸟,可能说不定也是菜鸟一个呢!!一副为了你好的样子,你看手册啊,手册不会吗?你用示波器打啊,示波器不会吗?你什么单位啊,示波器都没有吗?所以才打算在把这个捕获模式搞清楚后发一篇自己的心得吧.。发了半天牢骚,正文如下。

要用捕获我们得搞清楚捕获的原理是什么,捕获的原理是通过计数器,记录从使能开始到设定的沿的数值(也可以理解为时间)。在设定为捕获模式下,使能过后,计数器TA0R就开始计数了,在单步调试过程中,可以通过观察CCS里面的Registers各个寄存器的变化来深入的理解。

 

上面分别是CCS单步调试的时候的寄存器图和MSP430F5529的引脚图,根据引脚图我们可以知道,关于定时器TA0.0相关的功能在P1.1引脚上,以此类推对应起来。这次我用到的是P1.4引脚,也就是TA0.3,选择了TA0.3那么,相对应的捕获到的时间的值,是在TA0CCTL3那里。

然后我们可以通过写TA0CCTL3里面的寄存器,来选择模式,关于什么模式下是什么作用,可以通过头文件,看头文件里面的注释,也可以通过看上图Register中Value一栏的值,如:CM下的00-CM_0功能是Capture mode 1(捕获模式1)。

在单步调试的过程中,我们可以看到,计数器计数的过程中,TA0R每一个单步都会变,在捕获到设定好的边沿时,TA0R的值会赋给TA0CCR3,然后TA0R再接着计数。

单步调试的大概思路就是这样的,我们接下来通过观察Expressions里面的值,来看我们捕获到的时间。

我这里没有连超声模块,就没有再次单步调试了,但是之前调试的过程是这样的。按照这个思路来应该没有问题。

根据超声模块HC_SR04的时序图可以知道:

超声模块内部发出信号需要先10us的高电平,最后我们需要捕捉一个上升沿和下降沿就好了,就可以得出时间了。


#include<msp430f5529.h>
unsigned int k=0;
unsigned int LastCCR1;		//上一次高电平持续的时间,和距离正相关
unsigned int dat[20];		//通过数组备份采集到的数据

void HC_SR04Init();
void HC_SR04Start();
void TimeGetInit();


void main()
{
	HC_SR04Init();			//初始化超声模块HC_SR04
	TimeGetInit();			//初始化计数捕获引脚,模式等
	_EINT();
	while(1)
	{
		HC_SR04Start();
		LPM0;
	}
}

/*初始化HC_SR04Init()模块*/
void HC_SR04Init()
{
	P1DIR|=BIT2;
}
/*开始超声发送*/
void HC_SR04Start()
{
	P1OUT|=BIT2;		
	_delay_cycles(12);		//至少持续10us的高电平
	P1OUT&=~BIT2;			
}

/*初始化捕获模式,获取时间*/
void TimeGetInit()
{
	P1DIR&=~BIT4;
	P1SEL|=BIT4;

	TA0CTL=TASSEL_2+ID_0+MC_2+TACLR;
	TA0CCTL3=CM_1+SCS+CAP+CCIE+CCIS_0;
}


#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
{
	_DINT();						//关中断
	static unsigned char times=1;
	static unsigned char i=0;
	unsigned char j;
	unsigned int t;

	if(times==1)
	{
		LastCCR1=TA0CCR3;		//记录下上次CCR3的值
		TA0CCTL3&=~CM_1;		//清上升沿捕获
		TA0CCTL3|=CM_2;			//改为下降沿捕获
		times++;
	}
	if(times==0)
	{
		if(i<20)				//把采集到的20次的值都放到数组中
		{
			dat[i]=TA0CCR3-LastCCR1;;
			i++;
		}
		if(i>=20)				//为了防止误差,排序把采集到的两头两尾的值去掉,取中间的平均值
		{
			for(i=0;i<20;i++)
			{
				for(j=0;j<20-i;j++)
				{
					if(dat[j]>dat[j+1])
					{
						t=dat[j];
						dat[j]=dat[j+1];
						dat[j+1]=t;
					}
				}
			}
			
			t=0;
			for(i=7;i<12;i++)
			{
				t=t+dat[i];
			}
			k=t/5;
			i=0;
		}
		TA0CCTL3&=~CM_2;		//清除下降沿触发
		TA0CCTL3|=CM_1;			//变为上升沿触发
		times++;				//改变times的值
	}
	times&=0x01;				//times>1时清0
	LPM0_EXIT;					//退出低功耗模式
	TA0CCTL3&=~CCIFG;			//清除中断响应标志
	_EINT();					//开中断
}

这个没有具体的算时间,但是我根据距离S=V*(t/2)大概算了下,这里时间粗略为:t=k*1us。像那么回事,这里只是讲下MSP430F5529用捕获的方法,如果要精确的话,还需要校准时钟频率等等。

分享出来,希望能帮到大家。

  • 22
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值