//超声波模块显示程序
#include "include.h"
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
#define CLR_Tx P1OUT&=~BIT5; //sbit Tx = P1^5; 产生脉冲引脚,低
#define SET_Tx P1OUT|=BIT5; //高
//#define CLR_Rx P2OUT&=~BIT2; sbit Rx = P2^2; 回波引脚,捕获上升沿,0
//#define SET_Rx P2OUT|=BIT2;
uchar *s1 = "CHAO SHENG BO";
uchar *s2 = "juli:";
unsigned char digit[ ]={"0123456789"}; //定义字符数组显示数字
uint distance[4]; //测距接收缓冲区
uchar ge,shi,bai,temp,flag,outcome,i; //自定义寄存器
uint succeed_flag; //测量成功标志
void conversion(uint temp_data);
void delay_20us();
void pai_xu();
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
void csb(void) // 主程序
{ uint distance_data,a,b;
uchar CONT_1;
P2DIR = 0x01; //设置P2.0,1方向为输出
P2OUT = 0x01;
uchar k; //定义变量i指向字符串数组元素
LcdReset(); //调用LCD初始化函数
delay(10); //延时10ms,给硬件一点反应时间
DispStr(1,0,s1); // 从第1行第3列开始显示
flag=0;
CLR_Tx; //首先拉低脉冲输入引脚
TACTL = TASSEL_1 + MC_1; //定时器A的时钟源选择ACLK,增计数模式
TACCTL0 = CCIE; //使能CCR0中断
TACCR0 = 134 ; //65.535s进入中断
_EINT(); //使能全局中断 GIE
while(1) //程序循环
{
DispStr(1,1,s2); // 从第2行第3列开始显示
LcdWriteData(digit[bai]); //将万位数字的字符常量写入LCD
LcdWriteData(digit[shi]); //将千位数字的字符常量写入LCD
LcdWriteData('.'); //将万位数字的字符常量写入LCD
LcdWriteData(digit[ge]); //将百位数字的字符常量写入LCD
LcdWriteData(' '); //将百位数字的字符常量写入LCD
LcdWriteData('C'); //将万位数字的字符常量写入LCD
LcdWriteData('M'); //将万位数字的字符常量写入LCD
SET_Tx ;//P1.5引脚就是L5灯,置1=点亮L5
delay_20us();
CLR_Tx; //产生一个超过10us的脉冲,在Tx引脚
while((P2IN & BIT2)==0); //等待Rx回波引脚变高电平,Rx为0一直执行空语句
succeed_flag=0; //清测量成功标志
TACTL=TACLR;
TACCTL0 = CM_2 + SCS + CAP + CCIE+CCIS_0;//捕获模式,同步捕获,中断打开,下降沿捕获
_EINT();//开总中断
while(CCR0<134)
TACCTL0|= CCIE+CCIFG; //关闭外部中断
if(succeed_flag==1)
{
distance_data=(outcome*344/(1024*2*2*58)); //微秒的单位除以58等于厘米
} //为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
if(succeed_flag==0)
{
distance_data=0; //没有回波则清零
}
distance[i]=distance_data; //将测量结果的数据放入缓冲区
i++;
if(i==3)
{
distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4;
pai_xu();
distance_data=distance[1];
a=distance_data;
if(b==a) CONT_1=0;
if(b!=a) CONT_1++;
if(CONT_1>=3)
{ CONT_1=0;
b=a;
conversion(b);
}
i=0;
}
}
}
//外部中断0,用做判断回波电平
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
outcome=CCR0; //取出定时器的值
succeed_flag=1; //至成功测量的标志
TACCTL0|= CCIE+CCIFG; //关闭外部中断
P2OUT ^= 0x01;
}
//显示数据转换程序
void conversion(uint temp_data)
{
uchar ge_data,shi_data,bai_data ;
bai_data=temp_data/100 ;
temp_data=temp_data%100; //取余运算
shi_data=temp_data/10 ;
temp_data=temp_data%10; //取余运算
ge_data=temp_data;
bai = bai_data;
shi = shi_data;
ge = ge_data ;
}
void delay_20us()
{ uchar bt ;
for(bt=0;bt<60;bt++);
}
void pai_xu()
{ uint t;
if (distance[0]>distance[1])
{t=distance[0];distance[0]=distance[1];distance[1]=t;}
if(distance[0]>distance[2])
{t=distance[2];distance[2]=distance[0];distance[0]=t;}
if(distance[1]>distance[2])
{t=distance[1];distance[1]=distance[2];distance[2]=t;}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
下面的是51的主程序+外部中断:
void main(void) // 主程序
{ uint distance_data,a,b;
uchar CONT_1;
uchar k; //定义变量i指向字符串数组元素
LcdInitiate(); //调用LCD初始化函数
delay(10); //延时10ms,给硬件一点反应时间
WriteAddress(0x01); // 从第1行第3列开始显示
k = 0; //指向字符数组的第1个元素
while(string[k] != ' ')
{
WriteData(string[k]);
k++; //指向下字符数组一个元素
}
i=0;
flag=0;
Tx=0; //首先拉低脉冲输入引脚
TMOD=0x10; //定时器1,16位工作方式
// TR0=1; //启动定时器0
IT0=0; //由高电平变低电平,触发外部中断,外部中断0触发
//ET0=1; //打开定时器0中断
EX0=0; //关闭外部中断,禁止外部中断0中断
EA=1; //打开总中断
while(1) //程序循环
{
WriteAddress(0x41); // 从第2行第6列开始显示
WriteData('J'); //将万位数字的字符常量写入LCD
WriteData('U'); //将万位数字的字符常量写入LCD
WriteData('L'); //将万位数字的字符常量写入LCD
WriteData('I'); //将万位数字的字符常量写入LCD
WriteData(':'); //将万位数字的字符常量写入LCD
WriteData(digit[bai]); //将万位数字的字符常量写入LCD
WriteData(digit[shi]); //将千位数字的字符常量写入LCD
WriteData('.'); //将万位数字的字符常量写入LCD
WriteData(digit[ge]); //将百位数字的字符常量写入LCD
WriteData(' '); //将百位数字的字符常量写入LCD
WriteData('C'); //将万位数字的字符常量写入LCD
WriteData('M'); //将万位数字的字符常量写入LCD
EA=0; //禁止所有的中断请求
Tx=1; //P1.5引脚就是L5灯,置1=点亮L5
delay_20us();
Tx=0; //产生一个超过10us的脉冲,在Tx引脚
while(Rx==0); //等待Rx回波引脚变高电平,Rx为0一直执行空语句
succeed_flag=0; //清测量成功标志
EX0=1; //打开外部中断
TH1=0; //定时器1清零
TL1=0; //定时器1清零
TF1=0; //定时器T1溢出标志位
TR1=1; //启动定时器1
EA=1; //开总中断
while(TH1 < 30);//等待测量的结果,周期65.535毫秒(可用中断实现)
TR1=0; //关闭定时器1
EX0=0; //关闭外部中断
if(succeed_flag==1)
{
distance_data=outcomeH; //测量结果的高8位
distance_data<<=8; //放入16位的高8位
distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据
distance_data*=12; //因为定时器默认为12分频
distance_data/=58; //微秒的单位除以58等于厘米
} //为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
if(succeed_flag==0)
{
distance_data=0; //没有回波则清零
}
distance[i]=distance_data; //将测量结果的数据放入缓冲区
i++;
if(i==3)
{
distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4;
pai_xu();
distance_data=distance[1];
a=distance_data;
if(b==a) CONT_1=0;
if(b!=a) CONT_1++;
if(CONT_1>=3)
{ CONT_1=0;
b=a;
conversion(b);
}
i=0;
}
}
}
//***************************************************************
//外部中断0,用做判断回波电平
INTO_() interrupt 0 // 外部中断是0号
{
outcomeH =TH1; //取出定时器的值
outcomeL =TL1; //取出定时器的值
succeed_flag=1; //至成功测量的标志
EX0=0; //关闭外部中断
}
赞同
一周热门 更多>