蓝桥杯单片机STC15F2K60S2第七届省赛代码讲解(附完整代码)

        第七届的省赛相比于其他几届也比较常规了,只不过第七届考了PWM的使用,PWM其实也就是控制高低电平而已,我在这里就直接放出试题和我自己写的代码了,如果想更深入的学习各模块怎么写,欢迎去阅读我写的另外一篇更加详细的文章。

蓝桥杯单片机STC15F2K60S2第十三届省赛代码详细讲解(附完整代码)

以下是第七届省赛的试题

 

以下是完整的代码

main.c 

#include <STC15F2K60S2.H>
#include "display.h"
#include "onewire.h"

sbit PWM=P3^4;

void Show_Switch(void);
void Key_Board(void);
void Timer0_Init(void);		//@12.000MHz
void Timer1_Init(void);		//20毫秒@12.000MHz
void LED(void);


unsigned char Switching=0;
unsigned int PWM_Duty=200;
unsigned char Time=0;
unsigned char TimeFlag=0;
unsigned char S6Flag=1;
unsigned char temp=0;
unsigned char SwitchFlag;
unsigned char LEDFlag=1;

void main(void)
{
	System_Init();
	Timer0_Init();
	Timer1_Init();
	
	while(1)
	{
		Show_Switch();
		Key_Board();
		LED();
	}
}

void Key_Board(void)
{
	unsigned char Key;
	P44=0;P3 |=0x0f;
	Key =P3;Key &=0x0f;
	if(Key !=0x0f)
	{
		Delayms(5);
		if(Key !=0x0f)
		{
			switch(Key)
			{
				case 0x07:if(Switching==0){
					Switching=1;
					PWM_Duty=300;
					break;
				}
				if(Switching==1){
					Switching=2;
					PWM_Duty=700;
					break;
				}
				if(Switching==2){
					Switching=0;
					PWM_Duty=200;
					break;
				}	
				
				case 0x0b:S6Flag=1;LEDFlag=1;
				if(TimeFlag==0){
					Time=60;
					TimeFlag=Time;
					TR0=1;
					TR1=1;
					break;
				}
				if(TimeFlag==60){
					Time=120;
					TimeFlag=Time;
					TR0=1;
					TR1=1;
					break;
				}
				if(TimeFlag==120){
					Time=0;
					TimeFlag=Time;
					TR0=0;
					TR1=0;
					break;
				}
				
				case 0x0d:if(S6Flag){
					S6Flag=0;
					LEDFlag=0;
					Time=0;
					TR0=0;
				}break;
				
				case 0x0e:
				if(Switching != 3){
					SwitchFlag=Switching;
					Switching=3;
					break;
				}
				else if(Switching==3){
					Switching=SwitchFlag;	
					break;
				}				
			}
		}
		while(Key!=0x0f)
		{
			Key =P3;Key &=0x0f;
			Show_Switch();
		}
	}
}

void Show_Switch(void)
{	
	if(Switching==0)
	{
		Display_Number(1,10);Display_Number(2,1);Display_Number(3,10);	
		Display_Number(5,0);Display_Number(6,Time/100);Display_Number(7,Time/10%10);Display_Number(8,Time%10);
	}
	if(Switching==1)
	{
		Display_Number(1,10);Display_Number(2,2);Display_Number(3,10);	
		Display_Number(5,0);Display_Number(6,Time/100);Display_Number(7,Time/10%10);Display_Number(8,Time%10);
	}
	if(Switching==2)
	{
		Display_Number(1,10);Display_Number(2,3);Display_Number(3,10);
		Display_Number(5,0);Display_Number(6,Time/100);Display_Number(7,Time/10%10);Display_Number(8,Time%10);		
	}
	if(Switching==3)
	{
		temp=Read_Temp();
		Display_Number(1,10);Display_Number(2,4);Display_Number(3,10);
		Display_Number(6,temp/10);Display_Number(7,temp%10);Display_Number(8,11);
	}
}

void Timer0_Isr(void) interrupt 1
{
	static unsigned int Count;
	TH0 = (65535-1000)/256;				//设置定时初始值
	TL0 = (65535-1000)%256;				//设置定时初始值
	Count++;
	Count %=1000;
	if(Count>=PWM_Duty)
	{
		PWM=0;
	}
	else 
	{
		PWM=1;
	}
}

void Timer0_Init(void)		//@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = (65535-1000)%256;				//设置定时初始值
	TH0 = (65535-1000)/256;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
//	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA=1;
}

void Timer1_Isr(void) interrupt 3
{
	static unsigned char count=0;
	count++;
	if(count==20)
	{
		count=0;
		if(Time !=0)
		{
			Time--;
		}		
		if(Time==0){
			TR1=0;
			TR0=0;
			LEDFlag=0;
		}
	}
}

void Timer1_Init(void)		//50毫秒@12.000MHz
{
	AUXR &= 0xBF;			//定时器时钟12T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0xB0;				//设置定时初始值
	TH1 = 0x3C;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
//	TR1 = 1;				//定时器1开始计时
	ET1 = 1;				//使能定时器1中断
}

void LED(void)
{
	if(LEDFlag)
	{
		if(Switching==0)Display_LED(1,ON);
		else Display_LED(1,OFF);
		
		if(Switching==1)Display_LED(2,ON);
		else Display_LED(2,OFF);
		
		if(Switching==2)Display_LED(3,ON);
		else Display_LED(3,OFF);
	}
	else {
		Display_LED(1,OFF);
		Display_LED(2,OFF);
		Display_LED(3,OFF);
	}
}


display.c

#include <STC15F2K60S2.H>

code unsigned char Number[]={
	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
	0xbf,		//- 10
	0xc6		//C 11
};

void Delayms(int ms)	
{
	unsigned char data i, j;

	int k=0;
	
	for(k=0;k<ms;k++)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
	
}

void Select_HC573(unsigned char Number)
{
	switch(Number)
	{
		case 4:P2=(P2&0x1f)|0x80;break;
		case 5:P2=(P2&0x1f)|0xA0;break;
		case 6:P2=(P2&0x1f)|0xC0;break;
		case 7:P2=(P2&0x1f)|0xE0;break;
	}
	P2=(P2&0x1f)|0x00;
}

void System_Init(void)
{
	P0=0x00;
	Select_HC573(5);
	Select_HC573(6);
	P0=0xff;
	Select_HC573(4);
}

void Display_Number(unsigned char Pos,unsigned char Data)
{
	P0=0x01<<Pos-1;
	Select_HC573(6);
	P0=Number[Data];
	Select_HC573(7);
	Delayms(1);
	
	P0=0x01<<Pos-1;
	Select_HC573(6);
	P0=0xff;
	Select_HC573(7);
}

void Display_LED(unsigned char Number,unsigned char State)
{
	static unsigned char temp=0xff;
	if(State)
	{
		switch(Number)
		{
			case 1:temp &=0xfe;break;
			case 2:temp &=0xfd;break;
			case 3:temp &=0xfb;break;
		}
	}
	else 
	{
		switch(Number)
		{
			case 1:temp |=0x01;break;
			case 2:temp |=0x02;break;
			case 3:temp |=0x04;break;
		}
	}
	P0=temp;
	Select_HC573(4);
}

display.h

#ifndef		__DISPLAY_H
#define		__DISPLAY_H

void System_Init(void);
void Delayms(int ms);	
void Display_LED(unsigned char Number,unsigned char State);
void Display_Number(unsigned char Pos,unsigned char Data);

#define ON	1
#define OFF	0

#endif

onewire.c

/*	# 	单总线代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "onewire.h"
//
void Delay_OneWire(unsigned int t)  
{
	unsigned 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;
		Delay_OneWire(1);
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//
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;
}

unsigned char Read_Temp(void)
{
	unsigned char Temp;
	unsigned char th,tl;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	tl =Read_DS18B20();
	th=Read_DS18B20();
	Temp=(th*256+tl)*0.0625;
	return Temp;
}

onewire.h

#ifndef  __ONEWIRE_H__
#define  __ONEWIRE_H__

#include <STC15F2K60S2.H>


#define DQ  P14
unsigned char Read_Temp(void);

#endif

希望本文章能够对你学习蓝桥杯单片机有所帮助。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

—你的鼬先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值