《蓝桥杯真题》:2022年单片机省赛(第十三 / 13届第一场)
Posted Mascotttttt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《蓝桥杯真题》:2022年单片机省赛(第十三 / 13届第一场)相关的知识,希望对你有一定的参考价值。
2022年单片机省赛
有关题目
实现代码
注意:
数据处理方面
:由于ds1302芯片存储的数据是BCD码,所以我们要进行BCD码与十进制之间的转换,例如0x16 的BCD码为16,十进制为1 * 16 + 6 = 32。
源文件修改方面
:官方给onewire.h,ds1302.h中使用的时C51的头件"reg52.h",我们需修改为对应的15系列头文件"STC15F2K60S2.h",这样才可以使用一些特殊位寄存器。
底层代码
:需修改驱动代码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 "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
uchar jm = 0;//界面初始化温度界面
code uchar tab[] = 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff, 0xc1, 0xbf;
//U - 11 12
uchar init_time[3] = 0x40, 0x59, 0x23;//初始化时间秒 分 时
uchar time[3] = 0 ;//秒 分 时
bit mod_flag;//0为温度控制模式
bit rel_flag;//继电器是否闭合标志,为0未闭合
bit flag_5s;
bit led10_flag;//初始化0为led10熄灭
bit L1_flag;//初始化0为L1熄灭
bit L3_flag;//初始化0为L3熄灭
float curr_temp;
uchar para_temp = 23;
void sys_init();
void key_handle();
float rd_temperature();
void rd_time();
void rel_handle();
void led();
void dsp_smg_bit(uchar pos, val);
void display();//显示功能,分四个大块
void dsp_temp();
void dsp_time();
void dsp_para();
void dsp_min_sec();//长按S17显示分秒
void delay_k(uchar t);//延时t * 10us
void Delay1ms(); //1ms@12.000MHz,延时1ms用于给足数码管足够显示时间
void main()
sys_init();
while(1)
curr_temp = rd_temperature();
rd_time();//实时读取时间
key_handle();
display();
rel_handle();//继电器处理
led();
void led()
if (time[0] == 0x00 && time[1] == 0x00)
L1_flag = 1;
if (L1_flag)
P2 = (P2 & 0x1f) | 0x80;
L1 = 0;
else
P2 = (P2 & 0x1f) | 0x80;
L1 = 1;
if (!mod_flag)
P2 = (P2 & 0x1f) | 0x80;
L2 = 0;
else
P2 = (P2 & 0x1f) | 0x80;
L2 = 1;
if (led10_flag)
//继电器吸附,间隔0.1sL3闪烁
if (L3_flag)
P2 = (P2 & 0x1f) | 0x80;
L3 = 0;
else
L3 = 1;
P0 |= 0xf8;//将L4~L8熄灭
P2 &= 0x1f;
void rel_handle()
uint t = (uchar)(curr_temp * 10);
if (!mod_flag)
if (t > para_temp * 10)
led10_flag = 1;
P2 = (P2 & 0x1f) | 0xa0;
P0=0X10;
else
led10_flag = 0;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
else if (mod_flag)
if (time[0] == 0x00 && time[1] == 0x00)
rel_flag = 1;//整点,继电器吸附标志
if (rel_flag)
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0x10;
led10_flag = 1;
else
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
led10_flag = 0;
//P0 |= 0x00;
//P2 &= 0x1f;
void rd_time()
uchar t;
t = Read_Ds1302_Byte(0x81);//秒
time[0] = t / 16 * 10 + t % 16 ;
t = Read_Ds1302_Byte(0x83);//分
time[1] = t / 16 * 10 + t % 16 ;
t = Read_Ds1302_Byte(0x85);//时
time[2] = t / 16 * 10 + t % 16 ;
void display()
if (0 == jm)
dsp_temp();
else if (1 == jm)
dsp_time();
else if (2 == jm)
dsp_para();
void dsp_min_sec()
dsp_smg_bit(1, 11);//U
dsp_smg_bit(2, 2);//
dsp_smg_bit(4, time[1] / 10);
dsp_smg_bit(5, time[1] % 10);
dsp_smg_bit(6, 12);//-
dsp_smg_bit(7, time[0] / 10);
dsp_smg_bit(8, time[0] % 10);
void dsp_para()
dsp_smg_bit(1, 11);//U
dsp_smg_bit(2, 3);//
dsp_smg_bit(7, para_temp / 10 % 10);
dsp_smg_bit(8, para_temp % 10);
void dsp_time()
dsp_smg_bit(1, 11);//U
dsp_smg_bit(2, 2);//
dsp_smg_bit(4, time[2] / 10);
dsp_smg_bit(5, time[2] % 10);
dsp_smg_bit(6, 12);//-
dsp_smg_bit(7, time[1] / 10);
dsp_smg_bit(8, time[1] % 10);
void dsp_temp()
uint x = (uint)(curr_temp * 10);//当前温度扩大10倍
dsp_smg_bit(1, 11);//U
dsp_smg_bit(2, 1);//
dsp_smg_bit(6, x / 100 % 10);
//第7位数码管显示小数点
P2 = (P2 & 0x1f) | 0xc0;
P0 = 1 << (7 - 1);
P2 = (P2 & 0x1f) | 0xe0;
P0 = tab[x / 10 % 10] & 0x7f;
Delay1ms();
P0 = 0xff;
P2 &= 0x1f;
dsp_smg_bit(8, x % 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 Delay1ms() //@12.000MHz
unsigned char i, j;
i = 12;
j = 169;
do
while (--j);
while (--i);
void delay_k(uchar t)
while(t--)
display();
void key_handle()
P35 = P34 = P32 = 1;
P33 = 0;//第四行拉低
if(!P35)//s12
delay_k(10);
if(!P35)
if (++jm >= 3)
jm = 0;
while(!P35)
display();
if(!P34)//s16
delay_k(10);
if(!P34)
if (2 == jm)
if (++para_temp > 99)
para_temp = 99;
while(!P34)
display();
P35 = P34 = P33 = 1;
P32 = 0;//第三行拉低
if(!P35)//s13
delay_k(10);
if(!P35)
mod_flag = !mod_flag;
while(!P35)
display();
if(!P34)//s17
delay_k(10);
if(!P34)
if (2 == jm)
if (--para_temp < 10)//参数操作 + 参数检查
para_temp = 10;
if (1 == jm)
while(!P34)//s17的长按键操作
rd_time();
dsp_min_sec();
while(!P34)
display();
float rd_temperature()
uchar l, h;
uint t;
float temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
l = Read_DS18B20();
h = Read_DS18B20();
t = (h & 0x0f);
t <<= 8;
t |= l;
temp = t * 0.0625;
return temp;
void timer0() interrupt 1
static uint i1, i2, i3;
if (rel_flag)//继电器闭合5秒断开标志
if (++i1 == 5000)
i1 = 0;
rel_flag = 0;
if (L1_flag)
if (++i2 == 5000)
i2 = 0;
L1_flag = 0;
if (++i3 == 100)//0.1s切换一次L3的状态,使其闪烁
L3_flag = !L3_flag;
i3 = 0;
void sys_init()
//关蜂鸣器,继电器
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 &= 0x1f;
Write_Ds1302_Byte(0x8e,0x00);//关闭写保护
Write_Ds1302_Byte(0x80, init_time[0]);//秒
Write_Ds1302_Byte(0x82, init_time[1]);//分
Write_Ds1302_Byte(0x84, init_time[2]);//时
Write_Ds1302_Byte(0x8e,0x80);//开启写保护
//1ms
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
ET1 = 0;//禁止定时器中断1中断
EA = 1;
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include <STC15F2K60S2.H>
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
void Delay_OneWire(unsigned int t);
#endif
onewire.c
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include "onewire.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
char i;
while(t《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)
《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)
《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)
《蓝桥杯真题》:2022单片机省赛第二场_客观题(第十三 / 13届第二场)