第十三届蓝桥杯单片机省赛程序设计试题

发布于:2025-03-27 ⋅ 阅读:(25) ⋅ 点赞:(0)

目录

试题

各程序块代码

init.c

main.c

other.h

other.c

key.c

seg.c

onewire.c部分

ds1302.c部分


试题

 

各程序块代码

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;
	}
}