《蓝桥杯真题》:2017年单片机省赛(第八届)(内附两种代码实现风格)

Posted Mascotttttt

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年单片机省赛(第八届)(内附两种代码实现风格)的主要内容,如果未能解决你的问题,请参考以下文章

第八届省赛程序设计题--电子钟程序设计蓝桥杯真题—03

蓝桥杯赛前冲刺-枚举暴力和排序专题2(包含历年蓝桥杯真题和AC代码)

《蓝桥杯真题》:2017年单片机省赛(内附两种代码实现风格)

STM32G4备战蓝桥杯嵌入式---实战---第八届嵌入式省赛

2017第八届蓝桥杯C/C++ B组省赛个人代码

蓝桥日记①2017第八届省赛(软件类)JavaA组❤️答案解析