《蓝桥杯真题》:2017年单片机省赛(内附两种代码实现风格)
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《蓝桥杯真题》:2017年单片机省赛(内附两种代码实现风格)相关的知识,希望对你有一定的参考价值。
2017年单片机省赛
有关题目
实现代码
注意:①注意修改驱动代码时要留意一下onewire.c中单总线延时函数,是
STC89C52RC
,还是15系列
的,15系列的单片机速度比51快8~12倍,需要修改对应的延时函数
。②实现pwm控制电机实现不同的转动速度,通过调占空比
实现的。需要结合点击转动的频率。③剩余时间为零时,需要停止pwm信号的输出。
onewire.c中具体修改如下
//单总线延时函数
void Delay_OneWire(unsigned int t)
while(t--)
signed char i = 0;
for (i = 0; i < 12; i++);
实现风格①main.c
#include "STC15F2K60S2.h"
#include "onewire.h"
#define uchar unsigned char
#define uint unsigned int
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
uchar temp;//实时温度
uchar time;//倒计时时间
uchar mod = 1;//模式
code uchar tab[] = 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf, 0xc6;
//-, C 11 12
uchar pwm_val, pwm_cnt = 0;
bit flag_s7 = 0;//初始化0为显示剩余工作时间
void sys_init();//系统初始化
uchar rd_temp();
void key_handle();
void led();
//显示模块
void dsp_smg_bit(uchar pos, val);//位显示数码管
void display();
void dsp_time();
void dsp_temp();
void delay_k(uchar t);
void Delay1ms(); //@12.000MHz
void main()
sys_init();
while(1)
temp = rd_temp();//实时读取温度
key_handle();//按键处理
display();//界面显示
if (!time)
ET1 = 0;
P34 = 0;
else
ET1 = 1;
led();//led显示
void led()
if (time > 0)
if (mod == 1)
P2 = (P2 & 0x1f) | 0x80;
L1 = 0;
else if (mod == 2)
P2 = (P2 & 0x1f) | 0x80;
L2 = 0;
else if (mod == 3)
P2 = (P2 & 0x1f) | 0x80;
L3 = 0;
else
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
void display()
if (!flag_s7)
dsp_time();
else
dsp_temp();
void dsp_time()
dsp_smg_bit(1, 11);
dsp_smg_bit(2, mod);
dsp_smg_bit(3, 11);
dsp_smg_bit(4, 10);
dsp_smg_bit(5, 0);
dsp_smg_bit(6, time / 100);
dsp_smg_bit(7, time / 10 % 10);
dsp_smg_bit(8, time % 10);
void dsp_temp()
dsp_smg_bit(1, 11);
dsp_smg_bit(2, 4);
dsp_smg_bit(3, 11);
dsp_smg_bit(4, 10);
dsp_smg_bit(5, 10);
dsp_smg_bit(6, temp / 10);
dsp_smg_bit(7, temp % 10);
dsp_smg_bit(8, 12);
void key_handle()
if (!S4)
delay_k(20);
if (!S4)
while(!S4)
display();
mod++;
if (mod >= 4)
mod = 1;
//不同模式,对应转机速度不同
if (mod == 1)
pwm_val = 2;
else if (mod == 2)
pwm_val = 3;
else if (mod == 3)
pwm_val = 7;
if (!S5)
delay_k(20);
if (!S5)
while(!S5)
display();
time += 60;
if (time >= 180)
time = 0;
if (!S6)
delay_k(20);
if (!S6)
while(!S6)
display();
time = 0;
if (!S7)
delay_k(20);
if (!S7)
while(!S7)
display();
flag_s7 = !flag_s7;
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;
uchar rd_temp()
uchar t = 0, l, h;
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 Delay1ms() //@12.000MHz
unsigned char i, j;
i = 12;
j = 169;
do
while (--j);
while (--i);
void delay_k(uchar t)//大约延时t * 10 us,用于消抖
while(t--)
display();
//100us * 10
void timer1() interrupt 3
if (++pwm_cnt <= pwm_val)
P34 = 1;
else
P34 = 0;
if (pwm_cnt == 10)
pwm_cnt = 0;
void timer0() interrupt 1
static uint i1 = 0;
if (++i1 == 500)
i1 = 0;
if (time > 0)
--time;
void sys_init()
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 &= 0x1f;
AUXR &= 0x7F; //定时器时钟12T模式
TMOD = 0x00; //设置定时器模式
//2ms
TL0 = 0x30; //设置定时初值
TH0 = 0xF8; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//100us
TL1 = 0x9C; //设置定时初值
TH1 = 0xFF; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET0 = 1;
ET1 = 0;//由time 决定是否打开
EA = 1;
实现风格②main.c
#include "STC15F2K60S2.h"
#include "onewire.h"
#define uchar unsigned char
#define uint unsigned int
//PWM
unsigned char pwm_value = 2;
unsigned char pwm_count = 0;
uchar key_val = 20;
uchar wind = 1;
uchar time = 0;
uchar flag = 0;
uchar flag_temp = 0;
uchar temp = 0;
unsigned char dspcom = 0;//位选线
unsigned char dspbuf[8] = 11,10,11,10,10,10,10,10;//显示缓冲区
code unsigned char tab[] = 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0xc6;
//11 - 12 C
void sys_init(void);
void key_scanf(void);
void key_proc();
void display();
uchar read_temputerature();
void led_control();
void main()
sys_init();
while(1)
key_proc();
if (flag_temp)
flag_temp = 0;
temp = read_temputerature();
//实时显示
if (flag == 1)
dspbuf[1] = 4;
dspbuf[4] = 10;
dspbuf[5] = temp / 10;
dspbuf[6] = temp % 10;
dspbuf[7] = 12;
else
dspbuf[1] = wind;
dspbuf[4] = 0;
dspbuf[5] = time / 100;
dspbuf[6] = time / 10 % 10;
dspbuf[7] = time % 10;
led_control();
if (!time)
ET1 = 0;
P34 = 0;
else
ET1 = 1;
if (wind == 1) pwm_value = 2;
else if (wind == 2) pwm_value = 3;
else if (wind == 3) pwm_value = 7;
void led_control()
if (time != 0)
if (wind == 1)
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xfe;
P2 &= 0x1f;
else if (wind == 2)
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xfd;
P2 &= 0x1f;
else if (wind == 3)
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xfb;
P2 &= 0x1f;
else
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 &= 0x1f;
uchar read_temputerature()
uchar l, h, t = 0;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44);
//这边看情况延时
//while (!DQ); //Delay200us();
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xbe);
l = Read_DS18B20();
h = Read_DS18B20();
t |= h;
t <<= 4;
t |= (l >> 4);
return t;
void sys_init()
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 &= 0x1f;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 &= 0x1f;
//2ms
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x30; //设置定时初值
TH0 = 0xF8; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1;
//100us
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x9C; //设置定时初值
TH1 = 0xFF; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET0 = 1;
ET1 = 0;
EA = 1以上是关于《蓝桥杯真题》:2017年单片机省赛(内附两种代码实现风格)的主要内容,如果未能解决你的问题,请参考以下文章