题目和完整程序 !!!!
一、函数声明
#include <STC15F2K60S2.H>
#include <IIC.H>
#include <intrins.H>
#define u8 unsigned char
#define u16 unsigned int
sbit TX=P1^0;
sbit RX=P1^1; //超声波
sbit S7=P3^0; sbit L1=P0^0; //LED位变量 和 按键位变量
sbit S6=P3^1; sbit L2=P0^1;
sbit S5=P3^2; sbit L3=P0^2;
sbit S4=P3^3; sbit L8=P0^7;
u16 distance; //超声波距离
u8 SMG_mode; //数码管模式
u8 Rparm=45; //上限参数
u8 Dparm=5; //下限参数
u8 F_setwave; //超声波启动标志位
code u8 tab1[10] = //没有小数点的段码
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
};
code u8 tab2[10] = //有小数点的段码
{
0x40, //0
0x79, //1
0x24, //2
0x30, //3
0x19, //4
0x12, //5
0x02, //6
0x78, //7
0x00, //8
0x10, //9带点
};
三、数据读取函数
//============================数据读取函数===================================
u16 ReadADC() //电压读取
{
u16 val;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
val=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
val=5.0/255*100*val;
return val; //返回值 电压放大100倍,方便处理
}
void setDA(float digtal) //DA转换
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CSendByte(digtal);
I2CWaitAck();
I2CSendAck(1);
I2CStop();
}
void Sendwave() //发送方波信号
{
u8 i;
for(i=0;i<8;i++)
{
TX=1;
Delay14us();
TX=0;
Delay14us();
}
}
void setwave() //超声波测距
{
u16 time;
AUXR &= 0xBF; //定时器1模式0,16位,最大85535个计数脉冲
TMOD &= 0x0F;
TL1 = 0x00;
Sendwave(); //发送超声波信号
TR1 = 1; //启动定时器
while((RX==1)&&(TF1==0)); //等待超声波信号返回或者等到测量超出范围
TR1=0; //停止定时器
if(TF1==0) //正常测量范围,根据定时器溢出标志位来判断是否有效
{
time=TH1;
time=(time<<8)| TL1;
distance =(time*17/1000 ) + 3; //(time/2/1000 000 * 340 ) *100 + 3
} //单位cm
else //超出测量范围
{
TF1 = 0;
distance = 99;
}
}
三、初始化函数
//============================初始化函数===================================
void Delay1ms() //@12.000MHz
{
u8 i, j;
i = 22;
j = 169;
do
{
while (--j);
} while (--i);
}
void Delay14us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 39;
while (--i);
}
void SMGbit(u8 pos,u8 val) //数码管位选
{
P2=(P2 &0x1f) |0xc0;
P0=(1<<pos);
P2=(P2 &0x1f) |0xe0;
P0=val;
Delay1ms();
P2=(P2 &0x1f) |0xc0;
P0=0xff;
P2=(P2 &0x1f) |0xe0;
P0=0xff;
}
void IintSystem() //系统初始化
{
P2=(P2 &0x1f) |0x40;
P0=0xff;
P2=(P2 &0x1f) |0xa0;
P0=0x00;
P2=(P2 &0x1f) |0xc0;
P0=0xff;
P2=(P2 &0x1f) |0xe0;
P0=0xff;
}
四、数码管显示模块
//============================数码管显示模块===================================
void setSMG()
{
switch(SMG_mode)
{
case 0: //上电显示电压
SMGbit(0,0xc1);
SMGbit(1,0xff);
SMGbit(2,0xff);
SMGbit(3,0xff);
SMGbit(4,0xff);
SMGbit(5,tab2[ReadADC()/100]);
SMGbit(6,tab1[ReadADC()/10%10]);
SMGbit(7,tab1[ReadADC()%10]); break;
case 1: //参数界面
SMGbit(0,0x8c);
SMGbit(1,0xff);
SMGbit(2,0xff);
SMGbit(3,tab2[Rparm/10]); //上限参数
SMGbit(4,tab1[Rparm%10]);
SMGbit(5,0xff);
SMGbit(6,tab2[Dparm/10]);//下限参数
SMGbit(7,tab1[Dparm%10]); break;
case 2: //超声波界面
if((Dparm*10 <ReadADC()) &&( ReadADC()< Rparm*10 ) )//电压放大了100倍,电压放大了10倍
{F_setwave=1; setwave();} //电压输出是否大于下限参数小于上限参数
else F_setwave=0; // 超声波启动标志位位置1,且开始测量距离
SMGbit(0,0xc3);
SMGbit(1,0xff);
SMGbit(2,0xff);
SMGbit(3,0xff);
SMGbit(4,0xff);
if(F_setwave) //启动了测量
{
SMGbit(5,0xff);
SMGbit(6,tab1[distance/10%10]);
SMGbit(7,tab1[distance%10]);
}
else //没有启动测量
{
SMGbit(5,0x88);
SMGbit(6,0x88);
SMGbit(7,0x88);
}
break;
}
}
五、按键控制模块
//============================按键控制模块===================================
u8 S4sta; //S4状态机位
u8 S5sta; //S5状态机位
u8 S5flag; //S5标志位
void Scankey()
{
if(S4==0) { //切换界面
setSMG();
if(S4==0) {
switch(S4sta)
{
case 0 :SMG_mode=2; S4sta=1; break;
case 1 :SMG_mode=1; S4sta=2; break;
case 2 :SMG_mode=0; S4sta=0; break;
}
while(S4==0) setSMG();
} }
if(S5==0) { //选择上限参数还是下限参数
setSMG();
if(S5==0) {
switch(S5sta)
{
case 0 : S5flag=1; S5sta=1; break;
case 1 : S5flag=0; S5sta=0; break;
}
while(S5==0) setSMG();
} }
if(S6==0) { //对选择的上/下限参数,进行加
setSMG();
if(S6==0) {
switch(S5flag)
{ //限制最大值不超过5V,或者回到0.5V
case 0 : if(Rparm>=50) Rparm=5;else Rparm +=5; break;
case 1 : if(Dparm>=50) Dparm=5; else Dparm +=5; break;
}
while(S6==0) setSMG();
} }
if(S7==0) { //对选择的上/下限参数,进行减
setSMG();
if(S7==0) {
switch(S5flag)
{ //限制最大值不低于0.5V,或者回到5V
case 0 : if(Rparm<=5) Rparm=50;else Rparm -=5; break;
case 1 : if(Dparm<=5) Dparm=50;else Dparm -=5; break;
}
while(S7==0) setSMG();
} }
}
六、LED控制模块
//============================led控制模块===================================
u8 L8shineflag;
u8 cont;
void Timer0Init(void) //50毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xB0; //设置定时初值
TH0 = 0x3C; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1; ET0=1;
}
void Timer0Service(void) interrupt 1 //L8专属
{
cont++;
if(cont==2)
{
cont=0;
L8shineflag=~ L8shineflag; //L8每隔0.1闪亮标志位
}
}
void led()
{
if(F_setwave) //超声波启动标志位
{
if(L8shineflag) { //L8每隔0.1闪亮标志位
P2=(P2&0x1f)|0x80;
L8=0; }
}
else {
P2=(P2&0x1f)|0x80; //没启动则熄灭
L8=1; }
if(SMG_mode==0){ //电压界面
P2=(P2&0x1f)|0x80;
L1=0;
}
else if(SMG_mode==2) {//超声波界面
P2=(P2&0x1f)|0x80;
L2=0;
}
else if(SMG_mode==1){//参数界面
P2=(P2&0x1f)|0x80;
L3=0;
}
else //取消位选
{
P2 = (P2 & 0x1f);
}
}