[C++] syntaxhighlighter_viewsource syntaxhighlighter_copycode #include<intrins.h>
#include<STC11FXX.H>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code LED_W[8] = {0,1,2,3,4,5,6,7};
int count=0;
int count_T0 = 0; //记录T0的中断次数
uint distance_data; //距离折算的时钟数值
ulong distance_cm=0; //实际厘米数
uchar outcomeH,outcomeL; //自定义寄存器
uchar WFHL_i,WFHL_j; //触发后等待高电平的循环用变量
uchar T0_State = 0; //定时器标志阶段,0表示等待,1表示发射完成,2表示发射完成后等待时间超出。
bit succeed_flag; //测量成功标志
bit Echo_error; //等待高电平失败标志
sbit Trig = P1^0; //产生脉冲引脚
sbit Echo = P3^3; //回波引脚 中断INT1引脚
void Delay30ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 2;
j = 67;
k = 183;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 54;
j = 198;
do
{
while (--j);
} while (--i);
}
void Delay20us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 52;
while (--i);
}
void T0_interrupt(void) interrupt 1
{
TF0 = 0; //清除TF0标志
if(T0_State == 0 )
{
//重新装载50ms的延时
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
if(++count_T0 == 60) //==60表明延迟了3秒
{
count_T0 = 0;
WFHL_i = 6; //等待高Echo口电平延时参数
WFHL_j = 73; //等待高Echo口电平延时参数
Trig=1; //触发电平拉高
Delay20us(); //等20us
Trig=0; //触发电平拉低
// P0 = table[7]; //传送个位数码管数据
// P2 = LED_W[7]; //点亮个位 数码管
/*
do //等待Echo变为高电平
{
if(Echo==1)
break;
while (--WFHL_j)
{
if(Echo==1)
break;
}
} while (--WFHL_i);
*/
while(Echo == 0);
if(Echo == 1)
{
//设置等待50ms的定时器延时
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
T0_State=1; //定时器0阶段设置为1,
EX1=1; //开启INT1外部中断
P0 = table[7]; //传送个位数码管数据
P2 = LED_W[6]; //点亮个位 数码管
Delay20us();
}
/*
else
{
Echo_error=1; //发射器错误标志置1
distance_cm=888; //设置距离为888,表明等待高电平失败
}
*/
}
return;
}
if(T0_State == 1 ) //在1阶段,触发到定时器中断
{
EX1=0; //关闭INT1外部中断
succeed_flag=0; //测量失败
distance_cm=987-(count++); //设置距离为987递减,起标识作用;
T0_State=0; //定时器阶段改为0,
//重新装载50ms的延时
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
count_T0 = 0;
return;
}
}
void INT0_interrupt(void) interrupt 2
{
int i=0,j=0,l=100;
EX1 = 0; //已经探测到返回信号在距离发射器5米以内,关中断
TR0=0; //关闭定时器0计数
outcomeH =TH0; //取出定时器的值
outcomeL =TL0; //取出定时器的值
distance_data=outcomeH; //高8位赋值
distance_data<<=8; //放入16位的高8位
distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据
distance_data=distance_data-0x4c00; //得到实际定时器计数净差
distance_cm=(((unsigned long)distance_data)*17)/921; //实际距离CM;
succeed_flag=1; //测量成功
T0_State=0; //定时器0阶段改为0
//重新装载50ms的延时
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
count_T0 = 0;
TR0=1; //重新打开定时器0计数
// Delay30ms();
while(l--)
{
P0 = table[i]; // i 值的 个位数
P2 = LED_W[j]; //点亮第一位数码管
Delay5ms();
j++;
i++;
if(j == 8) //利用 j 值的变化,来控制数码管数值变化间隔的时间
{
j = 0;
i = 0;
}
}
IE1 =0; //中断清0,这个很重要,
}
/********************************************************************
* 名称 : Main()
* 功能 : 数码管的显示
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
// uint distance_data; //距离时钟数值
// uint u1,u2;
// distance_data=20000;
// u1=(((unsigned long)distance_data)*17)/921;
// u2=u1;
uchar j=0;
uchar LED_00X,LED_0X0,LED_X00;
uint temp_data=0xffff; //临时变量
T0_State=0; //发射等待标志置0
P1M1=0x00; //设置P1.0口为强推挽
P1M0=0x01; //设置P1.0口为强推挽
P3M1=0x00; //设置P3所有口为标准输入输出
P3M0=0x00; //设置P3所有口为标准输入输出
Trig=0; //拉低触发脉冲
Echo=1; //设置P3.3口为普通高电平,方便读取
IE = 0x00; //一来把中断全部关一下
EA=1; //开总中断
// IT0=0; //设置INT0低电平触发
// IT0=1; //设置INT0下降沿触发
// EX0=0; //关闭INT0外部中断
// EX0=1; //开启INT0外部中断
IT1=1; //设置INT1下降沿触发
// IT1=0; //设置INT1低电平触发
// EX1=1; //开启INT1外部中断
EX1=0; //关闭INT1外部中断
//以下是定时器操作
ET0 = 1; //开定时器0中断
//设置定时器0为50ms延时
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
while(1)
{
if(temp_data !=distance_cm)
{
temp_data=distance_cm;
LED_X00=temp_data/100; //获取百位数值
temp_data=temp_data%100;
LED_0X0=temp_data/10; //获取十位数值
temp_data=temp_data%10; //取余运算
LED_00X=temp_data; //获取各位数值
}
switch(j)
{
case 0:
P0 = table[LED_X00]; //传送个位数码管数据
P2 = LED_W[j]; //点亮个位 数码管
j++;
break;
case 1:
P0 = table[LED_0X0]; //传送个位数码管数据
P2 = LED_W[j]; //点亮个位 数码管
j++;
break;
case 2:
P0 = table[LED_00X]; //传送个位数码管数据
P2 = LED_W[j]; //点亮个位 数码管
j++;
break;
}
if(j >= 3)
j=0;
Delay5ms();
/*
P0 = table[i]; // i 值的 个位数
P2 = LED_W[j]; //点亮第一位数码管
Delay5ms();
j++;
i++;
if(j == 8) //利用 j 值的变化,来控制数码管数值变化间隔的时间
{
j = 0;
i = 0;
}
*/
}
} |