程序
由于参加的是第二场比赛,第一场的试题就当做拿来练手,写的较为仓促应该有不少的bug,如果有哪里写的不好的地方、哪里写错得地方欢迎指出,积极改正!!
hex文件
main.c
#include "main.h"
#include "seg.h"
#include "onewire.h"
#include "ds1302.h"
#include "key.h"
#include "isr.h"
uchar key_num=0;
uchar temp_sz_wd=23,key12_flag=0,key13_flag=0,zd_flag=0,relay_flag=0;
uchar led_buff=0xff;
uchar temp_sec,temp_min,temp_hour;
uint temp_wd;
void main()
{
Sys_Init(); //系统初始化
set_time(); //DS1302初始化
Timer0Init();
Timer1Init();
read_time();
// temp_wd=rd_temperature();
while(1)
{
key_num=key_scan(); //按键扫描
// if(temp_wd!=0)
// {
switch(key12_flag)
{
case 0:display_wd();break;
case 1:display_sj();break;
case 2:display_sz();break;
default:break;
}
// }
if(key_num==12) //如果S12按下
{
key12_flag++;
key12_flag=key12_flag%3;
}
if(key_num==13) //如果S13按下
{
key13_flag++;
key13_flag=key13_flag%2;
}
if(key_num==16&&key12_flag==2)//如果S16按下且在参数设置界面
{
temp_sz_wd++;
if(temp_sz_wd>99)
temp_sz_wd=99;
}
if(key_num==17&&key12_flag==2)//如果S17按下且在参数设置界面或时间显示
{
temp_sz_wd--;
if(temp_sz_wd<10)
temp_sz_wd=10;
}
if(key13_flag==0) //如果S13标志位为0即温度控制模式
{
if((led_buff&0X02)==0X02) //LED2点亮
{
led_buff=led_buff&~0X02;
Y4; P0=led_buff; Y0;
}
if(temp_wd>temp_sz_wd*10) //如果实际温度大于温度阈值
relay_open(); //锁存器打开
else
relay_close(); //锁存器关闭
}
else if(key13_flag==1) //如果S13标志位为1即时间控制模式
{
if((led_buff&0X02)==0X00) //LED2熄灭
{
led_buff=led_buff|0X02;
Y4; P0=led_buff; Y0;
}
if(temp_min==0&temp_sec==0) //整点判断
{
zd_flag=2;
TR0 = 1; //定时器0开始5s计时
}
}
if(zd_flag==2)
{
if((led_buff&0X01)==0X01) //时间控制模式下整点时打开LED1
{
led_buff=led_buff&~0X01;
Y4; P0=led_buff; Y0;
}
relay_open(); //时间控制模式下整点时打开锁存器
}
}
}
void display_sz() //参数设置显示
{
seg_one(0,25);seg_one(1,3);
seg_one(6,temp_sz_wd/10);
seg_one(7,temp_sz_wd%10);
}
void display_sj() //时间显示
{
seg_one(0,25);seg_one(1,2);
seg_one(2,16);
seg_one(3,temp_hour/10);
seg_one(4,temp_hour%10);
seg_one(5,17);
seg_one(6,temp_min/10);
seg_one(7,temp_min%10);
}
void display_wd() //温度显示
{
seg_one(0,25);seg_one(1,1);
seg_one(5,temp_wd/100%10);
seg_one(6,temp_wd/10%10+32);
seg_one(7,temp_wd%10);
}
void Sys_delay(uint t) //1us延时
{
while(t--);
}
void Sys_Init() //初始化
{
Y4; P0=0XFF; Y0;
Y5; P0=0X00; Y0;
Y6; P0=0X00; Y0;
}
main.h
#ifndef _MAIN_H_
#define _MAIN_H_
#include "STC15F2K60S2.h"
#define uchar unsigned char //偷懒
#define uint unsigned int
#define Y0 P2=(P2&0x1f)|0x00; //偷懒
#define Y1 P2=(P2&0x1f)|0x20;
#define Y2 P2=(P2&0x1f)|0x40;
#define Y3 P2=(P2&0x1f)|0x60;
#define Y4 P2=(P2&0x1f)|0x80;
#define Y5 P2=(P2&0x1f)|0xA0;
#define Y6 P2=(P2&0x1f)|0xC0;
#define Y7 P2=(P2&0x1f)|0xE0;
void Sys_Init();
void Sys_delay(uint t);
void display_wd();
void display_sj();
void display_sz();
#endif
key.c
#include "key.h"
#include "ds1302.h"
#include "seg.h"
extern uchar key12_flag,zd_flag;
extern uchar temp_sec,temp_min,temp_hour;
extern uchar led_buff;
uchar key_scan()
{
uchar key_num=0;
P32=1;P33=1;P34=0;P35=0;
if(P32==0||P33==0)
{
Sys_delay(10);
if(P32==0||P33==0)
{
if(P32==0)
{
P32=0;P33=0;P34=1;P35=1;
if(P34==0||P35==0)
{
Sys_delay(10);
if(P34==0||P35==0)
{
if(P34==0)
{
key_num=17;
if(key12_flag==1)
{
while(P34==0)
{
read_time();
seg_one(0,25);seg_one(1,2);
seg_one(2,16);
seg_one(3,temp_min/10);
seg_one(4,temp_min%10);
seg_one(5,17);
seg_one(6,temp_sec/10);
seg_one(7,temp_sec%10);
if(temp_min==0&&temp_sec==0)
{
zd_flag=1;
}
if(zd_flag==1)
{
if((led_buff&0X01)==0X01)
{
led_buff=led_buff&~0x01;
Y4; P0=led_buff; Y0;
}
relay_open();
TR0 = 1; //定时器0开始计时
zd_flag=2;
}
if(zd_flag==2)
{
if((led_buff&0X01)==0X01)
{
led_buff=led_buff&~0X01;
}
Y4; P0=led_buff; Y0;
}
}
}
else
while(P34==0);
}
if(P35==0)
{
key_num=13;
while(P35==0);
}
}
}
}
else if(P33==0)
{
P32=0;P33=0;P34=1;P35=1;
if(P34==0||P35==0)
{
Sys_delay(10);
if(P34==0||P35==0)
{
if(P34==0)
{
key_num=16;
while(P34==0);
}
if(P35==0)
{
key_num=12;
while(P35==0);
}
}
}
}
}
else
key_num=0;
}
return key_num;
}
isr.c
#include "isr.h"
#include "seg.h"
#include "onewire.h"
#include "ds1302.h"
extern uchar temp_sec,temp_min,temp_hour;
extern uchar zd_flag,relay_flag;
extern uchar led_buff;
extern uint temp_wd;
void Timer0Init(void) //20毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xE0; //设置定时初值
TH0 = 0xB1; //设置定时初值
TF0 = 0; //清除TF0标志
// TR0 = 1; //定时器0开始计时
EA = 1 ;
ET0 = 1;
}
void Timer_service() interrupt 1
{
uchar cnt;
cnt++;
if(cnt==50*5) //定时5s
{
zd_flag=0;
cnt=0;
TR0=0;
if((led_buff&0X01)==0X00)
led_buff=led_buff|0X01;
Y4;P0=led_buff;Y0;
if((led_buff&0X04)==0X00)
led_buff=led_buff|0X04;
Y4;P0=led_buff;Y0;
relay_close();
P34=1;
}
}
void Timer1Init(void) //20毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xE0; //设置定时初值
TH1 = 0xB1; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
EA = 1 ;
ET1 = 1;
}
void Timer1_service() interrupt 3
{
uint relay_cnt,ds1302_cnt,ds18b20_cnt;
ds1302_cnt++;
ds18b20_cnt++;
if(ds1302_cnt==50) //1s读一次时间
{
// read_time();
// ds1302_cnt=0;
}
if(ds18b20_cnt==50) //0.5读一次温度
{
read_time();
temp_wd=rd_temperature();
ds18b20_cnt=0;
}
if(relay_flag==1)
{
relay_cnt++;
if(relay_cnt==2) //锁存器打开时LED3以100ms翻转
{
relay_cnt=0;
if((led_buff&0X04)==0X04)
{
led_buff=led_buff&~0X04;
Y4; P0=led_buff; Y0;
}
else if((led_buff&0X04)==0X00)
{
led_buff=led_buff|0X04;
Y4; P0=led_buff; Y0;
}
}
}
}
ds1302.c
#include "ds1302.h"
uchar read_1302_add[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar write_1302_add[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//uchar TIME[7]={0,25,23,23,4,6,22};
uchar TIME[7]={40,59,23,28,4,6,22};
extern uchar temp_sec,temp_min,temp_hour;
//写字节
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//向DS1302寄存器写入数据
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
//从DS1302寄存器读出数据
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
void set_time()
{
uchar i;;
Write_Ds1302_Byte(0x8E,0X00);
for(i=0;i<7;i++)
{
Write_Ds1302_Byte(write_1302_add[i],DEC_BCD(TIME[i]));
}
Write_Ds1302_Byte(0x8E,0X80);
}
void read_time()
{
temp_sec=BCD_DEC(Read_Ds1302_Byte(read_1302_add[0]));
temp_min=BCD_DEC(Read_Ds1302_Byte(read_1302_add[1]));
temp_hour=BCD_DEC(Read_Ds1302_Byte(read_1302_add[2]));
}
uchar BCD_DEC(uchar dat)
{
return((dat>>4)*10+(dat&0x0f));
}
uchar DEC_BCD(uchar dat)
{
return((dat/10<<4)|(dat%10));
}
seg.c
#include "seg.h"
extern uchar relay_flag;
extern uchar led_buff;
/************* 本地常量声明 **************/
uchar code t_display[]={ //标准字库
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
void seg_one(uchar wei,dat)
{
Y6; P0=0X01<<wei; Y0;
Y7; P0=~t_display[dat]; Sys_delay(300); P0=0XFF; Y0;
}
void relay_open()
{
Y5; P0=(P0&0xaf)|0x10; Y0;
relay_flag=1;
}
void relay_close()
{
Y5; P0=P0&0Xaf; Y0; //1010 0000
relay_flag=0;
if((led_buff&0X04)==0X00)
{
led_buff=led_buff|0X04;
Y4; P0=led_buff; Y0;
}
}
onewire.c
#include "onewire.h"
#include "seg.h"
extern uint temp_wd;
extern uchar key12_flag;
//单总线内部延时函数
void Delay_OneWire(unsigned int t)
{
t=t*12;
while(t--);
}
//单总线写操作
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//单总线读操作
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
uint rd_temperature(void)
{
uint temp_h,temp_l;
float temp;
init_ds18b20();
if(key12_flag==0)
{
display_wd();
}
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(200);
// display_wd();
do{
init_ds18b20();
if(key12_flag==0)
{
display_wd();
}
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
temp_l=Read_DS18B20();
temp_h=Read_DS18B20();
temp=temp_h<<8|temp_l;
temp=temp*0.0625*10;
}while(temp == 850); //小bug,为了跳过初始显示85
return temp;
}