《蓝桥杯真题》: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届第二场)