藍橋杯單片機學習過程記錄(三十一)第九屆國賽多功能測量儀表
第九屆國賽,比較基礎。有幾點需要注意:一是溫度獲取需要小數,定義變量時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);
}