第三届蓝桥杯单片机省赛----程序题

在这里插入图片描述
在这里插入图片描述
因为最近参加比赛蓝桥杯大赛,所以把历年省赛试题做了个遍,每套试题功能也已全部实现,分享出来供大家参考学习。
这次分享的是第三届蓝桥杯单片机省赛的程序题,同样也是第四届蓝桥杯单片机的模拟题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
直接上代码吧,里面注释很清晰。

在这里插入图片描述
main.c程序

#include<stc15f2k60s2.h>
#include "iic.h"

#define uchar unsigned char   //定义无符号字符类型uchar
#define uint unsigned int     //定义无符号整型类型uint

uchar code tab[]={
    
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//数字0~9,“-”,“关”
uchar yi,er,san,si,wu,liu,qi,ba;   //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量

uchar guang; 
uint ML_10=0,money=0,tt=0;

void delayms(int ms);          //延时函数
void allinit();                //初始化函数
void keyscan();                //独立按键函数
void display1(uchar yi,uchar er);   //第一、二段数码管函数
void display2(uchar san,uchar si);  //第三、四段数码管函数
void display3(uchar wu,uchar liu);  //第五、六段数码管函数
void display4(uchar qi,uchar ba);   //第七、八段数码管函数
void Timer0Init(void);		//5毫秒@11.0592MHz

void main()//主函数
{
    
    
	allinit();                  //初始化函数
	Timer0Init();               //初始化定时器0
	yi=11;er=0;san=5;si=0;wu=0;liu=1;qi=0;ba=0;
	while(1)
	{
    
    
		guang=IIC_read(0x01);   //获取光敏电阻的值赋给变量guang
		if(guang<64)            //判断光敏电阻通道输入电压是否小于1.25V
		{
    
    
			P2=0X80;P0=0XFE;      //L1点亮
		}
		else                    //如果不小于
		{
    
    
			P2=0X80;P0=0XFF;      //L1熄灭 
		}
		
		keyscan();                //独立按键函数
		display1(yi,er);          //第一、二段数码管函数
		display2(san,si);         //第三、四段数码管函数
		display3(wu,liu);         //第五、六段数码管函数
		display4(qi,ba);          //第七、八段数码管函数
	}
}
void Timer0Init(void)		//5毫秒@11.0592MHz
{
    
    
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x28;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
void tm0_isr() interrupt 1   //定时器中断函数
{
    
    
  tt++;             //tt++;
	if(tt==20)        //判断是否到0.1s
	{
    
    
		ML_10=ML_10+1;  //出水量+1,即0.1s加10ML,符合题意100ML/秒
		wu=ML_10/1000;liu=ML_10%1000/100;qi=ML_10%100/10;ba=ML_10%10;//显示出水量
		tt=0;           //tt清零
		if(ML_10>=9999)  //判断是否达到99.99L
		{
    
    
			P2=0XA0;P0=0X00;   //关继电器
			money=ML_10*0.5;   //计算水费
			wu=money/1000;liu=money%1000/100;qi=money%100/10;ba=money%10;   //显示水费价格
			ML_10=0;    //出水量清零
		}
	}
}
void keyscan()//独立按键函数
{
    
    
	if(P30==0)       //判断P30是否等于0
	{
    
    
		delayms(5);    //延时5ms
		if(P30==0)     //再次判断P30是否等于0 
		{
    
    
			EA=1;ET0=1;  //打开定时器0
			P2=0XA0;P0=0X10;   //打开继电器
		}
		while(!P30);   //如果按键不松开,则一直循环
	}
	else if(P31==0)  //判断P31是否等于0
	{
    
    
		delayms(5);    //延时5ms
		if(P31==0)     //再次判断P31是否等于0 
		{
    
    
			EA=0;ET0=0;   //关闭定时器0
			P2=0XA0;P0=0X00;//关闭继电器
			money=ML_10*0.5;//计算水费
			wu=money/1000;liu=money%1000/100;qi=money%100/10;ba=money%10;//用来显示水费
			ML_10=0;	    //出水量清零
		}
		while(!P31);   //如果按键不松开,则一直循环
	}
}
void delayms(int ms)//延时函数
{
    
    
	uint i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
    
    
	P2=0XA0;P0=0X00;      //关闭蜂鸣器继电器
	P2=0X80;P0=0XFF;      //关闭所有LED灯
	
	P2=0XC0;P0=0XFF;      //选中所有数码管段选
	P2=0XFF;P0=0XFF;      //关闭所有数码管
}
void display1(uchar yi,uchar er)//第一、二段数码管函数
{
    
    
	P2=0XC0;P0=0X01;               //选中第一个数码管位选
	P2=0XFF;P0=tab[yi];            //让第一个数码管显示yi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X02;               //选中第二个数码管位选
	P2=0XFF;P0=tab[er]&0x7f;            //让第一个数码管显示er指向的值
	delayms(1);	                   //延时1ms
}
void display2(uchar san,uchar si)//第三、四段数码管函数
{
    
    
	P2=0XC0;P0=0X04;               //选中第s三个数码管位选
	P2=0XFF;P0=tab[san];           //让第一个数码管显示san指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X08;               //选中第四个数码管位选
	P2=0XFF;P0=tab[si];            //让第一个数码管显示si指向的值
	delayms(1);	                   //延时1ms
}
void display3(uchar wu,uchar liu)//第五、六段数码管函数
{
    
    
	P2=0XC0;P0=0X10;               //选中第五个数码管位选
	P2=0XFF;P0=tab[wu];            //让第一个数码管显示wu指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X20;               //选中第六个数码管位选
	P2=0XFF;P0=tab[liu]&0x7f;          //让第一个数码管显示liu指向的值
	delayms(1);	                   //延时1ms
}
void display4(uchar qi,uchar ba)//第七、八段数码管函数
{
    
    
	P2=0XC0;P0=0X40;               //选中第七个数码管位选
	P2=0XFF;P0=tab[qi];            //让第一个数码管显示qi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X80;               //选中第八个数码管位选
	P2=0XFF;P0=tab[ba];            //让第一个数码管显示ba指向的值
	delayms(1);                    //延时1ms
	P2=0XC0;P0=0X80;               //选中第八个数码管位选
	P2=0XFF;P0=0XFF;               //让第八个数码管熄灭             
}

iic.c程序

#include<stc15f2k60s2.h>
#include "intrins.h"

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}    


#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

//总线启动条件
void IIC_Start(void)
{
    
    
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    
    
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

//等待应答
bit IIC_WaitAck(void)
{
    
    
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{
    
       
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{
    
     
		SCL = 0;
		return 1;
	}
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    
    
	unsigned char i;
	for(i=0;i<8;i++)
	{
    
       
		if(byt&0x80) 
		{
    
    	
			SDA = 1;
		}
		else 
		{
    
    
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    
    
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{
    
       
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}

unsigned char IIC_read(unsigned char add)
{
    
    
	unsigned char temp;
	
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Start();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Start();
	
	return temp;
}

iic.h程序

#ifndef _IIC_H
#define _IIC_H

//函数声明
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 
unsigned char IIC_read(unsigned char add);

#endif

在这里插入图片描述

第三届蓝桥杯单片机省赛作品演示

Guess you like

Origin blog.csdn.net/qq_45385706/article/details/114947717