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

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

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,
                  0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,
                  0xbf,0xff,0x8e,0xc1};
uchar yi,er,san,si,wu,liu,qi,ba;   //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量
uchar yemian=0,AD;
uchar LED_bit=0XFF;
uint Dianya,trie=0,zheng,zheng_send,fan,fan_send,time,Pinlv;
bit flag=0,DAC=0,SMG_guan=0,LED_guan=0;
									
void delayms(int ms);          //延时函数
void allinit();                //初始化函数
void keyscan16();              //矩阵按键函数
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微秒@12.000MHz
void Timer1Init(void);		//1毫秒@12.000MHz
									
void main()//主函数
{
	allinit();
	Timer0Init();
	Timer1Init();
	yi=21;er=21;san=21;si=21;wu=21;liu=21;qi=21;ba=21;//上电数码管全部熄灭
	while(1)
	{
		AD=AD_read(0x03);     //获取AD的值
		if(DAC==0){AD_write(102);}   //当DAC等于0时读取固定电压值2V
		else if(DAC==1){AD_write(AD);} //当DAC等于1时读取RB2模拟电压值
		if(yemian==0)  //电压显示页面
		{
			Dianya=AD*1.961;
			yi=23;er=21;san=21;si=21;wu=21;liu=Dianya/100+10;qi=Dianya%100/10;ba=Dianya%10;	
		}
		else if(yemian==1)  //频率显示页面
		{
			if(Pinlv>=10000){yi=22;er=21;san=21;si=Pinlv/10000;wu=Pinlv%10000/1000;liu=Pinlv%1000/100;qi=Pinlv%100/10;ba=Pinlv%10;}
			else if(Pinlv>=1000){yi=22;er=21;san=21;si=21;wu=Pinlv/1000;liu=Pinlv%1000/100;qi=Pinlv%100/10;ba=Pinlv%10;}
			else if(Pinlv>=100){yi=22;er=21;san=21;si=21;wu=21;liu=Pinlv/100;qi=Pinlv%100/10;ba=Pinlv%10;}
			else if(Pinlv>=10){yi=22;er=21;san=21;si=21;wu=21;liu=21;qi=Pinlv/10;ba=Pinlv%10;}
		}
		if(LED_guan==0)   //各LED指示灯工作程序
		{
			if(yemian==0){P2|=0X80;P2&=0X9F;LED_bit=0XFE;LED_bit|=0X02;P0=LED_bit;}
			else if(yemian==1){P2|=0X80;P2&=0X9F;LED_bit=0XFD;LED_bit|=0X01;P0=LED_bit;}
			if(Dianya<150){P2|=0X80;P2&=0X9F;LED_bit|=0X04;P0=LED_bit;}
			else if((Dianya>=150)&&(Dianya<250)){P2|=0X80;P2&=0X9F;LED_bit&=0XFB;P0=LED_bit;}
			else if((Dianya>=250)&&(Dianya<350)){P2|=0X80;P2&=0X9F;LED_bit|=0X04;P0=LED_bit;}
			else if(Dianya>=350){P2|=0X80;P2&=0X9F;LED_bit&=0XFB;P0=LED_bit;}
			
			if(Pinlv<1000){P2|=0X80;P2&=0X9F;LED_bit|=0X08;P0=LED_bit;}
			else if((Pinlv>=1000)&&(Pinlv<5000)){P2|=0X80;P2&=0X9F;LED_bit&=0XF7;P0=LED_bit;}
			else if((Pinlv>=5000)&&(Pinlv<10000)){P2|=0X80;P2&=0X9F;LED_bit|=0X08;P0=LED_bit;}
			else if(Pinlv>=10000){P2|=0X80;P2&=0X9F;LED_bit&=0XF7;P0=LED_bit;}
			
			if(DAC==0){P2|=0X80;P2&=0X9F;LED_bit&=0XEF;P0=LED_bit;}
			else if(DAC==1){P2|=0X80;P2&=0X9F;LED_bit|=0X10;P0=LED_bit;}
		}
		keyscan();  //独立按键函数
		if(SMG_guan==0)   //数码管显示打开/关闭判断
		{
			display1(yi,er);          //第一、二段数码管函数
			display2(san,si);         //第三、四段数码管函数
			display3(wu,liu);         //第五、六段数码管函数
			display4(qi,ba);          //第七、八段数码管函数
		}
	}
}
void keyscan()//独立按键函数
{
	if(P30==0)       //判断P30是否等于0
	{
		delayms(5);    //延时5ms
		if(P30==0)     //再次判断P30是否等于0 
		{
			if(SMG_guan==0){SMG_guan=1;P2|=0XC0;P2&=0XDF;P0=0XFF;P2|=0XE0;P2&=0XFF;P0=0XFF;}
			else if(SMG_guan==1)SMG_guan=0;
		}
		while(!P30);   //如果按键不松开,则一直循环
	}
	else if(P31==0)  //判断P31是否等于0
	{
		delayms(5);    //延时5ms
		if(P31==0)     //再次判断P31是否等于0 
		{
			if(LED_guan==0){LED_guan=1;P2|=0X80;P2&=0X9F;P0=0XFF;}
			else if(LED_guan==1)LED_guan=0;
		}
		while(!P31);   //如果按键不松开,则一直循环
	}
	else if(P32==0)  //判断P32是否等于0
	{
		delayms(5);    //延时5ms
		if(P32==0)     //再次判断P32是否等于0 
		{
			if(DAC==0)DAC=1;
			else if(DAC==1)DAC=0;
		}
		while(!P32);   //如果按键不松开,则一直循环
	}
	else if(P33==0)  //判断P33是否等于0
	{
		delayms(5);    //延时5ms
		if(P33==0)     //再次判断P33是否等于0 
		{
			if(yemian==0)yemian=1;
			else if(yemian==1)yemian=0;
		}
		while(!P33);   //如果按键不松开,则一直循环
	}
}
void Timer0Init(void)		//5微秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xC4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
}
void time0() interrupt 1
{
	if(P34==0)
	{
		fan++;
		if(flag==0)
		{
			flag=1;
			zheng_send=zheng;
			zheng=0;
		}
	}
	else if(P34==1)
	{
		zheng++;
		if(flag==1)
		{
			flag=0;
			fan_send=fan;
			fan=0;
		}
	}
}
void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初值
	TH1 = 0xD1;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	EA=1;ET1=1;
}
void time1() interrupt 3
{
	trie++;
	if(trie==969)
	{
		TR0=1;ET0=1;
	}
	else if(trie==999)
	{
		TR0=0;ET0=0;
		trie=0;
		time=(zheng_send+fan_send)*5;
		Pinlv=1000000/time;
	}
}
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];            //让第一个数码管显示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];           //让第一个数码管显示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 "iic.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 AD_read(unsigned char add)
{
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_Stop();
	
	return temp;
}
void AD_write(unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

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 AD_read(unsigned char add);
void AD_write(unsigned char dat);

#endif

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

<iframe allowfullscreen="true" data-mediaembed="bilibili" id="qYt3EZoe-1619960225648" src="https://player.bilibili.com/player.html?aid=715326351"></iframe>

第十届蓝桥杯单片机作品演示

上一篇:LCD1602(以51单片机为例)


下一篇:跟着我从零开始入门FPGA(一周入门XXOO系列)-5、同步和异步设计