目录
试题
各程序块代码
init.c
#include "other.h"
void init74hc138(unsigned char n){
P2=(P2&0x1f)|(n<<5);
P2&=0x1f;
}
void init(){
P0=0x00;
init74hc138(5);
P0=0xff;
init74hc138(4);
}
main.c
#include "other.h"
void Timer0_Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x20; //设置定时初始值
TH0 = 0xD1; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA=1;
}
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x20; //设置定时初始值
TH1 = 0xD1; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
EA=1;
}
void main(){
Timer0_Init();
Timer1_Init();
w_ds1302();
temper=getT();
while((int)temper==85)temper=getT();
//解决初始温度数值为85°C的问题
init();
while(1){
if(flag_seg){
flag_seg=0;
seg_ui(UI);//界面选择
Seg_Loop();
}//数码管动态显示
if(flag_key){
flag_key=0;
Key_Loop();
}//按键动态刷新
if(flag_temper){
flag_temper=0;
temper=getT();
}//获取温度值
if(flag_time){
flag_time=0;
r_ds1302();
}//获取时钟信息
mod(); //温度/时间模式选择
led(); //LED效果函数
}
}
//定时器0用于基础模块
void Timer0_Isr(void) interrupt 1
{
static unsigned char count1=0,count2=0;
static unsigned int count3=0,count4=500;
count1++;count2++;count3++;count4++;
if(count1==2){
count1=0;
flag_seg=1;
}
if(count2==50){
count2=0;
flag_key=1;
}
if(count3==500){
count3=0;
flag_temper=1;
}
if(count4==1000){
count4=500;
flag_time=1;
}
}
//定时器1用于LED效果和继电器吸合控制
void Timer1_Isr(void) interrupt 3
{
static unsigned int count_relay=0,count_led1=0;
static unsigned char count_led3=0;
if(mod_relay_1){
count_relay++;
if(count_relay==5000){
count_relay=0;
no_relay();
mod_relay_1=0;
}
}//时间控制模式下,继电器吸合5s
if(led_time){
count_led1++;
if(count_led1==5000){
count_led1=0;
P0=0xff;
init74hc138(4);
}
}//整点LED1闪烁5s
if(led_relay){
if(count_led3==0){
P0=0xff;
init74hc138(4);
}else if(count_led3==100){
P0=0xfb;
init74hc138(4);
P0=0xff;
}else if(count_led3==200){
count_led3=0;
}
count_led3++;
}else{
count_led3=0;
}//继电器吸合时,LED3闪烁
}
other.h
#ifndef __OTHER_H__
#define __OTHER_H__
#include <STC15F2K60S2.H>
#include "intrins.h"
//onewire.c中的I/O口定义
sbit DQ=P1^4;
//ds1302.c中的I/O口定义
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^3;
//相关自定义变量
extern unsigned char keyval,keyold,keyup,keydown;//按键
extern unsigned char Seg_Buff[];//数码管缓存
extern unsigned char time[];//时钟数据
extern unsigned char UI;//界面控制字
extern float temper;//温度数据
extern unsigned char temper_max;//设定的温度参数
extern bit time_h_m_s;//时-分/分-秒标志位
extern bit mod_relay_1;//时间控制模式下的继电器吸合标志位
extern bit mod_relay_0;//温度控制模式下的继电器吸合标志位
extern bit led_time;//整点标志位
extern bit led_relay;//继电器吸合时,LED闪烁标志位
extern bit flag_mod;//控制模式转换标志位
extern bit flag_seg;//数码管扫描标志
extern bit flag_key;//按键扫描标志
extern bit flag_time;//时钟值获取标志
extern bit flag_temper;//温度值获取标志
//init.c
void init74hc138(unsigned char n);
void init();
//other.c
void relay();
void no_relay();
void mod();
void led();
//onewire.c
float getT();
//key.c
void Key_Loop();
//ds1302.c
void w_ds1302();
void r_ds1302();
//seg.c
void seg(unsigned char addr,num);
void Seg_Loop();
void seg_ui(unsigned char ui);
#endif
other.c
#include "other.h"
unsigned char keyval,keyold,keyup,keydown;
unsigned char temper_max=23;
unsigned char UI=1;
float temper=0;
bit flag_mod=0;
bit time_h_m_s=0;
bit mod_relay_1=0;
bit mod_relay_0=0;
bit led_time=0;
bit led_relay=0;
bit flag_seg=0;
bit flag_key=0;
bit flag_time=0;
bit flag_temper=0;
void relay(){
P0=0x10;
init74hc138(5);
P0=0xff;
}//继电器吸合
void no_relay(){
P0=0x00;
init74hc138(5);
P0=0xff;
}//继电器松开
//控制模式转换
void mod(){
//时间控制模式
if(flag_mod){
no_relay();
mod_relay_0=0;
P0=0xff;
init74hc138(4);
if(time[0]==0&&time[1]==0){
relay();//继电器吸合
mod_relay_1=1;
//由于需要持续5s
//故继电器关闭写在主函数里
}
}
//温度控制模式
else{
P0=0xfd;
init74hc138(4);
P0=0xff;
if((int)(temper*10)>(temper_max*10)){
relay();//继电器吸合
mod_relay_0=1;
}else{
no_relay();//关闭继电器
mod_relay_0=0;
}
}
}
//LED效果
void led(){
if(time[0]==0&&time[1]==0){
P0=0xfe;
init74hc138(4);
P0=0xff;
led_time=1;
}
if(mod_relay_0||mod_relay_1){
if(!led_relay){
P0=0xfb;
init74hc138(4);
P0=0xff;
led_relay=1;
}
}else{
P0=0xff;
init74hc138(4);
led_relay=0;
}
}
key.c
#include "other.h"
unsigned char Key_Scan(){
unsigned char temp=0;
P35=0;P34=1;
if(P32==0){temp=13;return temp;}
if(P33==0){temp=12;return temp;}
P34=0;P35=1;
if(P32==0){temp=17;return temp;}
if(P33==0){temp=16;return temp;}
return 0;
}
void Key_Loop(){
keyval=Key_Scan();
keydown=keyval&(keyold^keyval);
keyup=~keyval&(keyold^keyval);
if(keyval==12&&keyold!=12){UI++;if(UI==4)UI=1;}
if(keyval==13&&keyold!=13){flag_mod=!flag_mod;}
if(keyval==16&&keyold!=16&&UI==3){if(temper_max<99)temper_max++;}
if(keyval==17&&keyold!=17&&UI==3){if(temper_max>10)temper_max--;}
if(keyval==17&&UI==2){time_h_m_s=1;}else{time_h_m_s=0;}
keyold=keyval;
}
seg.c
#include "other.h"
code unsigned char Seg_Table[] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xbf, //- 10
0xc1, //U 11
0xff //熄灭 12
};
unsigned char Seg_Buff[]={11,12,12,12,12,12,12,12};
void seg(unsigned char addr,num){
P0=0xff;
init74hc138(7);
P0=0x01<<addr;
init74hc138(6);
P0=Seg_Table[num];
if(UI==1&&addr==6){
P0&=0x7f;
}
init74hc138(7);
}
void Seg_Loop(){
static unsigned char i=0;
seg(i,Seg_Buff[i]);
i++;
if(i==8)i=0;
}
void seg_u1(){
Seg_Buff[7]=(int)((temper+0.05)*10)%10;
Seg_Buff[6]=(int)((temper+0.05)*10)/10%10;
if((int)temper>=10)
Seg_Buff[5]=(int)((temper+0.05)*10)/100%10;
else
Seg_Buff[5]=12;
Seg_Buff[4]=12;
Seg_Buff[3]=12;
Seg_Buff[2]=12;
Seg_Buff[1]=1;
}
void seg_u2(){
if(time_h_m_s){//分_秒
Seg_Buff[7]=time[0]%10;
Seg_Buff[6]=time[0]/10;
Seg_Buff[4]=time[1]%10;
Seg_Buff[3]=time[1]/10;
}else{//时_分
Seg_Buff[7]=time[1]%10;
Seg_Buff[6]=time[1]/10;
Seg_Buff[4]=time[2]%10;
Seg_Buff[3]=time[2]/10;
}
Seg_Buff[5]=10;
Seg_Buff[2]=12;
Seg_Buff[1]=2;
}
void seg_u3(){
Seg_Buff[7]=temper_max%10;
Seg_Buff[6]=temper_max/10;
Seg_Buff[5]=12;
Seg_Buff[4]=12;
Seg_Buff[3]=12;
Seg_Buff[2]=12;
Seg_Buff[1]=3;
}
//界面选择
void seg_ui(unsigned char ui){
switch(ui){
case 1:seg_u1();break;
case 2:seg_u2();break;
case 3:seg_u3();break;
}
}
onewire.c部分
#include "other.h"
float getT(){
unsigned int tH,tL;
float temp;
EA=0;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
tL=Read_DS18B20();
tH=Read_DS18B20();
temp=(float)(tH<<8|tL)*0.0625;
EA=1;
return temp;
}
ds1302.c部分
#include "other.h"
unsigned char time[]={0,25,23};
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
//......................
Write_Ds1302(dat/10*16|dat%10); //十进制数——>BCD码
RST=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
unsigned char dat1,dat2;
//......................
dat1=temp/16*10;
dat2=temp%16;
temp=dat1+dat2; //BCD码——>十进制数
return (temp);
}
void w_ds1302(){
unsigned char i,addr=0x80;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<3;i++){
Write_Ds1302_Byte(addr,time[i]);
addr+=2;
}
Write_Ds1302_Byte(0x8e,0x80);
}
void r_ds1302(){
unsigned char i,addr=0x81;
for(i=0;i<3;i++){
time[i]=Read_Ds1302_Byte(addr);
addr+=2;
}
}