#include#include "FUnCTION.H" static unsigned int count = 0; static unsigned int distance = 45; bit isSon = 0; bit isAdr = 0; bit isCel = 0; bit isLE7 = 0; bit isTia = 1; unsigned char Ad_R = 0; static unsigned char Ad_up = 45; static unsigned char Ad_down = 5; static unsigned char Ad_up_temp = 45; static unsigned char Ad_down_temp = 5; unsigned char Key = 0; unsigned char Key0 = 0; bit State2 = 0;//对应2种电压 0-低 1-高 unsigned char State1 = 0;//对应3种显示状态 void Timer0Init(void) //100微秒12.000MHz { AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x50; TH0 = 0xFB; TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 TMOD |= 0x10; //设置定时器1为16位计数器 TL1 = 0; //设置定时初值 TH1 = 0; //设置定时初值 TF1 = 0; //清除TF1标志 TR1 = 0; //关闭定时器1 } unsigned char Key_Num(); //独立按键 void Timer() //定时服务,写在定时器外面,减少中断占用 { if(count == 1) { if(isAdr)//判断是否测压 { Ad_R = AD_Read(0x03); //01光敏,03电位器 } if(isSon)//判断是否测距 { distance = measure_distance(); } } if((count%100)==20) { if(isCel)//led闪烁,由于计时器0有时会被关闭,就用了0.01s,肯定有更好的实现方法,但是 //考试时候时间紧,来不及想 { isLE7 = ~isLE7; } } } void Init() //初始化板子 { Select(5); P0 = 0x00; Select(4); P0 = 0xFF; EA = 1; ET0 = 1; Timer0Init(); } //超声波相关函数 void Delay12us() //@12.000MHz 12us专用延时 { unsigned char i; _nop_(); _nop_(); i = 33; while (--i); } void send_wave() //发送超声波 { unsigned char i; for(i=0;i<8;i++) { TX=1; Delay12us(); TX=0; Delay12us(); } } //超声波测距 unsigned int measure_distance() { unsigned int distance = 0; unsigned int time = 0; //用于计数脉冲个数 TH1 = 0;TL1 = 0; send_wave(); //发送超声波信号 TR0 = 0; TR1 = 1; //启动定时器,开始测距 while((RX == 1)&&(TF1 == 0)); //等待接收到超声波信号返回,或者等到测量超出范围 TF1是溢出标志位,计满溢出后置1 TR1 = 0; //停止定时器 if(RX == 0&&TF1 == 0)//收到返回信号,计算时间 { time = TH1; time = (time<<8)|TL1; //读取定时器脉冲个数,获得时间T distance = (unsigned int)time*0.017 + 1;//时间转化为距离单位cm } else if(RX == 1&&TF1 == 1)//溢出 { TF1 = 0; distance = 999; } TH1 = 0;TL1 = 0; TR1 = 0; TR0 = 1; return distance; } //状态机 void FSM() { Key0 = Key_Num(); if(Key0) { Key = Key0; Key0 = 0; //判断按键并回零 if(Key == 4) { State1++; Key = 0; if(State1 == 3) State1 = 0; } } switch (State1) //根据State1进入相应状态 { case 0:{ //ad状态 if(~isTia) //进入状态0,将调参的参数保存 { Ad_up = Ad_up_temp; Ad_down = Ad_down_temp; isTia = 1; } isAdr = 1; isCel = 1; Nixie_Show_Ad(Ad_R); Select(4); Delay(5); P0 = 0xFE; } break; case 1: //测距状态 { isAdr = 1; isCel = 1; Nixie_Show_Son(distance,isSon); Select(4); P0 = 0xFD; } break; case 2: //调参状态 { if(isTia) { Ad_up_temp = Ad_up; //把Ad已有参数传给temp值 Ad_down_temp = Ad_down; isTia = 0; //转入标志位,表示进入temp状态 } isAdr = 0; isCel = 0; isLE7 = 0;//关闭led8闪烁 Nixie_Show_Can(Ad_down_temp,Ad_up_temp); Select(4); Delay(5); P0 = 0xFB;//使led8常亮 if(Key == 5) // { State2 = ~State2; //调整调参变量 Key = 0; } if(State2) { if(Key == 6) { Ad_up_temp += 5; if(Ad_up_temp >= 50)Ad_up_temp = 0; Key = 0; } if(Key == 7) { Ad_up_temp -= 5; if(Ad_up_temp <= 5)Ad_up_temp = 50; Key = 0; } } else { if(Key == 6) { Ad_down_temp += 5; if(Ad_down_temp >= 50)Ad_down_temp = 0; Key = 0; } if(Key == 7) { Ad_down_temp -= 5; if(Ad_down_temp <= 5)Ad_down_temp = 50; Key = 0; } } Key = 0;//key归零,方便再次检测 } break; default: break; } if(isSon)//根据是否打开超声波检测,以及测量值输出电压详细规则见题目 { if(distance<20)DA_Set(51); else if(80 Function.h文件
#ifndef _FUNCTION_H_ #define _FUNCTION_H_ #includeFunction.c文件#include "IIC.H" #include "intrins.h" sbit TX=P1^0; //超声波针脚 sbit RX=P1^1; //各种显示函数 void Select(unsigned char val); void Delay(unsigned int xus); void Nixie_Show(unsigned char ch,unsigned char dat); void Nixie_Show_Son(unsigned int son,bit isSon); void Nixie_Show_Ad(unsigned char ad); void Nixie_Show_Can(unsigned char down,up); //ad,da函数 unsigned char AD_Read(unsigned char add); void DA_Set(unsigned char val); #endif #include "FUNCTION.H" //都是一些常用的基本模块,没啥可说的 code unsigned char Date[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x80,0x3E,0x73,0x3C,0x77}; // 0~9 . U P L code unsigned char Com[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; void Delay(unsigned int xus) { while(xus--); } void Select(unsigned char val) { switch (val) { 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; default: break; } } void Nixie_Show(unsigned char ch,unsigned char dat) { P2 = P2&0x1F|0xC0; Delay(5); P0 = Com[ch]; P2 = P2&0x1F|0xE0; Delay(5); P0 = ~Date[dat]; Delay(100); P2 = P2&0x1F|0x00; } void Nixie_Show_Son(unsigned int son,bit isSon) { if(isSon) { Nixie_Show(0,13); if(son%1000/100) { Nixie_Show(5,son%1000/100); Nixie_Show(6,son%100/10); Nixie_Show(7,son%10); } else if(son%100/10) { Nixie_Show(6,son%100/10); Nixie_Show(7,son%10); } else { Nixie_Show(7,son%10); } } else { Nixie_Show(0,13); Nixie_Show(5,14); Nixie_Show(6,14); Nixie_Show(7,14); } } void Nixie_Show_Ad(unsigned char ad) { unsigned int adin = (int)(ad*(1.96));//500/255=1.96 Nixie_Show(0,11); Nixie_Show(5,adin/100); Nixie_Show(5,10); Nixie_Show(6,adin%100/10); Nixie_Show(7,adin%10); } void Nixie_Show_Can(unsigned char down,up) { Nixie_Show(0,12); Nixie_Show(3,down%100/10); Nixie_Show(3,10); Nixie_Show(4,down%10); Nixie_Show(6,up%100/10); Nixie_Show(6,10); Nixie_Show(7,up%10); } void DA_Set(unsigned char val) { IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(0x43); IIC_WaitAck(); IIC_SendByte(val); IIC_WaitAck(); IIC_Stop(); } unsigned char AD_Read(unsigned char add) { unsigned char rec; IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(add); IIC_WaitAck(); //Delay(5000); IIC_Start(); IIC_SendByte(0x91); IIC_WaitAck(); rec = IIC_RecByte(); IIC_SendByte(0); IIC_Stop(); return rec; }IIC.h文件#ifndef _IIC_H #define _IIC_H void IIC_Start(void); void IIC_Stop(void); bit IIC_WaitAck(void); void IIC_SendAck(bit ackbit); void IIC_SendByte(unsigned char byt); unsigned char IIC_RecByte(void); #endifIIC.c文件#include "reg52.h" #include "intrins.h" #define DELAY_TIME 5 #define SlaveAddrW 0xA0 #define SlaveAddrR 0xA1 //总线引脚定义 sbit SDA = P2^1; sbit SCL = P2^0; void IIC_Delay(unsigned char i) { do{_nop_();} while(i--); } //总线启动条件 void IIC_Start(void) { SDA = 1; SCL = 1; IIC_Delay(DELAY_TIME); SDA = 0; IIC_Delay(DELAY_TIME); SCL = 0; } //总线停止条件 void IIC_Stop(void) { SDA = 0; SCL = 1; IIC_Delay(DELAY_TIME); SDA = 1; IIC_Delay(DELAY_TIME); } //发送应答 void IIC_SendAck(bit ackbit) { SCL = 0; SDA = ackbit; // 0:应答,1:非应答 IIC_Delay(DELAY_TIME); SCL = 1; IIC_Delay(DELAY_TIME); SCL = 0; SDA = 1; IIC_Delay(DELAY_TIME); } //等待应答 bit IIC_WaitAck(void) { bit ackbit; SCL = 1; IIC_Delay(DELAY_TIME); ackbit = SDA; SCL = 0; IIC_Delay(DELAY_TIME); return ackbit; } //通过I2C总线发送数据 void IIC_SendByte(unsigned char byt) { unsigned char i; for(i=0; i<8; i++) { SCL = 0; IIC_Delay(DELAY_TIME); if(byt & 0x80) SDA = 1; else SDA = 0; IIC_Delay(DELAY_TIME); SCL = 1; byt <<= 1; IIC_Delay(DELAY_TIME); } SCL = 0; } //从I2C总线上接收数据 unsigned char IIC_RecByte(void) { unsigned char i, da; for(i=0; i<8; i++) { SCL = 1; IIC_Delay(DELAY_TIME); da <<= 1; if(SDA) da |= 1; SCL = 0; IIC_Delay(DELAY_TIME); } return da; }



