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

本文是写第十二届的蓝桥杯省赛代码,如果是新手的话,欢迎去观看我专门为新手写的一篇。也欢迎收录该专栏。

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

专栏:

蓝桥杯单片机

接下来直接上正文。

试题

main.c

复制代码
#include <STC15F2K60S2.H>
#include "display.h"
#include "ds1302.h"
#include "onewire.h"
#include "iic.h"

void Key_Board(void);
void Show_Switch(void);
void LED(void);


ds1302 Date ={55,59,23};
int Temp;
int Val;
unsigned char Switching=1;
unsigned char Tempara=25;
unsigned char ParaFlag=0;
unsigned char Mode=0;
unsigned char ValFlag=1;

void main()
{
	System_Init();
	while(1)
	{
		Temp=Read_Temp();
		Key_Board();
		Show_Switch();
		LED();
	}
}

void Key_Board(void)
{
	unsigned char Key;
	P44=0;P42=1;P3 |= 0x0f;
	Key=P3;Key &=0x0c;
	if(Key != 0x0c)
	{
		Delayms(5);
		if(Key != 0x0c)
		{
			switch(Key)
			{
				case 0x04: Switching++; if(Switching>3)Switching=1;
					break; //S4
				case 0x08: Mode = !Mode;				
					break; //S5					
			}
		}
	}
	while(Key !=0x0c)
	{
		Key=P3;Key &=0x0c;
		Show_Switch();
	}
	
	P42=0;P44=1;P3 |= 0x0f;
	Key=P3;Key &=0x0c;
	if(Key != 0x0c)
	{
		Delayms(5);
		if(Key != 0x0c)
		{
			if(ParaFlag==1)
			{
				switch(Key)
				{			
					case 0x04: Tempara--;break; //S8
					case 0x08: Tempara++;break; //S9				
				}
			}
		}
	}
	while(Key !=0x0c)
	{
		Key=P3;Key &=0x0c;
		Show_Switch();
	}
}

void Show_Switch(void)
{
	switch(Switching)
	{
		case 1:
			ParaFlag=0;			
			ShowNumber(1,12);ShowNumber(5,Temp/1000);ShowFNumber(6,Temp/100%10);
			ShowNumber(7,Temp/10%10);ShowNumber(8,Temp%10);			
			break;
		case 2:
			ParaFlag=1; 
			ShowNumber(1,11);ShowNumber(7,Tempara/10);ShowNumber(8,Tempara%10);			
			break;
		case 3:
			ParaFlag=0;
			if(!ValFlag)
			{
				ShowNumber(1,13);ShowFNumber(6,(unsigned char)Val/100);ShowNumber(7,(unsigned char)Val/10%10);
				ShowNumber(8,(unsigned char)Val%10);
			}
			else 
			{
				ShowNumber(1,13);ShowNumber(8,Val);
			}
			break;
	}
	if(Mode == 0)
	{	
		ValFlag=1;
		Show_LED(1,ON);
		
		if(Temp/100 < Tempara) 
		{
			Val=0;							
		}
		else
		{
				
			Val=5;
		}
		Read_DAC(Val);
	}
	else
	{
		Show_LED(1,OFF);
		ValFlag=0;
		Val = Temp*3/20 -2;
		Read_DAC((Val/100)+(((Val/10)%10)/10)+((Val%10)/10));  
	}		                      
}

void LED(void)
{
	if(Switching ==1) Show_LED(2,ON);
	else Show_LED(2,OFF);
	
	if(Switching ==2) Show_LED(3,ON);
	else Show_LED(3,OFF);
	
	if(Switching ==3) Show_LED(4,ON);
	else Show_LED(4,OFF);
}

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

//double Read_Temp(void)
//{
//	unsigned char temp;
//	double 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<<8;
//	temp |=Tl;
//	Temp = (int)(temp*0.625);
//	return Temp;
//}

int Read_Temp(void)
{
	unsigned char th,tl;
	int temp;
	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)*6.25;//0.0625
	return temp;
}

onewire.h

复制代码
#ifndef  __ONEWIRE_H__
#define  __ONEWIRE_H__

#include <STC15F2K60S2.H>

//float Read_Temp(void);
int Read_Temp(void);


#define DQ  P14

#endif

iic.c

复制代码
/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "iic.h"
#include "intrins.h"
#define DELAY_TIME	5

//
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();		
    }
    while(n--);      	
}

//
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}

//
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
	
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}

//
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}

//
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
	
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}

void Read_DAC(double Data)
{
//	double temp;
//	temp = Data/100+Data/10%10/10+Data%10/10;
	
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x40);	//通道0x40是发送AD信号
	I2CWaitAck();
	I2CSendByte(Data);
	I2CWaitAck();
	I2CStop();
	
}

iic.h

复制代码
#ifndef  __IIC_H__
#define  __IIC_H__

#include <stc15.h>

#define sda  P21
#define scl  P20

//unsigned char Read_ADC(unsigned char channel);
void Read_DAC(double Data);

#endif

display.c

复制代码
#include <STC15F2K60S2.H>
#include "display.h"


code unsigned char Show_Number[] = {
	0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,	//0~9
	0xBF,	//- 10
	0x88,	//A 11
	0xC6,	//C 12
	0x8C	//P 13
};

code unsigned char Show_FNumber[] ={
	0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10
};

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 Delayms(int ms)	//@12.000MHz
{
	unsigned char data i, j;
	int k;
	
	for(k=0;k<ms;k++)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}



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

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

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

void Show_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;
			case 4:temp &=0xf7;break;
		}
	}
	else
	{
		switch(Number)
		{
			case 1:temp |=0x01;break;
			case 2:temp |=0x02;break;
			case 3:temp |=0x04;break;
			case 4:temp |=0x08;break;
		}
	}
	P0 =temp;
	Select_HC573(4);
}

display.h

复制代码
#ifndef		__DISPLAY_H__
#define		__DISPLAY_H__

#define ON		1
#define OFF		0

void System_Init(void);
void ShowNumber(unsigned char Pos,unsigned char Data);
void ShowFNumber(unsigned char Pos,unsigned char Data);
void Show_LED(unsigned char Number,unsigned char state);
void Delayms(int ms);	//@12.000MHz


#endif

ds1302.c

复制代码
/*	# 	DS1302代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/								
#include "ds1302.h"
#include <STC15F2K60S2.H>


sbit SCK = P1^7;		
sbit SDA = P2^3;		
sbit RST = P1^3; 

//
void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK = 0;
		SDA = temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}

#define	WP		0x8e
#define W_Sec	0x80
#define R_Sec	0x81
#define W_Min	0x82
#define R_Min	0x83
#define W_Hour	0x84
#define R_Hour	0x85

void Write_Time(ds1302 *Date)
{
	unsigned char Sec,Min,Hour;
	Hour = Date -> Hour/10*16 + Date->Hour%10;
	Min = Date->Min/10*16+Date->Min%10;
	Sec = Date->Sec/10*16+Date->Sec%10;
	
	Write_Ds1302_Byte(WP,0x00);
	Write_Ds1302_Byte(W_Sec,Sec);
	Write_Ds1302_Byte(W_Min,Min);
	Write_Ds1302_Byte(W_Hour,Hour);
	Write_Ds1302_Byte(WP,0x00);
}

ds1302 Read_Time(void)
{
	unsigned char Hour,Min,Sec;
	ds1302 Date;
	
	Hour =  Read_Ds1302_Byte(R_Hour);
	Min =  Read_Ds1302_Byte(R_Min);
	Sec =  Read_Ds1302_Byte(R_Sec);
	
	Date.Hour=Hour/16*10+Hour%16;
	Date.Min=Min/16*10+Min%16;
	Date.Sec=Sec/16*10+Sec%16;
	
	return Date;
}

ds1302.h

复制代码
#ifndef  __DS1302_H__
#define  __DS1302_H__

#include <STC15F2K60S2.H>
#include "intrins.h"

typedef struct {
	unsigned char Sec;
	unsigned char Min;
	unsigned char Hour;
}ds1302;

void Write_Time(ds1302 *Date);
ds1302 Read_Time(void);


#endif
相关推荐
智者知已应修善业42 分钟前
【51单片机用数码管显示流水灯的种类是按钮控制数码管加一和流水灯】2022-6-14
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
智商偏低7 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen8 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森10 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白10 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D11 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术14 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt14 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘15 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang15 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c