元件配置及传感器在原理图中
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
单片机源程序如下:
- #include <reg52.h>
- #include <intrins.H>
- #include "i2c.h"
- #define DataPort2_DuanMa P2 //数码管段码数据口
- #define DataPort1_WeiMa P1 //数码管位码数据口
- #define uchar unsigned char
- #define uint unsigned int
- #define AddWr 0x90 //写数据地址
- #define AddRd 0x91 //读数据地址
- #define Pre_Max 45 //设定气压最大值
- #define Pre_Min 10 //设定气压最小值
- extern bit ack;
- unsigned char ReadADC(unsigned char Chl);
- bit WriteDAC(unsigned char dat);
- sbit Key_Set=P3^0; //设置
- sbit Key_Add=P3^1; // 加
- sbit Key_Dec=P3^2; //减
- sbit Key_Str=P3^3; //启动
- sbit Realy_1=P3^6; //继电器1
- sbit Realy_2=P3^7; //继电器2
- sbit Led=P0^6; //系统指示灯
- sbit Bee=P0^7; //蜂鸣器
- sbit Led_Red=P0^4;
- sbit Led_Green=P0^5;
- /*******************************************新加***********************************************************************/
-
- sfr ISP_DATA = 0xe2;
- sfr ISP_ADDRH = 0xe3;
- sfr ISP_ADDRL = 0xe4;
- sfr ISP_CMD = 0xe5;
- sfr ISP_TRIG = 0xe6;
- sfr ISP_CONTR = 0xe7;
- void cc(uint addr);//擦除
- void xcx(uint addr,uchar dat);//写字节
- uchar dcx(uint addr);//读字节
- void Q0();//关闭ISP
-
- /*擦除一个扇区*/
- void cc(uint addr)
- {
- // 0x83(??<5M) 0x82(??<10M) 0x81(??<20M) 0x80(??<40M)
- ISP_CONTR = 0x83; // ?? IAP ??(ISPEN(ISP_CONTR.7)=1:??????Flash, ?? Flash ???????
- ISP_CMD = 0x03; // ?????"Data Flash/EEPROM?"??????
- ISP_ADDRL = addr; // ISP/IAP????????????,
- ISP_ADDRH = addr>>8; // ISP/IAP?????????????
- EA =0;
- ISP_TRIG = 0x46; // ?ISPEN(ISP_CONTR.7)=1?,?ISP_TRIG???46h,
- ISP_TRIG = 0xB9; // ???B9h,ISP/IAP???????
- _nop_();
- Q0(); // ??ISP/IAP
- }
- /*写一个字节*/
- void xcx(uint addr,uchar dat)
- {
- ISP_CONTR = 0x83;
- ISP_CMD = 0x02; // ?????"Data Flash/EEPROM?"??????
- ISP_ADDRL = addr;
- ISP_ADDRH = addr>>8;
- ISP_DATA = dat; // ???ISP_DATA
- EA = 0;
- ISP_TRIG = 0x46;
- ISP_TRIG = 0xB9;
- _nop_();
- Q0(); // ??ISP/IAP
- }
- /*读一个字节*/
- uchar dcx(uint addr)
- {
- uchar dat;
-
- ISP_CONTR = 0x83;
- ISP_CMD = 0x01; // ?????"Data Flash/EEPROM?"?????
- ISP_ADDRL = addr;
- ISP_ADDRH = addr>>8;
- EA = 0;
- ISP_TRIG = 0x46;
- ISP_TRIG = 0xB9;
- _nop_();
- dat = ISP_DATA; // ????
- Q0(); // ??ISP/IAP
- return dat;
- }
- /*关闭ISP操作*/
- void Q0()
- {
- ISP_CONTR = 0; // ??IAP??
- ISP_CMD = 0; // ????,?ISP??
- ISP_TRIG = 0; // ??IAP??, ??ISP??????????
- }
- /***************************************************************************************************************/
- unsigned char code DuanMa[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};// 显示段码值0~9
- unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
- unsigned char TempData[6]; //存储显示值的全局变量
- uchar Pressure_Flag;
- uchar Time_Flag;
- uchar Flash_Pressure_Flag;
- uchar Flash_Time_Flag;
- uchar Data_IIC,Pressure,Pressure2,Time,Time_Buffer,key_press_num,Key_Set_Num;
- uchar Flag_Str,Flag_Test,Flag_Bee,Flag_Count,Flag_Result,State_Red,State_Green,Flag_GetTime,Flag_Realy_1;
- int Time_500ms,Time_CountDown;
- void Display(unsigned char FirstBit,unsigned char Num);
- void Init_Timer0(void);
- void Init_Timer1(void);
- void DelayUs2x(unsigned char t);//微秒延时函数声明
- void DelayMs(unsigned char t);//毫秒延时函数声明
- // void ISR_INT0(void);
- /*------------------------------------------------
- 定时器初始化子程序
- ------------------------------------------------*/
- void Init_Timer1(void)
- {
- TMOD |= 0x10; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
- TH1=0x00; //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
- TL1=0x00;
- EA=1; //总中断打开
- ET1=1; //定时器中断打开
- TR1=1; //定时器开关打开
- }
- /*------------------------------------------------
- 显示数据处理函数1
- ------------------------------------------------*/
- void Display_Data_Operation1(void)
- {
- TempData[0]=DuanMa[(Pressure2)/100];
- TempData[1]=DuanMa[((Pressure2)%100)/10];
- TempData[2]=DuanMa[((Pressure2)%100)%10];
- TempData[3]=DuanMa[Time/100];
- TempData[4]=DuanMa[(Time%100)/10];
- TempData[5]=DuanMa[(Time%100)%10];
- }
- /*------------------------------------------------
- 显示数据处理函数2
- ------------------------------------------------*/
- void Display_Data_Operation2(void)
- {
- TempData[0]=DuanMa[Pressure/100];
- TempData[1]=DuanMa[(Pressure%100)/10];
- TempData[2]=DuanMa[(Pressure%100)%10];
- TempData[3]=0xff;
- TempData[4]=0xff;
- TempData[5]=0xff;
- }
- /*------------------------------------------------
- 显示数据处理函数3
- ------------------------------------------------*/
- void Display_Data_Operation3(void)
- {
- TempData[0]=0xff;
- TempData[1]=0xff;
- TempData[2]=0xff;
- TempData[3]=DuanMa[Time/100];
- TempData[4]=DuanMa[(Time%100)/10];
- TempData[5]=DuanMa[(Time%100)%10];
- }
- /*------------------------------------------------
- 显示数据处理函数4
- ------------------------------------------------*/
- void Display_Data_Operation4(void)
- {
- TempData[0]=DuanMa[Pressure/100];
- TempData[1]=DuanMa[(Pressure%100)/10];
- TempData[2]=DuanMa[(Pressure%100)%10];
- TempData[3]=DuanMa[Time/100];
- TempData[4]=DuanMa[(Time%100)/10];
- TempData[5]=DuanMa[(Time%100)%10];
- }
- /*------------------------------------------------
- 主函数
- ------------------------------------------------*/
- void main (void)
- {
- Flag_Str=0;
- Flag_Test=0;
- Pressure = dcx(0x2000);
- Time= dcx(0x2004);
- EA=1; //全局中断开
- // EX0=1; //外部中断0开
- // IT0=1; //0电平触发 1边沿触发
- Realy_1=1;
- Realy_2=1;
- Init_Timer0();
- Init_Timer1();
- while (1)
- {
- Data_IIC=ReadADC(0);
- Pressure2=(Data_IIC-11)*113/255;
-
- if(!Key_Add && Pressure_Flag==1) //如果检测到低电平,说明按键按下
- {
- DelayMs(10); //延时去抖,一般10-20ms
- if(!Key_Add&& Pressure_Flag==1) //再次确认按键是否按下,没有按下则退出
- {
- while(!Key_Add&& Pressure_Flag==1)
- {
- key_press_num++;
- DelayMs(10); //10x100=1000ms=1s
- if(key_press_num==90) //大约1s
- {
- key_press_num=0; //如果达到长按键标准
- //则进入长按键动作
- while(!Key_Add && Pressure_Flag==1) //这里用于识别是否按
- //键还在按下,如果按
- //下执行相关动作,否则退出
- {
- // if(Vol<99) //加操作
- Pressure++;
- if(Pressure>Pre_Max)
- {
- Pressure=Pre_Min;
- }
- DelayMs(80);//用于调节长按循环操作
- //的速度,可以自行调整此值以便达到最佳效果
- }
- }
- }
- key_press_num=0;//防止累加造成错误识别
- Pressure++;
- if(Pressure>Pre_Max)
- {
- Pressure=Pre_Min;
- }
- }
- }
- if(!Key_Dec && Pressure_Flag==1) //如果检测到低电平,说明按键按下
- {
- DelayMs(10); //延时去抖,一般10-20ms
- if(!Key_Dec && Pressure_Flag==1) //再次确认按键是否按下,没有
- //按下则退出
- {
- while(!Key_Dec && Pressure_Flag==1)
- {
- key_press_num++;
- DelayMs(10);
- if(key_press_num==100) //大约1s
- {
- key_press_num=0;
- while(!Key_Dec && Pressure_Flag==1)
- {
- if(Pressure>Pre_Min) //减操作
- Pressure--;
- DelayMs(80);
- //用于调节长按循环操作的速度
- }
- }
- }
- key_press_num=0;//防止累加造成错误识别
- if(Pressure>Pre_Min) //减操作
- Pressure--;
- }
- }
- if(!Key_Add && Time_Flag==1) //如果检测到低电平,说明按键按下
- {
- DelayMs(10); //延时去抖,一般10-20ms
- if(!Key_Add && Time_Flag==1) //再次确认按键是否按下,没有按下则退出
- {
- while(!Key_Add && Time_Flag==1)
- {
- key_press_num++;
- DelayMs(10); //10x100=1
- if(key_press_num==100) //大约1s
- {
- key_press_num=0; //如果达到长按键标准
- //则进入长按键动作
- while(!Key_Add && Time_Flag==1) //这里用于识别是否按
- //键还在按下,如果按
- //下执行相关动作,否则退出
- {
- Time++;
- if(Time>600)
- {
- Time=0;
- }
- DelayMs(50);//用于调节长按循环操作
- //的速度,可以自行调整此值以便达到最佳效果
- }
- }
- }
- key_press_num=0;//防止累加造成错误识别
- Time++;
- if(Time>600)
- {
- Time=0;
- }
- }
- }
- if(!Key_Dec && Time_Flag==1) //如果检测到低电平,说明按键按下
- {
- DelayMs(10); //延时去抖,一般10-20ms
- if(!Key_Dec && Time_Flag==1) //再次确认按键是否按下,没有
- //按下则退出
- {
- while(!Key_Dec && Time_Flag==1)
- {
- key_press_num++;
- DelayMs(10);
- if(key_press_num==100) //大约1s
- {
- key_press_num=0;
- while(!Key_Dec && Time_Flag==1)
- {
- if(Time>0) //减操作
- Time--;
- DelayMs(50);
- //用于调节长按循环操作的速度
- }
- }
- }
- key_press_num=0;//防止累加造成错误识别
- if(Time>0) //减操作
- Time--;
- }
- }
- /*------------------------------------------------
- 按设置键,保存数据,循环设置参数
- ------------------------------------------------*/
-
- if((!Key_Set) &&(Flag_Count==0) && (Flag_Str==0)&&(Flag_Bee==0)&& (State_Red==0) && (State_Green==0) ) //如果检测到低电平,说明按键按下,并且启动标志为零
- {
- DelayMs(10); //延时去抖,一般10-20ms
- if((!Key_Set) &&(Flag_Count==0)&& (Flag_Str==0)&&(Flag_Bee==0)&& (State_Red==0)&& (State_Green==0)) //再次确认按键是否按下,并且启动标志为零,没有按下则退出
- {
- while((!Key_Set)&&(Flag_Count==0)&& (Flag_Str==0)&&(Flag_Bee==0)&& (State_Red==0)&& (State_Green==0));//如果确认按下按键等待按键释放,没有释放则一直等待
- {
- Key_Set_Num++;
- if(Key_Set_Num>2)
- {
- Key_Set_Num=0;
- }
- // EX0=1;
- // IT0=1;
- cc(0x2000);
- xcx(0x2000,Pressure); // ?EEPROM?2002h??2
- xcx(0x2004,Time);
- EA = 1;
- }
- }
- }
- /*------------------------------------------------
- 设置时的三种循环状态
- ------------------------------------------------*/
- if(Key_Set_Num==0)
- {
- Pressure_Flag=0;
- Time_Flag=0;
- Flash_Pressure_Flag=0;
- Flash_Time_Flag=0;
- }
-
- if(Key_Set_Num==1)
- {
- Pressure_Flag=1;
- Time_Flag=0;
- Flash_Pressure_Flag=1;
- Flash_Time_Flag=0;
- }
-
- if(Key_Set_Num==2)
- {
- Pressure_Flag=0;
- Time_Flag=1;
- Flash_Pressure_Flag=0;
- Flash_Time_Flag=1;
- }
- /*------------------------------------------------
- 按下启动且启动标志置0,不合格状态置0,则启动气泵,并把启动标志置1
- ------------------------------------------------*/
- if( (!Key_Str) && (Flag_Str==0) &&(State_Red==0) &&(Flag_Count==0)) //如果检测到低电平,说明按键按下,并且启动标志为零
- {
- DelayMs(10); //延时去抖,一般10-20ms
- if((!Key_Str) && (Flag_Str==0) &&(State_Red==0) &&(Flag_Count==0) ) //再次确认按键是否按下,并且启动标志为零,没有按下则退出
- {
- while((!Key_Str)&& (Flag_Str==0) &&(State_Red==0)&&(Flag_Count==0) )//如果确认按下按键等待按键释放,没有释放则一直等待
- {
- Flag_Realy_1=1;
- Flag_Str=1;
- }
- }
- }
- if((Pressure2<Pressure)&&(Flag_Realy_1==1))
- {
- Realy_1=0;
- }
-
-
- /*------------------------------------------------
- 同时按下 加 减 ,清除报警状态
- ------------------------------------------------*/
- if( (!Key_Add) &&(!Key_Dec) ) //如果检测到低电平,说明按键按下,并且启动标志为零
- {
- DelayMs(10); //延时去抖,一般10-20ms
- if( (!Key_Add) &&(!Key_Dec) ) //再次确认按键是否按下,并且启动标志为零,没有按下则退出
- {
- while( (!Key_Add) &&(!Key_Dec) )//如果确认按下按键等待按键释放,没有释放则一直等待
- {
- Led_Red=1;
- Bee=1;
- State_Red=0;
- Flag_Count=0;
- Time=Time_Buffer;
- Realy_1=1;
- }
- }
- }
-
- /*------------------------------------------------
- 如果实时压力 > 设定压力 ,且启动标志置1,那么,关闭气泵,把时间放入缓存
- ------------------------------------------------*/
- if( (Pressure2>(Pressure))&&(Flag_Str==1)&&(Flag_Realy_1==1) )
- {
- Realy_1=1;
- Flag_Realy_1=0;
- Time_Buffer=Time;
- Flag_Bee=1;//充气完成的声音提醒
- Flag_Test=1;//检测开始的标志
- Flag_Str=0; //启动标志置0
- }
-
-
- if(Flag_Bee==1)//声音提醒
- {
- Bee=0;
- DelayMs(500);
- DelayMs(500);
- Bee=1;
- Flag_Bee=0;
- }
-
- if(Flag_Test==1)//开始检测
- {
- Time=0;//初始化时间
- Time_CountDown=0;
- Flag_GetTime=1;
- Flag_Test=0;
- Flag_Count=1;
- }
- if(Flag_Count==1)//计数标志置1,时间开始从0计数到设定值
- {
- Time=Time_CountDown/2;
- }
- if((Time==Time_Buffer)&&(Flag_GetTime==1))//计时完成,结果标志置1
- {
- Flag_Count=0;
- Flag_Result=1;
- Flag_GetTime=0;
- }
- /*------------------------------------------------
- 经过一段时间后,如果压力小了,说明不合格,亮红灯,蜂鸣器长响,不合格标志置1
- ------------------------------------------------*/
-
- if((Flag_Count==1) &&(Pressure2*10 < Pressure*8) )
- {
- Flag_Result=0;
- Led_Red=0;
- Bee=0;
- State_Red=1;
- }
-
-
-
-
-
-
- /*------------------------------------------------
- 经过一段时间后,如果压力没减小,说明合格,合格标志置1
- ------------------------------------------------*/
- if((Flag_Result==1) &&(Pressure2*10 > Pressure*9) )
- {
- State_Green=1;
- }
- /*------------------------------------------------
- 合格标志置1后,且结果标志置1,则发出合格提示
- ------------------------------------------------*/
- if((State_Green==1) && (Flag_Result==1))
- {
- Led_Green=0;
- Realy_2=0;
- Bee=0;
- DelayMs(500); //第一响
- Bee=1;
- DelayMs(300);
- Bee=0; //第二响
- DelayMs(500); //第二响
- Bee=1;
- Led_Green=1;
- DelayMs(500);
- Realy_2=1;
- Flag_Result=0;
- State_Green=0;
- Time=Time_Buffer;
- }
-
- }
- }
- /*------------------------------------------------
- 读AD转值程序
- 输入参数 Chl 表示需要转换的通道,范围从0-3
- 返回值范围0-255
- ------------------------------------------------*/
- unsigned char ReadADC(unsigned char Chl)
- {
- unsigned char Val;
- Start_I2c(); //启动总线
- SendByte(AddWr); //发送器件地址
- if(ack==0)return(0);
- SendByte(0x40|Chl); //发送器件子地址
- if(ack==0)return(0);
- Start_I2c();
- SendByte(AddWr+1);
- if(ack==0)return(0);
- Val=RcvByte();
- NoAck_I2c(); //发送非应位
- Stop_I2c(); //结束总线
- return(Val);
- }
-
-
-
-
- /*------------------------------------------------
- us延时函数
- 含有输入参数 unsigned char t,无返回值
- unsigned char 是定义无符号字符变量,其值的范围是
- 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
- 长度如下 T=tx2+5 uS
- ------------------------------------------------*/
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延时函数
- 含有输入参数 unsigned char t,无返回值
- unsigned char 是定义无符号字符变量,其值的范围是
- 0~255 这里使用晶振12M,精确延时请使用汇编
- ------------------------------------------------*/
- void DelayMs(unsigned char t)
- {
-
- while(t--)
- {
- //大致延时1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /*数码管显示函数*/
- void Display(unsigned char FirstBit,unsigned char Lenth)
- {
- static unsigned char i=0;
- DataPort2_DuanMa=0; //清空段码数据,防止重影
- DataPort1_WeiMa=WeiMa[i+FirstBit]; //取位码
- DataPort2_DuanMa=TempData[i]; //取显示数据,段码
- i++;
- if(i==Lenth)
- i=0;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
测漏仪工程.rar
(674.25 KB, 下载次数: 53)
|