- #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;
- }
復制代碼
|