- #include <reg52.h>
- #include <intrins.h>
- bit flag =1; //采样刷新标志位
- sbit SCL = P2^1; //I2C时钟
- sbit SDA = P2^0; //I2C数据
- sbit du=P2^6; //数码管段选
- sbit we=P2^7; //数码管位选
- sbit RST=P2^4; //DS1302时钟使能端
- sbit in1=P3^4; //键盘行扫描检测
- sbit in2=P3^5;
- sbit in3=P3^6;
- sbit in4=P3^7;
- sbit bibi=P2^3;
- unsigned int code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管显示译码
- unsigned int buffer[3]={0x00,0x00,0x00}; //电压显示缓存
- unsigned char Ratebuffer[6]; //采样周期送串口缓存
- unsigned int ConfigBuffer[4]; //采样周期数码管显示缓存
- unsigned char sending; //串口发送一字节数据发送完成标志位
- unsigned int Timerflag=1000; //采样周期全局变量
- unsigned int TimerflagBuffer; //采样周期缓存,用于判断采样周期是否发生变化,若是则送24C02储存
- unsigned char TimerT0[4]; //存储按键设置的采样周期各位数
- unsigned char num1; //将采样周期分解为两个8位数据,送24C02存储
- unsigned char num2;
- unsigned int te;
- unsigned int tr;
- unsigned int valu;
- void Delay(); //用于I2C总线延迟
- void delay1(unsigned char a); //用于数码管显示延迟以及24C02存储延迟
- void Start(); //I2C总线开始信号
- void Stop(); //I2C总线结束信号
- bit Write(unsigned char dat); //向I2C总线写一字节数据,并返回应答信号
- unsigned char ReadNAK(); //从I2C总线读一字节数据
- unsigned char ReadACK(); //从I2C总线读多字节数据
- void Timer(); //1ms定时,用于采样周期
- unsigned char ADC(unsigned char ch); //从ADC读一字节数据
- void display(unsigned int t0,unsigned int t1,unsigned int t2); //数码管显示电压值
- void display2(unsigned int t0,unsigned int t1,unsigned int t2,unsigned int t3); //数码管显示采样周期
- void transfer(unsigned char *str,unsigned int val); //将电压值转换为ASCII码,用于串口发送
- void UART(); //设置串行通信
- void Config(); //设置外部中断1
- unsigned char E2Read(unsigned char addr); //从24C02读取最后一次设置的采样周期,用于程序初始化
- void E2Write(unsigned char addr,unsigned char dat); //向24C02写入变化后的采样周期
- void main()
- {
- unsigned int val;
- unsigned char str[10];
- unsigned char i;
-
-
- RST=0; //DS1302芯片占用I2C总线,应先关闭使能
- num1=E2Read(0);
- num2=E2Read(1);
- Timerflag=num2*256+num1;
- TimerflagBuffer=Timerflag;
- Config();
- Timer();
- UART();
-
- while(1)
- {
- if(in1==0) //若按键1按下,则进入外部中断1
- P3=0xf7;
- if(flag==1)
- {
- flag=0;
- val=ADC(2);
- val=196*val/100; //转换ADC读出的原始数据,避免小数运算
-
- valu=val;
- buffer[0]=table[val%10];
- buffer[1]=table[val/10%10];
- buffer[2]=table[val/100%10]+0x80;
-
- Ratebuffer[0]=','; //将采样周期转ASCII码,用于串口发送
- Ratebuffer[1]=Timerflag/1000%10+'0';
- Ratebuffer[2]=Timerflag/100%10+'0';
- Ratebuffer[3]=Timerflag/10%10+'0';
- Ratebuffer[4]=Timerflag%10+'0';
- Ratebuffer[5]=',';
-
- transfer(str,val);
-
- for(i=0;i<5;i++)
- {
- SBUF=str[i];
- sending=1;
- while(sending);
- }
- for(i=0;i<6;i++)
- {
- SBUF=Ratebuffer[i];
- sending=1;
- while(sending);
- }
-
- }
- display(buffer[0],buffer[1],buffer[2]);
-
- if(valu>400)
- {
- if(te<200)bibi=0;
- else bibi=1;
- }
- if(valu<150)
- {
- if(tr<800)bibi=0;
- else bibi=1;
- }
- if(valu>150&&valu<400)
- {
- te=0;
- tr=0;
- bibi=1;
- }
- if(TimerflagBuffer!=Timerflag) //检测采样周期变化,并存储到掉电不丢失模块
- {
- num2=Timerflag/256;
- num1=Timerflag%256;
- E2Write(0,num1);
- E2Write(1,num2);
- TimerflagBuffer=Timerflag;
- }
- }
- }
- void Delay()
- {
- _nop_();_nop_();_nop_();_nop_();
- }
- void delay1(unsigned char a)
- {
- unsigned char j,k;
- for(j=a;j>0;j--)
- for(k=125;k>0;k--);
- }
- void Start()
- {
- SDA=1;
- SCL=1;
- Delay();
- SDA=0;
- Delay();
- SCL=0;
- }
- void Stop()
- {
- SCL=0;
- SDA=0;
- Delay();
- SCL=1;
- Delay();
- SDA=1;
- Delay();
- }
- bit Write(unsigned char dat)
- {
- bit ack;
- unsigned char mask;
- for(mask=0x80;mask!=0;mask>>=1)
- {
- if((mask&dat)==0)
- {
- SDA=0;
- }
- else
- {
- SDA=1;
- }
- Delay();
- SCL=1;
- Delay();
- SCL=0;
- }
-
- SDA=1;
- Delay();
- SCL=1;
- ack=SDA;
- Delay();
- SCL=0;
- return(ack);
- }
- unsigned char ReadNAK()
- {
- unsigned char mask;
- unsigned char dat;
- SDA=1;
- for(mask=0x80;mask!=0;mask>>=1)
- {
- Delay();
- SCL=1;
- if(SDA==0)
- {
- dat&= ~mask;
- }
- else
- {
- dat|=mask;
- }
- Delay();
- SCL=0;
- }
- SDA=1;
- Delay();
- SCL=1;
- Delay();
- SCL=0;
- return dat;
- }
- unsigned char ReadACK()
- {
- unsigned char mask;
- unsigned char dat;
- SDA=1;
- for(mask=0x80;mask!=0;mask>>=1)
- {
- Delay();
- SCL=1;
- if(SDA==0)
- {
- dat&=~mask;
- }
- else
- {
- dat|=mask;
- }
- Delay();
- SCL=0;
- }
- SDA=0;
- Delay();
- SCL=1;
- Delay();
- SCL=0;
- return(dat);
- }
- void Timer()
- {
- TMOD=0x01;
- TH0=0xfc;
- TL0=0x66;
- ET0=1;
- EA=1;
- TR0=1;
- }
- unsigned char ADC(unsigned char ch)
- {
- unsigned char val;
- EA=0;
- Start();
- if(Write(0x48<<1))
- {
- Stop();
- return 0;
- }
- Write(0x40|ch);
- Start();
- Write((0x48<<1)|0x01);
- val=ReadACK();
- val=ReadNAK();
- Stop();
- EA=1;
- return val;
- }
- void display(unsigned int t0,unsigned int t1,unsigned int t2)
- {
- P0=t0;du=1;du=0;P0=0xdf;we=1;we=0;delay1(5);
- P0=t1;du=1;du=0;P0=0xef;we=1;we=0;delay1(5);
- P0=t2;du=1;du=0;P0=0xf7;we=1;we=0;delay1(5);
- }
- void display2(unsigned int t0,unsigned int t1,unsigned int t2,unsigned int t3)
- {
- P0=t0;du=1;du=0;P0=0xdf;we=1;we=0;delay1(5);
- P0=t1;du=1;du=0;P0=0xef;we=1;we=0;delay1(5);
- P0=t2;du=1;du=0;P0=0xf7;we=1;we=0;delay1(5);
- P0=t3;du=1;du=0;P0=0xfb;we=1;we=0;delay1(5);
- }
- void transfer(unsigned char *str,unsigned int val)
- {
- str[0]=(val/100%10)+'0';
- str[1]='.';
- str[2]=(val/10%10)+'0';
- str[3]=(val%10)+'0';
- str[4]='V';
- }
- void UART()
- {
- EA=0;
- SCON=0x50;
- PCON=0x00;
- TMOD|=0x20;
- TH1=0xfd;
- TL1=0xfd;
- REN=1;
- ES=1;
- TR1=1;
- EA=1;
- }
- void Config()
- {
- EA=0;
- TCON|=0x04;
- P3=0xff;
- EX1=1;
- EA=1;
-
- }
- unsigned char E2Read(unsigned char addr)
- {
- unsigned char dat;
-
- Start();
- Write(0xa0);
- Write(addr);
- Start();
- Write(0xa1);
- dat=ReadNAK();
- Stop();
- delay1(100);
- return dat;
- }
- void E2Write(unsigned char addr,unsigned char dat)
- {
- Start();
- Write(0xa0);
- Write(addr);
- Write(dat);
- Stop();
- delay1(5000);
- }
- void interruptT0() interrupt 1 //定时器T0中断,通过标志位完成设置的采样周期计时
- {
- static unsigned long t = 0;
- TH0=0xfc;
- TL0=0x66;
- t++;
- if(valu>400)
- {
- te++;
- if(te>400)
- te=1;
- }
- if(valu<400&&valu>150)
- {
- te=0;tr=0;bibi=1;
- }
- if(valu<150)
- {
- tr++;
- if(tr>1600)
- tr=1;
- }
- if(t>=Timerflag)
- {
- t=0;
- flag=1;
- }
- }
- void interruptS() interrupt 4
- {
- unsigned long temp;
- static signed char n=3;
- static unsigned char t[4]; //串口接收到的采样周期缓存
- if(RI==1)
- {
- EA=0;
- RI=0;
- temp=SBUF;
- if(n>=0)
- {
- t[n]=temp-'0'; //将接收到的ASCII码转换为10进制存储
- n--;
- }
- if(n<0) //接收到四位数后更新采样周期
- {
- n=3;
- Timerflag=t[3]*1000+t[2]*100+t[1]*10+t[0];
-
- }
- EA=1;
-
- }
- else
- {
- TI=0;
- sending=0;
- }
- }
- void interruptEX0() interrupt 2 //外部中断1,完成按键操作,进入中断后立即显示当前的采样周期
- {
- signed char i;
- bit backup; //按键备份,用于去抖
- REN=0;
- EA=0;
- ConfigBuffer[0]=table[Timerflag%10];
- ConfigBuffer[1]=table[Timerflag/10%10];
- ConfigBuffer[2]=table[Timerflag/100%10];
- ConfigBuffer[3]=table[Timerflag/1000%10];
- while(1)
- {
- display2(ConfigBuffer[0],ConfigBuffer[1],ConfigBuffer[2],ConfigBuffer[3]);
- if(in2==0) //按键2按下则退出中断服务程序
- {
- P3=0xff;
- EA=1;
- break;
- }
- if(in3==0) //按键3按下则开始设置采样周期,并在数码管显示
- {
- while(in3!=1); //检测按键跳变
- ConfigBuffer[0]=0x00;ConfigBuffer[1]=0x00;ConfigBuffer[2]=0x00;ConfigBuffer[3]=0x00;
- while(1)
- {
-
- for(i=3;i>=0;i--) //键盘矩阵扫描,读取4位采样周期
- {
- while(1)
- {
- display2(ConfigBuffer[0],ConfigBuffer[1],ConfigBuffer[2],ConfigBuffer[3]);
- P3=0xfe;
- if(in1==0)
- {
- backup=in1; //按键去抖
- delay1(20);
- if(backup!=in1)continue;
- while(in1!=1); //检测跳变为一次有效按键
- ConfigBuffer[i]=table[0];TimerT0[i]=0;break;
- }
- if(in2==0)
- {
- backup=in2;
- delay1(20);
- if(backup!=in2)continue;
- while(in2!=1);
- ConfigBuffer[i]=table[1];TimerT0[i]=1;break;
- }
- if(in3==0)
- {
- backup=in3;
- delay1(20);
- if(backup!=in3)continue;
- while(in3!=1);
- ConfigBuffer[i]=table[2];TimerT0[i]=2;break;
- }
- if(in4==0)
- {
- backup=in4;
- delay1(20);
- if(backup!=in4)continue;
- while(in4!=1);
- ConfigBuffer[i]=table[3];TimerT0[i]=3;break;
- }
- P3=0xfd;
- if(in1==0)
- {
- backup=in1;
- delay1(20);
- if(backup!=in1)continue;
- while(in1!=1);
- ConfigBuffer[i]=table[4];TimerT0[i]=4;break;
- }
- if(in2==0)
- {
- backup=in2;
- delay1(20);
- if(backup!=in2)continue;
- while(in2!=1);
- ConfigBuffer[i]=table[5];TimerT0[i]=5;break;
- }
- if(in3==0)
- {
- backup=in3;
- delay1(20);
- if(backup!=in3)continue;
- while(in3!=1);
- ConfigBuffer[i]=table[6];TimerT0[i]=6;break;
- }
- if(in4==0)
- {
- backup=in4;
- delay1(20);
- if(backup!=in4)continue;
- while(in4!=1);
- ConfigBuffer[i]=table[7];TimerT0[i]=7;break;
- }
- P3=0xfb;
- if(in1==0)
- {
- backup=in1;
- delay1(20);
- if(backup!=in1)continue;
- while(in1!=1);
- ConfigBuffer[i]=table[8];TimerT0[i]=8;break;
- }
- if(in2==0)
- {
- backup=in2;
- delay1(20);
- if(backup!=in2)continue;
- while(in2!=1);
- ConfigBuffer[i]=table[9];TimerT0[i]=9;break;
- }
- }
- }
- Timerflag=TimerT0[3]*1000+TimerT0[2]*100+TimerT0[1]*10+TimerT0[0];
-
- P3=0xff;
- EA=1;
- break;
- }
-
- }
- }
- REN=1;
- }
复制代码
|