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

前言     

    第三届省赛的蓝桥杯代码部分是比较简单的,因为举办得比较早,所以比赛的形式可能也有所不同,我在这里就主要讲解的是代码部分,其他的题目如果读者感兴趣的话可自行去了解。

        如果基础不太好的读者呢可去看我的一个讲得很详细的文章,这个文章很适合初学者去学,把基础打好之后,做其他的也就信手拈来了。

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

题目

过多的我就不赘述了,因为在我第十三届省赛代码那里我已经写过了,所以这里我就直接放出完整代码了。

完整代码

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

float Read_Output(unsigned char Channle)
{
	unsigned char ADC;
	float Byte;
	
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(Channle);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	
	ADC=I2CReceiveByte();
	I2CSendAck(1);
	Byte=ADC*5/255;
	return Byte;
}

iic.h

#ifndef  __IIC_H__
#define  __IIC_H__

#include <stc15.h>

#define sda  P21
#define scl  P20
float Read_Output(unsigned char Channle);

#endif

display.c

#include <STC15F2K60S2.H>

code unsigned char Number[]={
	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
};

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

void Delayms(int ms)	//@12.000MHz
{
	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_FNumber(unsigned char Pos,unsigned char Data)
{
	P0=0x01<<Pos-1;
	Select_HC573(6);
	P0=FNumber[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;
		}
	}
	else 
	{
		switch(Number)
		{
			case 1:temp |=0x01;break;
		}
	}
	P0=temp;
	Select_HC573(4);
}

void Display_Relay(unsigned char State)
{
	static unsigned char temp=0x00;
	if(State)
	{
		temp |=0x10;
	}
	else 
	{
		temp &=0x00;
	}
	P0=temp;
	Select_HC573(5);
}

 display.h

#ifndef		__DISPLAY_H__
#define		__DISPLAY_H__

void System_Init(void);
void Delayms(int ms);	//@12.000MHz
void Display_Number(unsigned char Pos,unsigned char Data);
void Display_LED(unsigned char Number,unsigned char State);
void Display_FNumber(unsigned char Pos,unsigned char Data);
void Display_Relay(unsigned char State);

#define ON	1
#define OFF	0

#endif

main.c

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

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


unsigned char Switching=0;
int total=0;
int Money=0;
unsigned char Count;
unsigned char OutFlag=0;

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

void Key_Board(void)
{
	unsigned char Key;
	P44=0;P3 |=0x0f;
	Key=P3;Key &=0x03;
	if(Key !=0x03)
	{
		Delayms(5);
		if(Key !=0x03)
		{
			switch(Key)
			{	//S6
				case 0x01:OutFlag=0;
				Switching=1;
				TR0=0;Display_Relay(OFF);
				break;
				case 0x02:
				if(OutFlag==0)
				{
					OutFlag=1;
					TR0=1;
					Display_Relay(ON);						
				}
				break;
			}
		}
		while(Key !=0x03)
		{
			Key=P3;Key &=0x03;
			Show_Switch();
		}
	}
}

void Show_Switch(void)
{
	if(Switching==0)
	{
		Display_FNumber(2,0);Display_Number(3,5);Display_Number(4,0);
		Display_Number(5,total/10000);Display_FNumber(6,total/1000%10);Display_Number(7,total/100%10);Display_Number(8,total/10%10);
		if(total == 99999)
		{
			Switching=1;
		}
	}
	else 
	{
		Display_FNumber(2,0);Display_Number(3,5);Display_Number(4,0);
		Display_Number(5,Money/10000);Display_FNumber(6,Money/1000%10);Display_Number(7,Money/100%10);Display_Number(8,Money/10%10);
	}
}

void PCF(void)
{
	if(Read_Output(0x01)<1.25)Display_LED(1,ON);
	else Display_LED(1,OFF);
}

void Timer0_Isr(void) interrupt 1
{
	Count++;
	if(Count==50)
	{
		Count=0;
		total+=100;
		Money=total*0.5;
	}
}

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

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

—你的鼬先生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值