//求最小值的时候把第一次测的值赋值给最小值,依次再作比较,这样防止定义最小值的时候为0,最小值一直为0的情况
//矩阵按键***************可以换成2×2(如果 data超出)********完美代码****************
//计算距离平均值的时候保留一位小数需要乘10,不在算出平均值的时候乘,直接对dsitance乘,这样可以把小数点后的一位显示出来
//=因为没有触发采集距离的时候,数据位不显示,但是平均值那个小数点会显示,所以加一个小数点标志位
//在参数界面下的采集时间设置界面2-4数码管显示了ad采集光照的值
题目如下
代码
main函数:
//求最小值的时候把第一次测的值赋值给最小值,依次再作比较,这样防止定义最小值的时候为0,最小值一直为0的情况
//矩阵按键***************可以换成2×2(如果 data超出)********完美代码****************
//计算距离平均值的时候保留一位小数需要乘10,不在算出平均值的时候乘,直接对dsitance乘,这样可以把小数点后的一位显示出来
//=因为没有触发采集距离的时候,数据位不显示,但是平均值那个小数点会显示,所以加一个小数点标志位
//在参数界面下的采集时间设置界面2-4数码管显示了ad采集光照的值
#include "stc15f2k60s2.h"
#include "intrins.h"
#include "ds1302.h"
#include "iic.h"
sbit h0=P3^0;
sbit h1=P3^1;
sbit h2=P3^2;
sbit h3=P3^3;
sbit l0=P4^4;
sbit l1=P4^2;
sbit l2=P3^5;
sbit l3=P3^4;
unsigned char code tab[]=
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //10(灭)
0xbf, //11(-)
0xfe, //12(上划)
0xf7, //13(下划)
0xc6, //14(C)
0x8e, //15(F)
0xc7, //16(L)
0x89, //17(H)
0x8c //18(P)
};
unsigned char code keycode[4][4]={{7,11,15,19},{6,10,14,18},{5,9,13,17},{4,8,12,16}};
unsigned char keysta[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char keybackup[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char keybuff[4][4]={{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
unsigned char dscom=0;
unsigned char dsbuff[8];
unsigned char number=0;
unsigned char ym_mode=1;
unsigned char shuju_mode=1;
unsigned char canshu_mode=1;
unsigned char lcf_mode=1;
unsigned char value_mode=1;
unsigned char caijishijian=2;
unsigned char juli_canshu=20;
unsigned char l5_number=0;
unsigned char time_count=0;
unsigned char ad_value;
unsigned char ad_value_last;
unsigned char ad_count=0;
unsigned char da_count=0;
unsigned char csb_count=0;
unsigned char i=0;
unsigned int distance;
unsigned int distance_min;
unsigned int distance_max;
unsigned int n;
float distance_ave;
float y;
bit time_bit=0;
bit csb_bit=0;
bit ad_bit=0;
bit da_bit=0;
bit not_bit=0;
void yemian();
void keysong(unsigned char dat);
void keyaction(unsigned char dat);
void select573(channel)
{
P2&=0x1f;
P0=0xff;
switch(channel)
{
case 4:P2=(P2&0x1f)|0x80;break;
case 5:P2=(P2&0x1f)|0xa0;break;
case 6:P2=(P2&0x1f)|0xc0;break;
case 7:P2=(P2&0x1f)|0xe0;break;
}
}
void allinit()
{
select573(4);P0=0xff;
select573(5);P0=0x00;
select573(6);P0=0xff;
select573(7);P0=0xff;
}
void display()
{
select573(7);P0=0xff;
select573(6);
P0=1<<dscom;
select573(7);
if(dscom==6 && ym_mode==1 && shuju_mode==3 && value_mode==2 && not_bit==1)
{
P0=tab[dsbuff[dscom]]&0x7f;
}
else
P0=tab[dsbuff[dscom]];
P2&=0x1f;
P0=0xff;
if(++dscom==8)
dscom=0;
}
void timerinit()
{
TMOD=0x00;
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
TF1=0;
ET1=1;
EA=1;
TR1=1;
TH0=0;
TL0=0;
TF0=0;
}
//=============================按键函数========================================================================================================
//=============按键扫描================
void keyscan()
{
unsigned char i;
static unsigned char keyout=0;
keybuff[keyout][0]=keybuff[keyout][0]<<1|l0;
keybuff[keyout][1]=keybuff[keyout][1]<<1|l1;
keybuff[keyout][2]=keybuff[keyout][2]<<1|l2;
keybuff[keyout][3]=keybuff[keyout][3]<<1|l3;
for(i=0;i<4;i++)
{
if((keybuff[keyout][i]&0x0f)==0)
{
keysta[keyout][i]=0;
}
else if((keybuff[keyout][i]&0x0f)==0x0f)
{
keysta[keyout][i]=1;
}
}
keyout++;
if(keyout>=4)
{
keyout=0;
}
switch(keyout)
{
case 0:h0=0;h3=1;break;
case 1:h1=0;h0=1;break;
case 2:h2=0;h1=1;break;
case 3:h3=0;h2=1;break;
}
}
//=========按键处理====================
void key_handle()
{
unsigned char i,j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(keybackup[i][j]!=keysta[i][j])
{
if(keysta[i][j]==0)
{
keyaction(keycode[i][j]);
}
else if(keysta[i][j]==1)
{
keysong(keycode[i][j]);
}
keybackup[i][j]=keysta[i][j];
}
}
}
}
//=========按键按下====================
void keyaction(unsigned char dat)
{
//=====S4=====界面按键=========
if(dat==4)
{
if(ym_mode==1)
{
ym_mode=2; //参数设置界面
canshu_mode=1; //从数据显示界面进入参数设置界面默认采集时间界面(P1)
}
else if(ym_mode==2)
{
ym_mode=1; //数据显示界面
shuju_mode=1; //从参数设置界面进入数据显示界面默认时间数据显示界面
}
}
//=====S5=====切换按键=========
if(dat==5)
{
if(ym_mode==1) //如果在数据显示界面
{
if(shuju_mode==1)
{
shuju_mode=2; //距离数据显示
}
else if(shuju_mode==2)
{
shuju_mode=3; //数据记录显示
value_mode=1; //每次进入数据记录显示界面,默认当前显示为测距最大值
}
else if(shuju_mode==3)
{
shuju_mode=1; //时间数据显示
}
}
else if(ym_mode==2) //如果在参数设置界面
{
if(canshu_mode==1)
{
canshu_mode=2; // P2--距离参数设置界面
}
else if(canshu_mode==2)
{
canshu_mode=1; // P1--采集时间设置界面
}
}
}
//=====S8=====模式按键=========
if(dat==8)
{
if(ym_mode==1) //数据显示界面
{
if(shuju_mode==2) //距离数据显示
{
if(lcf_mode==1)
{
lcf_mode=2; // LF--定时模式
}
else if(lcf_mode==2)
{
lcf_mode=1; // LC--触发模式
}
}
else if(shuju_mode==3) //数据记录显示
{
if(value_mode==1)
{
value_mode=2; // 平均值
}
else if(value_mode==2)
{
value_mode=3; // 最小值
}
else if(value_mode==3)
{
value_mode=1; // 最大值
}
}
}
}
//=====S9=====调整按键=========
if(dat==9)
{
if(ym_mode==2) //参数设置界面
{
if(canshu_mode==1) // P1--采集时间设置界面
{
if(caijishijian==2) caijishijian=3;
else if(caijishijian==3) caijishijian=5;
else if(caijishijian==5) caijishijian=7;
else if(caijishijian==7) caijishijian=9;
else if(caijishijian==9) caijishijian=2;
}
else if(canshu_mode==2) // P2--距离参数设置界面
{
juli_canshu+=10;
if(juli_canshu>80)
{
juli_canshu=10;
}
}
}
}
}
//============================超声波测距=======================================================================================================
sbit TX=P1^0;
sbit RX=P1^1;
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void send_wave()
{
unsigned char i=0;
for(i=0;i<8;i++)
{
TX=1;
Delay12us();
TX=0;
Delay12us();
}
}
void csb_ceju()
{
unsigned int disttt;
TH0=0;
TL0=0;
TF0=0;
ET0=0;
send_wave();
TR0=1;
while((RX==1)&&(TF0==0));
TR0=0;
disttt=TH0*256+TL0;
if(TF0==0)
{
distance=disttt*0.017;
}
else
{
distance=999;
TF0=0;
}
TH0=0;
TL0=0;
}
//=========按键松开====================
void keysong(unsigned char dat)
{
if(dat==4)
{
}
}
//=============================LED函数========================================================================================================
unsigned char led_number=0xff;
void led_handle()
{
P0=0xff;
select573(4);
P0=led_number;
P2&=0x1f;
}
void func_led()
{
//==========L1=L2=L3=================
if(ym_mode==1)
{
//==========L1==================
if(shuju_mode==1)
{
led_number=led_number & 0xfe;
}
else
{
led_number=led_number | 0x01;
}
//==========L2==================
if(shuju_mode==2)
{
led_number=led_number & 0xfd;
}
else
{
led_number=led_number | 0x02;
}
//==========L3==================
if(shuju_mode==3)
{
led_number=led_number & 0xfb;
}
else
{
led_number=led_number | 0x04;
}
}
//==========L4======================
if(lcf_mode==1)
{
led_number=led_number & 0xf7;
}
else
{
led_number=led_number | 0x08;
}
//==========L5======================
if(distance>=(juli_canshu-5) && distance<=(juli_canshu+5) && lcf_mode==2)
{
l5_number++;
if(l5_number>=3)
{
l5_number=0;
led_number=led_number & 0xef;
}
else
{
led_number=led_number | 0x10;
}
}
//==========L6======================
if(ad_value>=80)
{
led_number=led_number & 0xdf;
}
else
{
led_number=led_number | 0x20;
}
}
//=============================中断函数========================================================================================================
void timer()interrupt 3
{
keyscan();
yemian();
display();
led_handle();
//============读取ds1302时间==============
time_count++;
if(time_count>=250)
{
time_count=0;
time_bit=1;
}
//============测距离=====================================================
if(ym_mode==1 && shuju_mode==2)
{
//=========定时模式=============
if((((clk[0]/16)*10+clk[0]%16)%caijishijian==0)&&(lcf_mode==2))
{
csb_count++;
if(csb_count>=200)
{
csb_bit=1;
csb_count=0;
}
}
else if((ad_value_last-ad_value)>30 &&lcf_mode==1)
{
csb_count++;
if(csb_count>=200)
{
csb_bit=1;
csb_count=0;
}
}
}
//============ad采集光照=====================================================
ad_count++;
if(ad_count>=200)
{
ad_count=0;
ad_bit=1;
}
//============da输出=====================================================
da_count++;
if(da_count>=200)
{
da_count=0;
da_bit=1;
}
}
//=============================main函数========================================================================================================
void main()
{
allinit();
timerinit();
ds1302_init();
while(1)
{
//=========读取ds1302时间============
if(time_bit==1)
{
time_bit=0;
ds1302_read();
}
//=========超声波测距==============
if(csb_bit==1)
{
//=因为没有触发采集距离的时候,数据位不显示,但是平均值那个小数点会显示,所以加一个小数点标志位
not_bit=1;
i++;
csb_bit=0;
csb_ceju();
//=========把第一次测量的值赋值给最小值=和平均值========
if(i==1)
{
distance_min=distance;
distance_ave=distance;
}
//=========求出最大--最小--平均值=================================
//=========最大
if(distance>=distance_max)
{
distance_max=distance;
}
else
{
distance_max=distance_max;
}
//=========最小
if(distance<=distance_min)
{
distance_min=distance;
}
else
{
distance_min=distance_min;
}
//=========平均
distance_ave=(((distance_ave*(i-1))+distance*10.0)/(i*1.0));
}
//=========采集adc光照==============
if(ad_bit==1)
{
ad_value_last=ad_value;
ad_bit=0;
ad_value=pcf_ad(0x01);
}
//=========dac输出==============
if(da_bit==1)
{
da_bit=0;
if(distance<=10)
{
pcf_da(51);
}
else if(distance>=80)
{
pcf_da(255);
}
else
{
y=(0.057143*distance+0.42857)*51;
pcf_da((unsigned char)(y));
}
}
func_led();
key_handle();
}
}
//=========================页面函数============================================================================================================
unsigned char j=0;
void yemian()
{
if(ym_mode==1) //数据显示界面
{
if(shuju_mode==1)//时间数据显示
{
dsbuff[0]=clk[2]/16;
dsbuff[1]=clk[2]%16;
dsbuff[2]=11;
dsbuff[3]=clk[1]/16;
dsbuff[4]=clk[1]%16;
dsbuff[5]=11;
dsbuff[6]=clk[0]/16;
dsbuff[7]=clk[0]%16;
}
else if(shuju_mode==2)//距离数据显示
{
if(lcf_mode==1) // LC--触发模式
{
n=distance;
dsbuff[0]=16;
dsbuff[1]=14;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
// dsbuff[5]=distance/100;
// dsbuff[6]=distance/10%10;
// dsbuff[7]=distance%10;
dsbuff[5]=10;
dsbuff[6]=10;
dsbuff[7]=10;
for(j=7;((j>3)&&(n!=0));j--)
{
dsbuff[j]=n%10;
n=n/10;
}
}
else if(lcf_mode==2) // LF--定时模式
{
n=distance;
dsbuff[0]=16;
dsbuff[1]=15;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
// dsbuff[5]=distance/100;
// dsbuff[6]=distance/10%10;
// dsbuff[7]=distance%10;
dsbuff[5]=10;
dsbuff[6]=10;
dsbuff[7]=10;
for(j=7;((j>3)&&(n!=0));j--)
{
dsbuff[j]=n%10;
n=n/10;
}
}
}
else if(shuju_mode==3)//数据记录显示
{
if(value_mode==1) // 最大值
{
n=distance_max;
dsbuff[0]=17;
dsbuff[1]=12;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
// dsbuff[5]=distance_max/100;
// dsbuff[6]=distance_max/10%10;
// dsbuff[7]=distance_max%10;
dsbuff[5]=10;
dsbuff[6]=10;
dsbuff[7]=10;
for(j=7;((j>3)&&(n!=0));j--)
{
dsbuff[j]=n%10;
n=n/10;
}
}
else if(value_mode==2)// 平均值
{
n=(unsigned int)distance_ave;
dsbuff[0]=17;
dsbuff[1]=11;
dsbuff[2]=10;
dsbuff[3]=10;
// dsbuff[4]=((unsigned int)distance_ave)/1000%10;
// dsbuff[5]=((unsigned int)distance_ave)/100%10;
// dsbuff[6]=((unsigned int)distance_ave)/10%10;
// dsbuff[7]=((unsigned int)distance_ave)%10;
dsbuff[4]=10;
dsbuff[5]=10;
dsbuff[6]=10;
dsbuff[7]=10;
for(j=7;((j>3)&&(n!=0));j--)
{
dsbuff[j]=n%10;
n=n/10;
}
}
else if(value_mode==3) // 最小值
{
n=distance_min;
dsbuff[0]=17;
dsbuff[1]=13;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
// dsbuff[5]=distance_min/100;
// dsbuff[6]=distance_min/10%10;
// dsbuff[7]=distance_min%10;
dsbuff[5]=10;
dsbuff[6]=10;
dsbuff[7]=10;
for(j=7;((j>3)&&(n!=0));j--)
{
dsbuff[j]=n%10;
n=n/10;
}
}
}
}
else if(ym_mode==2) //参数设置界面
{
if(canshu_mode==1)// P1--采集时间设置界面
{
dsbuff[0]=18;
dsbuff[1]=1;
dsbuff[2]=ad_value/100;
dsbuff[3]=ad_value/10%10;
dsbuff[4]=ad_value%10;
dsbuff[5]=10;
dsbuff[6]=caijishijian/10;
dsbuff[7]=caijishijian%10;
}
else if(canshu_mode==2)// P2--距离参数设置界面
{
dsbuff[0]=18;
dsbuff[1]=2;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=10;
dsbuff[6]=juli_canshu/10;
dsbuff[7]=juli_canshu%10;
}
}
}
ds1302函数
#include "ds1302.h"
#include "intrins.h"
//
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^3;
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
unsigned char clk[3];
void ds1302_init()
{
Write_Ds1302_Byte(0x8e,0x00);
Write_Ds1302_Byte(0x80,0x01);
Write_Ds1302_Byte(0x82,0x20);
Write_Ds1302_Byte(0x84,0x13);
Write_Ds1302_Byte(0x8e,0x80);
}
void ds1302_read()
{
clk[2]=Read_Ds1302_Byte(0x85);
clk[1]=Read_Ds1302_Byte(0x83);
clk[0]=Read_Ds1302_Byte(0x81);
}
IIC函数
#include "iic.h"
#include "intrins.h"
#define DELAY_TIME 5
sbit scl=P2^0;
sbit sda=P2^1;
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
unsigned char pcf_ad(unsigned channel)
{
unsigned char adt;
EA=0;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(channel);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
adt=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
EA=1;
return adt;
}
void pcf_da(unsigned char adt)
{
EA=0;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x40);
I2CWaitAck();
I2CSendByte(adt);
I2CWaitAck();
EA=1;
}