基于15单片机简易温度采集——蓝桥杯
在一个寒假的准备中,15单片机各个模块应经有了一个充分的认识,对其内部原理以及程序控制已经熟练掌握,在距离省赛蓝桥杯不到10天的时间里,每天练习一套省赛模拟题,来提高各个模块的综合应用。
此次省赛试题中主要使用了DS1302和DS18B20两个模块,整套题难度算中上吧。本题难度在于温度采集时间设置和采集温度的逐一读取。我在程序设计中,使用了一个数组和两个索引的方法,将采集的温度逐一保存,然后再通过另一个索引将其读出。这个方法比较容易理解并且代码不易出错。在一个就是定时器的使用。本实验使用了一个定时器0,就很好的解决了一大堆延时问题。整个代码中没有使用while()函数来进行延时,因为使用过程中while()会慢慢地拖垮整个系统,导致系统定时不准。这个实验对定时的要求还是挺高的,所以一次也不使用while()延时!
行了,闲话不多说,一起来看看实验效果和代码吧!
设置温度采样时间间隔!
读取温度检测数值!
#include "STC15F2K60S2.h"
#include "onewire.h"
#include "ds1302.h"
#define u8 unsigned char
unsigned char code smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
unsigned char code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
#define KEY P3
#define NO_KEY 0xff //?????????
#define KEY_STATE0 0 //?ж????????
#define KEY_STATE1 1 //??????????
#define KEY_STATE2 2 //???
unsigned char Key_Scan()
{
static unsigned char key_state=KEY_STATE0;
u8 key_value=0,key_temp;
u8 key1,key2;
P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1;
if(P44==0) key1=0x70;
if(P42==0) key1=0xb0;
if(P35==0) key1=0xd0;
if(P34==0) key1=0xe0;
if((P34==1)&&(P35==1)&&(P42==1)&&(P44==1)) key1=0xf0;
P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0;
if(P30==0) key2=0x0e;
if(P31==0) key2=0x0d;
if(P32==0) key2=0x0b;
if(P33==0) key2=0x07;
if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1)) key2=0x0f;
key_temp=key1|key2;
switch(key_state)
{
case KEY_STATE0:
if(key_temp!=NO_KEY)
{
key_state=KEY_STATE1;
}
break;
case KEY_STATE1:
if(key_temp==NO_KEY)
{
key_state=KEY_STATE0;
}
else
{
switch(key_temp)
{
case 0x77: key_value=4;break;
case 0x7b: key_value=5;break;
case 0x7d: key_value=6;break;
case 0x7e: key_value=7;break;
case 0xb7: key_value=8;break;
case 0xbb: key_value=9;break;
case 0xbd: key_value=10;break;
case 0xbe: key_value=11;break;
case 0xd7: key_value=12;break;
case 0xdb: key_value=13;break;
case 0xdd: key_value=14;break;
case 0xde: key_value=15;break;
case 0xe7: key_value=16;break;
case 0xeb: key_value=17;break;
case 0xed: key_value=18;break;
case 0xee: key_value=19;break;
}
key_state=KEY_STATE2;
}
break;
case KEY_STATE2:
if(key_temp==NO_KEY)
{
key_state=KEY_STATE0;
}
break;
}
return key_value;
}
void Timer_Init(void) //1ms
{
AUXR |= 0x80; //1T timer
TMOD &= 0xF0; // 16bit
TL0 = 0xCD;
TH0 = 0xD4;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA=1;
}
bit key_flag;
bit blink_flag;
bit temp_caiji_flag;
bit real_temp_flag;
bit led_flag;
bit led_blink_flag;
u8 one_display[8];
u8 two_display[8];
u8 temp_caiji[10];
u8 three_display[8];
u8 mode;
u8 set_time=1;
u8 jiajia;
u8 shi,fen,miao;
u8 temp_time;
u8 temp_caiji_inedx;
u8 real_inedx;
void main(void)
{
u8 key_val=NO_KEY;
P2=0xa0;P0=0x00;P2=0x00; // close buzzer and relay
set_sfm(23,59,50);
Timer_Init(); //1ms
while(1)
{
one_display[0]=0x00;
one_display[1]=0x00;
one_display[2]=0x00;
one_display[3]=0x00;
one_display[4]=0x00;
one_display[5]=0x40;
one_display[6]=smg_du[set_time/10];
one_display[7]=smg_du[set_time%10];
shi=Read_Ds1302 (0x85);
fen=Read_Ds1302 (0x83);
miao=Read_Ds1302 (0x81);
two_display[0]=smg_du[shi/16];
two_display[1]=smg_du[shi%16];
two_display[3]=smg_du[fen/16];
two_display[4]=smg_du[fen%16];
two_display[6]=smg_du[miao/16];
two_display[7]=smg_du[miao%16];
three_display[0]=0x40;
three_display[1]=smg_du[real_inedx/10];
three_display[2]=smg_du[real_inedx%10];
three_display[3]=0x00;
three_display[4]=0x00;
three_display[5]=0x40;
three_display[6]=smg_du[temp_caiji[real_inedx]/10];
three_display[7]=smg_du[temp_caiji[real_inedx]%10];
if(real_temp_flag)
{
real_temp_flag=0;
if(temp_caiji_inedx<10)
{
temp_caiji[temp_caiji_inedx]=rd_temperature();
temp_caiji_inedx++;
}
else
{
temp_caiji_flag=0;
led_flag=1;
mode=2;
}
}
if(key_flag) //10ms
{
key_flag=0;
key_val=Key_Scan();
switch(key_val)
{
case 4:if(mode==0)
{
jiajia++;
if(jiajia==4)
{
jiajia=0;
}
if(jiajia==0)
{
set_time=1;
}
if(jiajia==1)
{
set_time=5;
}
if(jiajia==2)
{
set_time=30;
}
if(jiajia==3)
{
set_time=60;
}
}
break;
case 5:
if(mode==0)
{
mode=1;
temp_caiji_flag=1;
temp_time=set_time;
}
break;
case 6:
led_flag=0;
real_inedx++;
if(real_inedx==10)
{
real_inedx=0;
}
break;
case 7:
mode=0;
set_time=1;
real_inedx=0;
temp_caiji_inedx=0;
break;
}
}
}
}
void timer0() interrupt 1 using 1
{
static int key_count=0,smg_count=0,blink_smg_count=0,temp_count,led_count=0,i=0;
key_count++;smg_count++;
if(key_count==10) //10ms
{
key_count=0;
key_flag=1;
}
if(led_flag)
{
led_count++;
if(led_count==1000)
{
led_count=0;
led_blink_flag=~led_blink_flag;
if(led_blink_flag)
{
P2=0X80;P0=~0X01;P2=0X00;
}
else
{
P2=0X80;P0=0XFF;P2=0X00;
}
}
}
else
{
P2=0X80;P0=0XFF;P2=0X00;
}
if(mode==1)
{
blink_smg_count++;
if(blink_smg_count==1000)
{
blink_smg_count=0;
blink_flag=~blink_flag;
if(blink_flag)
{
two_display[2]=0x40;
two_display[5]=0x40;
}
else
{
two_display[2]=0x00;
two_display[5]=0x00;
}
}
}
if(smg_count==3) //3ms
{
smg_count=0;
P2=0xc0;P0=0;P2=0;
if(mode==0)
{
P2=0xe0;P0=~one_display[i];P2=0;
}
if(mode==1)
{
P2=0xe0;P0=~two_display[i];P2=0;
}
if(mode==2)
{
P2=0xe0;P0=~three_display[i];P2=0;
}
P2=0xc0;P0=smg_wei[i];P2=0;
i++;
if(i==8) i=0;
}
if(temp_caiji_flag==1)
{
temp_count++;
if(temp_count==temp_time*1000)
{
temp_count=0;
real_temp_flag=1;
}
}
}