//测频率 T0计数 T1定时
//测超声波 T0定时 T1定时
// LED相关函数功能没有写
//把frequence同时给n和Kn,或者把n和kn设置成全局变量--解决了Khz与HZ之间转换的时候莫名少了3K的问题
// pwm 输出的时候会影响 P05 管脚,所以在 led_handle 函数中,离开的时候把通道改了,让他不影响其他功能,例如加一句select573(0)
// number 用来存储继电器开关次数并且写入eeprom里,在湿度界面显示并且验证长按是否把number清零和继电器吸合number是否加1。
// eeprom_val用来读取eeprom看是否存储正确,在湿度参数下显示用来验证number是否正确存入。、
// 考试时不用把number和eeprom_val显示出来,练习只用来验证,考试可去掉
// 所有功能都已完美实现
//测频率 T0计数,T1定时,计数模式把CT位置一 0100或者0101都行
//按键扫描keybuff[0123] <<1 |h0123;
// 按键4与按键7相反的问题 keycode[4]={7,6,5,4}写成了4,5,6,7
// 继电器从高往低是第4位,让继电器吸合P0=0x10;
// 算完频率立马赋值给n和kn
/*高位0不显示,但是用这种方法,一定得在显示函数里把frequence赋值给n和kn不能在直接算出来frequence赋值给n和kn,否则所有都不显示了
for(i=7;(i>=2) && (n!=0);i--)
{
dsbuff[i]=n%10;
n=n/10;
}
*/
题目如下
代码如下:
main函数:
//测频率 T0计数 T1定时
//测超声波 T0定时 T1定时
// LED相关函数功能没有写
//把frequence同时给n和Kn,或者把n和kn设置成全局变量--解决了Khz与HZ之间转换的时候莫名少了3K的问题
// pwm 输出的时候会影响 P05 管脚,所以在 led_handle 函数中,离开的时候把通道改了,让他不影响其他功能,例如加一句select573(0)
// number 用来存储继电器开关次数并且写入eeprom里,在湿度界面显示并且验证长按是否把number清零和继电器吸合number是否加1。
// eeprom_val用来读取eeprom看是否存储正确,在湿度参数下显示用来验证number是否正确存入。、
// 考试时不用把number和eeprom_val显示出来,练习只用来验证,考试可去掉
// 所有功能都已完美实现
#include "stc15f2k60s2.h"
#include "iic.h"
#include "intrins.h"
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(灭)
0x8e, //11(F)
0x88, //12(A)
0x8c, //13(P)
0x89 //14(H)
};
unsigned char code keycode[4]={7,6,5,4};
unsigned char keysta[4]={1,1,1,1};
unsigned char keybackup[4]={1,1,1,1};
unsigned char keybuff[4]={0xff,0xff,0xff,0xff};
unsigned char ym_mode=1;
unsigned char canshu_mode=1;
unsigned char number=0;//继电器开关次数
unsigned char eeprom_val=0; //读取eeprom的值
unsigned char dscom=0;
unsigned char dsbuff[8];
unsigned char juli_canshu=6;
unsigned char pinlv_canshu=90;
unsigned char ad_shidu;
unsigned char pwm_count=0;
unsigned char t=0;
unsigned char led_number=0xff;
unsigned char longting=0;//长按事件标志
unsigned int dis_mid ;
unsigned int pinlv_count=0;
unsigned int frequence;
unsigned int ad_count=0;
unsigned int ad_value;
unsigned int distance ;
unsigned int last_distance;
unsigned int dis_count=0;
unsigned int led_count=0;
unsigned int key_count=0;
float shidu_canshu=40.0;
float y;
bit juli_danwei=0;
bit pinlv_danwei=0;
bit ad_bit=0;
bit dis_bit=0;
bit da_bit=0;
bit jdq_flag=0;
bit l1_flag=0;
bit l2_flag=0;
bit l3_flag=0;
bit l4_flag=0;
bit l5_flag=0;
bit l6_flag=0;
bit l3_shan_flag=0; //led3闪烁标志
bit l2_shan_flag=0; //led2闪烁标志
bit l1_shan_flag=0; //led1闪烁标志
bit key_bit=0;
sbit TX=P1^0;//超声波发送标志
sbit RX=P1^1;//超声波接收标志
sbit h0=P3^0;
sbit h1=P3^1;
sbit h2=P3^2;
sbit h3=P3^3;
void keysong(unsigned char dat);
void keyaction(unsigned char dat);
void yemian();
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
//=============发送脉冲=====================================================================================================
void send_wave()
{
unsigned char i=8;
do
{
TX=1;
Delay12us();
TX=0;
Delay12us();
}while(i--);
}
//==========================================================================================================================
void select573(unsigned char 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 timerinit()
{
TMOD=0x04;
TH1=(65536-100)/256;
TL1=(65536-100)%256;
TF1=0;
ET1=1;
EA=1;
TR1=1;
TH0=0;
TL0=0;
ET0=0;
TF0=0;
}
//=================显示函数=======================
void display()
{
select573(7);
P0=0xff;
select573(6);
P0=1<<dscom;
select573(7);
if(dscom==6 && ym_mode==1 && pinlv_danwei==1)
{
P0=tab[dsbuff[dscom]]&0x7f;
}
else if(dscom==6 && ym_mode==4 && (canshu_mode==1||canshu_mode==3))
{
P0=tab[dsbuff[dscom]]&0x7f;
}
else if(dscom==5 && ym_mode==3 && juli_danwei==1)
{
P0=tab[dsbuff[dscom]]&0x7f;
}
else
P0=tab[dsbuff[dscom]];
P2&=0x1f;
P0=0xff; //********************消影**很重要****************
if(++dscom==8)
dscom=0;
}
//=================按键函数======================================================
//==============按键扫描============
void keyscan()
{
unsigned char i=0;
keybuff[0]=keybuff[0]<<1|h0;
keybuff[1]=keybuff[1]<<1|h1;
keybuff[2]=keybuff[2]<<1|h2;
keybuff[3]=keybuff[3]<<1|h3;
for(i=0;i<4;i++)
{
if((keybuff[i]&0xff)==0)
{
keysta[i]=0; //按键按下
}
else if((keybuff[i]&0xff)==0xff)
{
keysta[i]=1; //没有按下
}
}
}
//==============按键处理============
void keyhandle()
{
unsigned char i=0;
for(i=0;i<4;i++)
{
if(keysta[i]!=keybackup[i])
{
if(keysta[i]==0)
{
keyaction(keycode[i]);
}
else
{
keysong(keycode[i]);
}
keybackup[i]=keysta[i];
}
}
}
//==============按键按下============
void keyaction(unsigned char dat)
{
if(dat==4) //界面按键
{
if(ym_mode==1)
{
ym_mode=2; //湿度界面
l6_flag=0;
}
else if(ym_mode==2)
{
ym_mode=3; //测距界面
}
else if(ym_mode==3)
{
ym_mode=4; //参数界面
l6_flag=0;
}
else if(ym_mode==4)
{
l6_flag=0; //如果L6亮的时候切换了页面,会导致L6一直亮,所以在这个页面把l6_flag清零
ym_mode=1; //频率界面
// TR0=1;
TMOD=0x04;
}
}
else if(dat==5) //参数界面
{
if(ym_mode==4)
{
if(canshu_mode==1) canshu_mode=2; // P2--湿度参数
else if(canshu_mode==2) canshu_mode=3; // P3--距离参数
else if(canshu_mode==3) canshu_mode=1; // P1--频率参数
}
}
else if(dat==6) // 加按键
{
if(ym_mode==4)//参数界面
{
if(canshu_mode==1) // P1--频率参数
{
pinlv_canshu+=5;
if(pinlv_canshu>=120)
pinlv_canshu=120;
}
else if(canshu_mode==2)// P2--湿度参数
{
shidu_canshu+=10;
if(shidu_canshu>=60)
shidu_canshu=60;
}
else if(canshu_mode==3)// P3--距离参数
{
juli_canshu+=1;
if(juli_canshu>=12)
juli_canshu=12;
}
}
else if(ym_mode==3) //测距界面
{
juli_danwei=~juli_danwei;
}
}
else if(dat==7) // 减按键
{
if(ym_mode==4)//参数界面
{
if(canshu_mode==1) // P1--频率参数
{
pinlv_canshu-=5;
if(pinlv_canshu<=10)
pinlv_canshu=10;
}
else if(canshu_mode==2)// P2--湿度参数
{
shidu_canshu-=10;
if(shidu_canshu<=10)
shidu_canshu=10;
}
else if(canshu_mode==3)// P3--距离参数
{
juli_canshu-=1;
if(juli_canshu<=1)
juli_canshu=1;
}
}
else if(ym_mode==1) //频率界面
{
pinlv_danwei=~pinlv_danwei;
}
//***********湿度界面 长按清零继电器次数*************===============================================
if(ym_mode==2)
{
key_bit=1; //按键长按计时标志
}
}
}
//==============按键松开============
void keysong(unsigned char dat)
{
if(dat==7)
{
if(longting==1)
{
longting=0;
number=0;
}
key_count=0;
key_bit=0;
longting=0;
}
}
//==========超声波测距=====================================================================
unsigned char csb_ceju()
{
unsigned char disttt;
TMOD &= 0xf0;
TMOD |= 0x00; // T1不变,T0变成计时模式,CT位置0,工作方式0
TR0=0;
ET0=0;
TF0=0;
send_wave();
TR0=1;
while((RX==1)&&(TF0==0));
TR0=0;
if(TF0==1)
{
TF0=0;
disttt=888;
}
else
{
dis_mid=TH0*256+TL0;
disttt=(dis_mid*0.017);
}
TH0=0;
TL0=0;
return disttt;
}
//==============LED函数================================================================================================
void led_handle()
{
P0=0xff;
select573(4);
P0=led_number;
select573(0);
}
void func_led()
{
//=======L1============
//==频率界面
if(ym_mode==1)
{
l1_flag=1;
}
else
{
l1_flag=0;
}
//==频率参数界面
if(ym_mode==4&&canshu_mode==1)
{
l1_shan_flag=1;
}
else
{
l1_shan_flag=0;
}
//=======L2============
//==湿度界面
if(ym_mode==2)
{
l2_flag=1;
}
else
{
l2_flag=0;
}
//==湿度参数界面
if(ym_mode==4&&canshu_mode==2)
{
l2_shan_flag=1;
}
else
{
l2_shan_flag=0;
}
//=======L3============
//==测距界面
if(ym_mode==3)
{
l3_flag=1;
}
else
{
l3_flag=0;
}
//==距离参数界面
if(ym_mode==4&&canshu_mode==3)
{
l3_shan_flag=1;
}
else
{
l3_shan_flag=0;
}
}
//==============中断函数================================================================================================
void timer()interrupt 3
{
//=======测频率============
if(ym_mode==1) //频率界面
{
pinlv_count++;
if(pinlv_count>=2460)
{
TR0=0;
pinlv_count=0;
frequence=(TH0*256+TL0)*4;
TH0=0;
TL0=0;
TR0=1;
}
}
//===========按键长按=====================
if(key_bit==1)
{
key_count++;
if(key_count>=10000)
{
key_count=0;
longting=1;
}
}
//================================
t++;
if(t>=20)
{
t=0;
keyscan();
display();
yemian();
led_handle();
}
//=======ad采集=====da输出=======
ad_count++;
if(ad_count>=2500)
{
ad_count=0;
ad_bit=1;
da_bit=1;
}
//=======测距离============
if(ym_mode==3) //测距界面
{
dis_count++;
if(dis_count>=2000)
{
dis_count=0;
dis_bit=1;
}
}
//*********脉冲输出功能*********LED4*********************************************
if((frequence/100)>pinlv_canshu)
{
l4_flag=1;
pwm_count++;
if(pwm_count<8)
P05=1;
else if(pwm_count<10)
P05=0;
else
pwm_count=0;
}
else
{
l4_flag=0;
pwm_count++;
if(pwm_count<2)
P05=1;
else if(pwm_count<10)
P05=0;
else
pwm_count=0;
}
//==============LED功能=================================================================================================
//==========L1====*******************
if(l1_flag==1)
{
led_number=led_number & 0xfe;
}
else
{
led_number=led_number | 0x01;
}
//==========L2====*******************
if(l2_flag==1)
{
led_number=led_number & 0xfd;
}
else
{
led_number=led_number | 0x02;
}
//==========L3====*******************
if(l3_flag==1)
{
led_number=led_number & 0xfb;
}
else
{
led_number=led_number | 0x04;
}
//==========L4====*******************
if(l4_flag==1)
{
led_number=led_number & 0xf7;
}
else
{
led_number=led_number | 0x08;
}
//==========L5====*******************
if(l5_flag==1)
{
led_number=led_number & 0xef;
}
else
{
led_number=led_number | 0x10;
}
//==========L6====*******************
if(l6_flag==1)
{
led_number=led_number & 0xdf;
}
else
{
led_number=led_number | 0x20;
}
//==========L1闪烁====*******************
if(l1_shan_flag==1)
{
led_count++;
if(led_count<=1000)
{
led_number=led_number & 0xfe;
}
else if(led_count<=2000)
{
led_number=led_number | 0x01;
}
else
{
led_count=0;
}
}
//==========L2闪烁====*******************
else if(l2_shan_flag==1)
{
led_count++;
if(led_count<=1000)
{
led_number=led_number & 0xfd;
}
else if(led_count<=2000)
{
led_number=led_number | 0x02;
}
else
{
led_count=0;
}
}
//==========L3闪烁====*******************
else if(l3_shan_flag==1)
{
led_count++;
if(led_count<=1000)
{
led_number=led_number & 0xfb;
}
else if(led_count<=2000)
{
led_number=led_number | 0x04;
}
else
{
led_count=0;
}
}
}
//==============main函数=================================================================================================
void main()
{
allinit();
timerinit();
while(1)
{
func_led();
keyhandle();
//*********获取ad值***湿度********LED5*******************************************
if(ad_bit==1)
{
ad_bit=0;
ad_value=pcf_ad();
ad_shidu=20*ad_value/51.1;
if(ad_shidu>shidu_canshu)
{
l5_flag=1;
}
else
{
l5_flag=0;
}
eeprom_val=read_eeprom(0x00);
}
//*********测量距离******************************************************
if(dis_bit==1)
{
last_distance=distance;
dis_bit=0;
distance=csb_ceju();
//*********判断继电器是否吸合*****LED6**********************************************************************(((((((((((((((((((
if(distance>(juli_canshu*10))
{
l6_flag=1;
jdq_flag=1;
select573(5);
P0|=0x10;
}
else
{
l6_flag=0;
jdq_flag=0;
select573(5);
P0&=0xef;
}
if((last_distance<(juli_canshu*10)) && jdq_flag==1)
{
number++;
write_eeprom(0x00,number); //***写入继电器吸合次数
}
}
//*********da输出******************************************************
if(da_bit==1)
{
da_bit=0;
if(ad_shidu<=shidu_canshu)
{
pcf_da(51);
}
else if(ad_shidu>=80)
{
pcf_da(255);
}
else
{
//电压值
y=(4/(80-shidu_canshu))*ad_shidu-4*shidu_canshu/(80-shidu_canshu)+1;
pcf_da(y*51);
}
}
}
}
//==============页面函数=================================================================================================
unsigned int n=0,kn=0;
void yemian()
{
unsigned char i=0;
if(ym_mode==1) //频率界面
{
if(pinlv_danwei==0) //hz
{
n=frequence;
// dsbuff[0]=11;
// dsbuff[1]=1;
// dsbuff[2]=10;
// dsbuff[3]=frequence/10000;
// dsbuff[4]=frequence%10000/1000;
// dsbuff[5]=frequence%1000/100;
// dsbuff[6]=frequence%100/10;
// dsbuff[7]=frequence%10;
dsbuff[0]=11;
dsbuff[1]=1;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=10;
dsbuff[6]=10;
dsbuff[7]=10;
for(i=7;(i>=2)&&(n!=0);i--)
{
dsbuff[i]=n%10;
n=n/10;
}
}
else if(pinlv_danwei==1) //khz
{
kn=frequence/100.0;
dsbuff[0]=11;
dsbuff[1]=2;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=kn/100;
if(dsbuff[5]==0)
{
dsbuff[5]=10;
}
dsbuff[6]=kn/10%10;
dsbuff[7]=kn%10;
}
}
else if(ym_mode==2) //湿度界面
{
dsbuff[0]=14;
dsbuff[1]=10;
dsbuff[2]=number/10;
dsbuff[3]=number%10;
dsbuff[4]=10;
dsbuff[5]=10;
dsbuff[6]=ad_shidu/10;
dsbuff[7]=ad_shidu%10;
}
else if(ym_mode==3) //测距界面
{
if(juli_danwei==0) // cm
{
dsbuff[0]=12;
dsbuff[1]=1;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=distance/100;
if(dsbuff[5]==0)
{
dsbuff[5]=10;
}
dsbuff[6]=distance/10%10;
dsbuff[7]=distance%10;
}
else if(juli_danwei==1) //m
{
dsbuff[0]=12;
dsbuff[1]=2;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=distance/100;
dsbuff[6]=distance/10%10;
dsbuff[7]=distance%10;
}
}
else if(ym_mode==4) //参数界面
{
if(canshu_mode==1) // P1--频率参数
{
dsbuff[0]=13;
dsbuff[1]=1;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=pinlv_canshu/100;
if(dsbuff[5]==0)
{
dsbuff[5]=10;
}
dsbuff[6]=pinlv_canshu/10%10;
dsbuff[7]=pinlv_canshu%10;
}
else if(canshu_mode==2) // P2--湿度参数
{
dsbuff[0]=13;
dsbuff[1]=2;
dsbuff[2]=10;
dsbuff[3]=eeprom_val/10;
dsbuff[4]=eeprom_val%10;
dsbuff[5]=10;
dsbuff[6]=(unsigned char)shidu_canshu/10;
dsbuff[7]=(unsigned char)shidu_canshu%10;
}
else if(canshu_mode==3) // P3--距离参数
{
dsbuff[0]=13;
dsbuff[1]=3;
dsbuff[2]=10;
dsbuff[3]=10;
dsbuff[4]=10;
dsbuff[5]=10;
dsbuff[6]=juli_canshu/10;
dsbuff[7]=juli_canshu%10;
}
}
}
IIC函数:
#include "iic.h"
#include "intrins.h"
sbit scl=P2^0;
sbit sda=P2^1;
#define DELAY_TIME 5
//
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 char temp;
EA=0;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x03);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
temp=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
EA=1;
return temp;
}
void pcf_da(unsigned char dat)
{
EA=0;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x40); //四个单独的通道
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CSendAck(1);
I2CStop();
EA=1;
}
void write_eeprom(unsigned char add,unsigned char val)
{
EA=0;
I2CStart();
I2CSendByte(0xA0);
I2CWaitAck();
I2CSendByte(add);
I2CWaitAck();
I2CSendByte(val);
I2CWaitAck();
I2CStop();
EA=1;
}
unsigned char read_eeprom(unsigned char add)
{
unsigned char dat;
EA=0;
I2CStart();
I2CSendByte(0xA0);
I2CWaitAck();
I2CSendByte(add);
I2CWaitAck();
I2CStart();
I2CSendByte(0xA1);
I2CWaitAck();
dat=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
EA=1;
return dat;
}