《蓝桥杯真题》:2020年单片机省赛第二场

Posted 是七喜呀!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《蓝桥杯真题》:2020年单片机省赛第二场相关的知识,希望对你有一定的参考价值。

2020年单片机省赛第二场

有关题目





实现代码

注意:
限制条件方面:①切换温度上下限,仅在参数设置界面有效
②进入数据界面和参数界面分别需进行参数判断与初始化控制温度下限Tmin的设置
③DAC输出时,注意写入的数字IIC_SendByte(temp)中temp范围在0~255;
源文件修改方面:官方给的onewire.h,iic.h中使用的时C51的头文件"reg52.h",我们需要修改为对应的15系列头件"STC15F2K60S2.h",这样才可以使用其中的一些特殊位寄存器
底层代码:①DAC输出函数dac_pcf8591()在实现中需设置DA模式
②需修改驱动代码onewire.c中单总线延时函数,官方给我们是STC89C52RC系列,15系列的单片机速度比51快8~12倍,需要修改对应的延时函数。修改如下
void Delay_OneWire(unsigned int t)

char i;
while(t–)
for (i = 0; i < 12; i++);

main.c

#include "STC15F2K60S2.h"
#include "onewire.h"
#include "iic.h"

#define uchar unsigned char
#define uint unsigned int

sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;

uchar jm = 0;//界面初始化数据界面
code uchar tab[] = 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff, 0xc6, 0x8c; 
//c p 11 12

bit Tmax_Tmin_flag = 0;//默认0为温度下限参数 Tmin

uchar T;
char Tmax = 30, Tmin = 20;//注意参数设定范围,为了方便判断,所以我们这边正常使用有符号类型char
uchar Last_Tmax = 30, Last_Tmin = 20;

void sys_init();
void dac_pcf8591();
void key_handle();
uchar rd_temperature();

void dsp_smg_bit(uchar pos, val);
void display();//显示功能,分两个大块
void dsp_dat();
void dsp_para();
void delay_k(uchar t);//延时t * 10us
void Delay1ms();		//1ms@12.000MHz,延时1ms用于给足数码管足够显示时间

void main()

	sys_init();
	while(1)
	
		T = rd_temperature();
		key_handle();
		display();
		dac_pcf8591();
	


void key_handle()

	if(!S4)//切换模式
	
		delay_k(20);
		if (!S4)
		
			while(!S4)
				display();
			
			if (++jm >= 2)
				jm = 0;
			
			if (0 == jm)//进行参数检查
			
				if (Tmax >= Tmin)
				
					Last_Tmax = Tmax;
					Last_Tmin = Tmin;
				
				else 
				
					Tmax = Last_Tmax;
					Tmin = Last_Tmin;
				
			
			else if (1 == jm)//即将进入参数界面,默认选择当前温度参数为Tmin
				Tmax_Tmin_flag = 0;
		
	
	
	if(!S5)//切换温度上下限
	
		delay_k(20);
		if (!S5)
		
			while(!S5)
				display();
			if (1 == jm)
				Tmax_Tmin_flag = !Tmax_Tmin_flag;
		
	
	
	if(!S6)//+1
	
		delay_k(20);
		if (!S6)
		
			while(!S6)
				display();
				
			if (1 == jm)	
			
				if (!Tmax_Tmin_flag)
				
					Tmin++;
					if (Tmin > 99)
						Tmin = 99;
				
				else 
				
					Tmax++;
					if (Tmax > 99)
						Tmax = 99;
				
			
		
	
	
	if(!S7)//-1
	
		delay_k(20);
		if (!S7)
		
			while(!S7)
				display();
				
			if (1 == jm)	
			
				if (!Tmax_Tmin_flag)
				
					Tmin--;
					if (Tmin < 0)
						Tmin = 0;
				
				else 
				
					Tmax--;
					if (Tmax < 0)
						Tmax = 0;
				
			
		
	



void display()

	if (0 == jm)
		dsp_dat();
	else if (1 == jm)
		dsp_para();




void dsp_para()

	dsp_smg_bit(1, 12);//p
	
	dsp_smg_bit(4, Tmax / 10 % 10);
	dsp_smg_bit(5, Tmax % 10);
	
	dsp_smg_bit(7, Tmin / 10 % 10);
	dsp_smg_bit(8, Tmin % 10);


void dsp_dat()

	dsp_smg_bit(1, 11);//c
	dsp_smg_bit(7, T / 10 % 10);
	dsp_smg_bit(8, T % 10);


void dsp_smg_bit(uchar pos, val)

	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 1 << (pos - 1);
	
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = tab[val];
	
	Delay1ms();
	P0 = 0xff;
	P2 &= 0x1f;


void delay_k(uchar t)

	while(t--)
		display();

void Delay1ms()		//@12.000MHz

	unsigned char i, j;

	i = 12;
	j = 169;
	do
	
		while (--j);
	 while (--i);


void dac_pcf8591()

		uint temp = 0;
		if (Tmax >= Tmin)
		
			if (T > Tmax)
			
				P2 = (P2 & 0x1f) | 0x80;
				L1 = 0;
				temp = 51 * 4;
			
			else if (T >= Tmin && T <= Tmax)
			
				P2 = (P2 & 0x1f) | 0x80;
				L2 = 0;
				temp = 51 * 3;
			
			else 
			
				P2 = (P2 & 0x1f) | 0x80;
				L3 = 0;
				temp = 51 * 2;
			
		
		else //参数设置错误
		
			P2 = (P2 & 0x1f) | 0x80;
			L4 = 0;
		
		IIC_Start();
		IIC_SendByte(0x90);
		IIC_WaitAck();

		IIC_SendByte(0x40);//DA模式
		IIC_WaitAck();

		IIC_SendByte(temp);
		IIC_WaitAck();
		IIC_Stop();


uchar rd_temperature()

	uchar l, h, t;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	l = Read_DS18B20();
	h = Read_DS18B20();
	
	t = (h << 4);
	t |= (l >> 4);
	
	return t;


void sys_init()

	//关蜂鸣器,继电器
	P2 = (P2 & 0x1f) | 0xa0;
	P0 = 0xaf;
	
	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
	P2 &= 0x1f;

iic.h

#ifndef _IIC_H
#define _IIC_H

#include "STC15F2K60S2.h"
#include "intrins.h"

sbit SDA = P2^1;
sbit SCL = P2^0;

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
//void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
//unsigned char IIC_RecByte(void); 

#endif

iic.c

#include "iic.h"

#define DELAY_TIME 5

//I2C总线内部延时函数
void IIC_Delay(unsigned char i)

    do_nop_();
    while(i--);        


//I2C总线启动信号
void IIC_Start(void)

    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	


//I2C总线停止信号
void IIC_Stop(void)

    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);


//发送应答或非应答信号
//void IIC_SendAck(bit ackbit)
//
//    SCL = 0;
//    SDA = ackbit;  					
//    IIC_Delay(DELAY_TIME);
//    SCL = 1;
//    IIC_Delay(DELAY_TIME);
//    SCL = 0; 
//    SDA = 1;
//    IIC_Delay(DELAY_TIME);
//

//等待应答
bit IIC_WaitAck(void)

    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;


//I2C总线发送一个字节数据
void IIC_SendByte(unsigned char byt)

    unsigned char i;

    for(i=0; i<8; i++)
    
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    
    SCL  = 0;  


//I2C总线接收一个字节数据
//unsigned char IIC_RecByte(void)
//
//    unsigned char i, da;
//    for(i=0; i<8; i++)
//       
//    	SCL = 1;
//	IIC_Delay(DELAY_TIME);
//	da <<= 1;
//	if(SDA) da |= 1;
//	SCL = 0;
//	IIC_Delay(DELAY_TIME);
//    
//    return da;    
//

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

#include "STC15F2K60S2.h"

sbit DQ = P1^4;  

//unsigned char rd_temperature(void);  
void Delay_OneWire(unsigned int t);
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);

#endif

onewire.c

#include "onewire.h"

//单总线内部延时函数
void Delay_OneWire(unsigned int t)  
	
	char i;
	while(t--)
		for (i = 0; i < 12; i++);


//单总线写操作
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;


以上是关于《蓝桥杯真题》:2020年单片机省赛第二场的主要内容,如果未能解决你的问题,请参考以下文章

《蓝桥杯真题》:2020年单片机省赛第二场(第十一届第二场)

《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)

《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)

《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)

2020第十一届蓝桥杯真题JAVA B组省赛第二场答案分享(2020.10.17)

《蓝桥杯真题》:2021单片机省赛第二场(第十二届第二场)暨第十三届蓝桥杯赛前模拟试题