藍橋杯單片機學習過程記錄(三十一)第九屆國賽多功能測量儀表

藍橋杯單片機學習過程記錄(三十一)第九屆國賽多功能測量儀表

第九屆國賽,比較基礎。有幾點需要注意:一是溫度獲取需要小數,定義變量時long。二是存儲時拆分開成兩部分進行存儲,要不然eeprom保存不了那麼大的數字。三是小燈亮滅部分誰開誰閉,非與或燈要理清楚。四是NE555的計數定時,要清楚定時器的原理。
應用的內容:
獨立按鍵、數碼管
led、定時器
溫度傳感器DS18B20
IIC中RB2和EEPROM讀取寫入
NE555方波產生器
題目如下:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

/*
---------------------
第九屆國賽多功能測量儀表
2020.3.29
完成
---------------------
*/


#include<STC15F2K60S2.H>
#include<intrins.h>
#include<onewire.h>
#include<iic.h>

sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;

bit flag_shanshuo;
long wendu;
unsigned int count_freq,freq,rb2_read;
unsigned char t_1,rb2_save,freq_save_1,freq_save_2,wendu_save_1,wendu_save_2,dis_h_1,dis_h_2,dianya_set;
unsigned char flag_yemian,flag_h,flag_longset;
unsigned char yi,er,san,si,wu,liu,qi,ba;
unsigned char seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10, 0xbf,0xff,0xc1,0xc6,0x8e,0x89,0x8c};
void allinit();
void delayms(int ms);
void display_12(yi,er);
void display_34(san,si);
void display_56(wu,liu);
void display_78(qi,ba);
void Timer0Init(void);
void Timer1Init(void);
unsigned char iic_read(unsigned char add);
void eeprom_write(unsigned char add,unsigned char dat);
unsigned char eeprom_read(unsigned char add);
long ds18b20_get();
void key_scan();
void led_set();	
//主函數
void main(){
	//初始化
	allinit();
	Timer0Init();Timer1Init();
	EA=1;ET0=1;ET1=1;
	dianya_set=eeprom_read(0x10);delayms(5);
	while(1){
		//實時讀取電壓
		rb2_read=iic_read(0x03)*2;
		//小燈亮滅函數
		led_set();		
		//電壓顯示界面
		if(flag_yemian==0){
			yi=22;er=21;san=21;si=21;wu=21;liu=21;qi=rb2_read/100+10;ba=rb2_read%100/10;
		}
		//頻率顯示界面
		else if(flag_yemian==1){
			yi=24;er=21;san=21;si=freq/10000;wu=freq%10000/1000;liu=freq%1000/100;qi=freq%100/10;ba=freq%10;
		}
		//溫度顯示界面
		else if(flag_yemian==2){
			wendu=ds18b20_get();
			yi=23;er=21;san=21;si=21;wu=wendu/100000;liu=wendu%100000/10000+10;qi=wendu%10000/1000;ba=wendu%1000/100;
		}
		//數據回顯界面
		else if(flag_yemian==3){
			//電壓顯示
			if(flag_h==0){
				dis_h_1=eeprom_read(0x01);
				yi=25;er=22;san=21;si=21;wu=21;liu=21;qi=dis_h_1/10+10;ba=dis_h_1%10;
			}
			//溫度顯示
			else if(flag_h==1){
				dis_h_1=eeprom_read(0x02);
				dis_h_2=eeprom_read(0x03);
				yi=25;er=23;san=21;si=21;wu=dis_h_1/10;liu=dis_h_1%10+10;qi=dis_h_2/10;ba=dis_h_2%10;
			}
			//頻率顯示
			else if(flag_h==2){
				dis_h_1=eeprom_read(0x04);
				dis_h_2=eeprom_read(0x05);
				yi=25;er=24;san=21;si=dis_h_1/10;wu=dis_h_1%10;liu=dis_h_2/10;qi=dis_h_2%10;ba=0;
			}
		}
		//電壓閾值設置界面
		else if(flag_yemian==4){
			yi=26;er=21;san=21;si=21;wu=21;liu=21;qi=dianya_set/10+10;ba=dianya_set%10;
		}
		//按鍵
		key_scan();
		display_12(yi,er);
		display_34(san,si);
		display_56(wu,liu);
		display_78(qi,ba);
	}
}
//獨立按鍵
void key_scan(){
	//s4控制切換界面,回顯數據
	if(s4==0){
		delayms(5);
		if(s4==0){
			//回顯界面
			if(flag_yemian==3){
				flag_h++;
				if(flag_h==3)
					flag_h=0;
			}
			//測量界面
			else{
				flag_yemian++;
				if(flag_yemian==3)
					flag_yemian=0;
			}
		}
		while(!s4);
	}
	//s5存儲
	else if(s5==0){
		delayms(5);
		if(s5==0){
			//保存電壓
			rb2_read=iic_read(0x03)*2;
			rb2_save=rb2_read/100*10+rb2_read%100/10;
			eeprom_write(0x01,rb2_save);delayms(5);
			//保存溫度,拆分開
			wendu=ds18b20_get();
			wendu_save_1=wendu/100000*10+wendu%100000/10000;
			wendu_save_2=wendu%10000/1000*10+wendu%1000/100;
			eeprom_write(0x02,wendu_save_1);delayms(5);
			eeprom_write(0x03,wendu_save_2);delayms(5);
			//保存頻率拆分開
			freq_save_1=freq/10000*10+freq%10000/1000;
			freq_save_2=freq%1000/100*10+freq%100/10;
			eeprom_write(0x04,freq_save_1);delayms(5);
			eeprom_write(0x05,freq_save_2);delayms(5);
		}
		while(!s5);
	}
	//s6回顯界面及設置閾值
	else if(s6==0){
		delayms(5);
		if(s6==0){
			//回顯界面
			if(flag_yemian==3)
				flag_yemian=0;
			//閾值設定
			else if(flag_yemian==4){
				flag_longset=1;
				t_1=0;
				dianya_set++;
				if(dianya_set>50)
					dianya_set=1;
			}
			else
				flag_yemian=3;
		}
		while(!s6){
			//閾值設定時,按下超過0.8s,快速增加
			if(flag_yemian==4){
				if(flag_longset==2){
					dianya_set++;
					if(dianya_set>50)
						dianya_set=1;
				}
				yi=26;er=21;san=21;si=21;wu=21;liu=21;qi=dianya_set/10+10;ba=dianya_set%10;
				display_12(yi,er);display_34(san,si);display_56(wu,liu);display_78(qi,ba);
			}
		}
		flag_longset=0;
	}
	//s7控制電壓閾值設定保存
	else if(s7==0){
		delayms(5);
		if(s7==0){
			if(flag_yemian==4){
				flag_yemian=0;
				eeprom_write(0x10,dianya_set);delayms(5);
			}
			else
				flag_yemian=4;
		}
		while(!s7);
	}
}
//小燈亮滅函數
void led_set(){
	//判斷電壓
	if(rb2_read>dianya_set*10){
		if(flag_shanshuo==0) {
			P2=0X80;P0=0X7F;
		}
		else {
			P2=0X80;P0=0XFF;
		}
	}
	else {
		P2=0X80;P0=0XFF;
	}
	//判斷當前測量
	if(flag_yemian==0){
		P2=0X80;P0=~(~P0|0X04);
	}
	else if(flag_yemian==1){
		P2=0X80;P0=~(~P0|0X02);
	}
	else if(flag_yemian==2){
		P2=0X80;P0=~(~P0|0X01);
	}
	else {
		P2=0X80;P0=P0;
	}
}
//DS18B20溫度獲取
long ds18b20_get(){
	unsigned char low,high;
	long temp;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	delayms(1);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	delayms(1);
	low=Read_DS18B20();
	high=Read_DS18B20();
	init_ds18b20();
	temp=high&0x0f;
	temp<<=8;
	temp|=low;
	temp=temp*625;
	return temp;
}
//eeprom讀取
unsigned char eeprom_read(unsigned char add){
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	return temp;
}
//eeprom寫入
void eeprom_write(unsigned char add,unsigned char dat){
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
//IIc讀取
unsigned char iic_read(unsigned char add){
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	return temp;
}
//定時器0用來計數
void time0() interrupt 1{
	count_freq++;
}
//定時器1用來定時
void time1() interrupt 3{
	t_1++;
	if(flag_longset==1){
		if(t_1==160)
			flag_longset=2;
	}
	if(rb2_read>dianya_set*10){
		if(t_1%40==0){
			flag_shanshuo=!flag_shanshuo;
		}
	}
	if(t_1==200){
		freq=count_freq;
		count_freq=0;
		t_1=0;
	}
}
//定時器1定時5ms
void Timer1Init(void)
{
	AUXR |= 0x40;
	TMOD &= 0x0F;	
	TL1 = 0x00;		
	TH1 = 0x28;		
	TF1 = 0;	
	TR1 = 1;	
}
//定時器0計數模式
void Timer0Init(void)	
{
	AUXR |= 0x80;	
	TMOD &= 0x0F;	
	TMOD |= 0x04;	
	TL0 = 0XFF;		
	TH0 = 0XFF;		
	TF0 = 0;		
	TR0 = 1;
}
//初始化
void allinit(){
	P2=0XA0;P0=0X00;
	P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;
	P2=0X80;P0=0XFF;
}
//延時
void delayms(int ms){
	int q,w;
	for(q=0;q<ms;q++)
		for(w=0;w<845;w++);
}
//數碼管
void display_12(yi,er){
	P2=0XC0;P0=0X01;P2=0XE0;P0=seg[yi];delayms(1);
	P2=0XC0;P0=0X02;P2=0XE0;P0=seg[er];delayms(1);
}
void display_34(san,si){
	P2=0XC0;P0=0X04;P2=0XE0;P0=seg[san];delayms(1);
	P2=0XC0;P0=0X08;P2=0XE0;P0=seg[si];delayms(1);
}
void display_56(wu,liu){
	P2=0XC0;P0=0X10;P2=0XE0;P0=seg[wu];delayms(1);
	P2=0XC0;P0=0X20;P2=0XE0;P0=seg[liu];delayms(1);
}
void display_78(qi,ba){
	P2=0XC0;P0=0X40;P2=0XE0;P0=seg[qi];delayms(1);
	P2=0XC0;P0=0X80;P2=0XE0;P0=seg[ba];delayms(1);
	P2=0XC0;P0=0XFF;P2=0XE0;P0=0XFF;delayms(1);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章