MSP430F149 HC-SR04超声波模块测距LCD1602显示程序.docx
《MSP430F149 HC-SR04超声波模块测距LCD1602显示程序.docx》由会员分享,可在线阅读,更多相关《MSP430F149 HC-SR04超声波模块测距LCD1602显示程序.docx(7页珍藏版)》请在冰豆网上搜索。
![MSP430F149 HC-SR04超声波模块测距LCD1602显示程序.docx](https://file1.bdocx.com/fileroot1/2022-10/7/2f8244d9-31cc-45be-a07b-26bf38db9e01/2f8244d9-31cc-45be-a07b-26bf38db9e011.gif)
/*********************************************************************
程序功能:
msp430f149控制HC—SR04超声波模块实现测距,并在lcd1602显示
---------------------------------------------------------------—-------------—-------------—-------------—-
特别说明:
本程序实测精度为0.5cm,可调算法进行修正
--------------------------------------------------------------—-—------------—-------------—-------------
测试说明:
HC—SR04工作电压为5v,小于5v的模块不能使模块正常工作,因此
需给模块单独供电
--------------------------------------------------------------—-—------------—-------------—-------------
程序说明:
本程序含三部分,分别为HC-SR04main.c,HC-SR04.h,cry1602.h
*********************************************************************/
下面是主程序:
HC-SR04main.c
#include"msp430x14x.h"
#include"cry1602.h"
#include"HC-SR04.h"
#defineuintunsignedint
#defineucharunsignedchar
uchartishi[]={"Thedistis:
"};
ucharSR_Temp[];
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD;
uchari;
longSR_Long;
/*------选择系统主时钟为8MHz-------*/
BCSCTL1&=~XT2OFF;//打开XT2高频晶体振荡器
do
{
IFG1&=~OFIFG;//清除晶振失败标志
for(i=0xFF;i>0;i++);//等待8MHz晶体起振
}
while((IFG1&OFIFG));//晶振失效标志仍然存在?
BCSCTL2|=SELM_2+SELS;//MCLK和SMCLK选择高频晶振
SR_Init();//初始化端口和定时器B
LcdReset();//初始化1602
DispNChar(2,0,12,tishi);
while
(1)
{
SR_Start();
SR_Long=SR_DoTrans();
/*SR_Temp[0]=SR_Long/100+0x30;
SR_Temp[1]=(SR_Long/10)%10+0x30;
SR_Temp[2]=(SR_Long)%10+0x30;
DisplChar(4,1,SR_Temp[0]);
DisplChar(5,1,SR_Temp[1]);
DisplChar(6,1,'.');
DisplChar(7,1,SR_Temp[2]);
DisplChar(8,1,'');
DisplChar(9,1,'c');
DisplChar(10,1,'m');*/
SR_Temp[0]=SR_Long/100+0x30;
SR_Temp[1]=(SR_Long/10)%10+0x30;
SR_Temp[2]='.';
SR_Temp[3]=(SR_Long)%10+0x30;
SR_Temp[4]='';
SR_Temp[5]='c';
SR_Temp[6]='m';
for(i=0;i<7;i++)
{
DisplChar((4+i),1,SR_Temp[i]);
}
}
}
下面是HC-SR04模块程序:
HC-SR04.h
/****************************************************************
程序说明:
Trig为发射端,接P2.4,ECHO为接收端,接P1.1
*****************************************************************/
#include"msp430x14x.h"
#defineTrig_HP2OUT|=BIT4//端口P2.4输出高电平
#defineTrig_LP2OUT&=~BIT4//端口P2.4输出低电平
#defineuintunsignedint
#defineucharunsignedchar
#defineCPU(8000000)
#definedelay_us(x)(__delay_cycles((double)x*CPU/1000000.0))
#definedelay_ms(x)(__delay_cycles((double)x*CPU/1000.0))
#definedely_s(x)(__delay_cycles((double)x*CPU/1.0))
voidSR_Init(void);
voidSR_DelayNus(uintn);
voidSR_Start(void);
longSR_DoTrans();
uintTB_CCR0,TB0_CCR0,TB1_CCR0;//用来保存TBCCR0的值
ucharSR_Flag=0;//SR的标志位,1为一次捕捉完成
voidSR_Init(void)//初始化端口和定时器B
{
Trig_L;
P2DIR|=BIT4;//设置P2.4为输出口
P1SEL|=BIT1;
P1DIR&=~BIT1;//设置P1.1为输入口
TACTL=TASSEL_2+TACLR+ID_3;//选择SMCLK为时钟,并且8分频,清除TAR
CCTL0=CM_1+CCIS_0+CAP+CCIE;//上升沿捕捉模式,选择CCIxA作为捕捉事件的输
入信号
//工作在捕捉模式,捕获/比较中断使能
TBCTL|=TBSSEL_2+ID_3+TBCLR;//设置TimerB时钟为SMCL,8分频,清空TBR;
TBCCTL0|=CM_1+CCIS_1+SCS+CAP+CCIE;//设置TimerB为上升沿捕捉,选择CCI0B(P4.0)
//为捕捉输入端口,捕捉为同步捕捉,打开捕捉中断
_EINT();//使能GIE
}
/*******************************************
函数名称:
SR_DelayNus
功能:
实现N个微秒的延时,需设置TACTL|=TASSEL_2+ID_3;//选择SMCLK为时钟,并且
8分频
参数:
n--延时长度
返回值:
无
说明:
定时器A的计数时钟是1MHz,CPU主频8MHz
所以通过定时器延时能够得到极为精确的
us级延时
********************************************/
voidSR_DelayNus(uintn)
{
uinti;
for(i=0;idelay_us
(1);
}
voidSR_Start(void)//发送启动信号
{
Trig_L;
SR_DelayNus(20);
Trig_H;
SR_DelayNus(20);//延时20us,至少10us;
Trig_L;
}
longSR_DoTrans()//SR转换,返回测量距离(cm)
{
longTemp;
SR_Start();
while(!
(P1IN&BIT7));//等待回送高电平
TBCTL|=MC_2+TBCLR;//设置为连续计数模式
TB1_CCR0=TBR;
while(P1IN&BIT7);//等待回送低电平
TB_CCR0=TBR;
TBCTL&=~MC_2;//停止计数
Temp=(long)((TB_CCR0-TB1_CCR0)*340.0/2);
Temp=Temp/1000;
delay_ms(700);
returnTemp;
}
#pragmavector=TIMERA0_VECTOR
__interruptvoidTimerA0Int(void)//TimerBCCRO捕捉中断服务程序
{
if(TACCTL0&CM_1)//是上升沿捕捉
{
TB0_CCR0=TACCR0;//保存TBCCR0的值
TACCTL0&=~CM_1;//清除上升沿捕捉
TACCTL0|=CM_2;//设置下降沿捕捉
TACTL|=MC_2;//开始TimerB计数,模式为连续计数
}
else//是下降沿捕捉
{
TB1_CCR0=TACCR0;//保存TBCCR0的值
TACCTL0&=~CM_2;//清除下降沿沿捕捉
TACCTL0|=CM_1;//设置为上升沿捕捉
TACTL|=MC_0;//停止计数直到改变模式后,重新计数
TB_CCR0=TB1_CCR0-TB0_CCR0;
SR_Flag=1;
}
}
下面是LCD1602模块程序:
cry1602.h
#include"msp430x14x.h"
typedefunsignedcharuchar;
typedefunsignedintuint;
#defineDataDirP2DIR
#defineDataPortP2OUT
#defineBusy0x80
#defineCtrlDirP6DIR
#defineCLR_RSP6OUT&=~BIT3;
#defineSET_RSP6OUT|=BIT3;
#defineCLR_RWP6OUT&=~BIT4;
#defineSET_RWP6OUT|=BIT4;
#defineCLR_ENP6OUT&=~BIT5;
#defineSET_ENP6OUT|=BIT5;
voidDispStr(ucharx,uchary,uchar*ptr);
voidDispNChar(ucharx,uchary,ucharn,uchar*ptr);
voidLocateXY(ucharx,uchary);
voidDisplChar(ucharx,uchary,uchardata);
voidLcdReset(void);
voidLcdWriteCommand(ucharcmd,ucharchk);
voidLcdWriteData(uchardata);
voidWait_EN(void);
voidDelay5ms(void);
/*延时5ms*/
voidDelay5ms(void)
{
uinti=40000;
while(i!
=0)
{
i--;
}
}
/*从某个位置起连线写字符*/
voidDispStr(ucharx,uchary,uchar*ptr