蓝桥杯单片机第十届国赛

今天是第十三届蓝桥杯单片机国赛的比赛时间,刚比完,简单说一下感想,这次国赛必须要用到三个定时器,昨天刚看了定时器2的使用,不太熟练,所以写的也不是很好,超声波和频率有点冲突,就个人而言,我觉得这一届最大的难点也就是在这里了,其他的应该没什么难的,个人感觉。虽然没有写的很好,但是总体思路还可以说一下,怎么解决定时器问题。

定时器0必须用来测量频率,定时器1必须用来超声波测距,那么还需要一个定时器来实现一些外设的定时,比如数码管的2ms扫描一次,再比如按键的20ms扫描一次,所以这一届国赛,需要用到三个定时器,那就得用到定时器2。这个时候可能就会有疑问,为什么一定要用到定时器2,我简单说明一下,因为定时器0作为计数脉冲,也就是说这时的定时器0是作为计数器使用的,超声波需要用到TF溢出标志位,而这个标志位只有定时器0和定时器1才有,定时器0已经被使用了,所以只能用定时器1。而定时器2既不能作为计数器使用,也没有TF标志位,所以这一届就需要用到三个定时器。(说错请在评论区纠正,个人观点,不喜勿喷)

以后有时间可以出一下第十三届国赛的代码,今天就简单出一下第十届吧,第十届考到了串口,也存在一定难度,说了这么多废话,还是展示代码吧。

对以下代码有疑问的可以评论区问我,我会尽我所能给大家解答,谢谢支持

#include "stc15.h"
#include "iic.h"
#include "onewire.h"
#include "intrins.h"
#include "stdio.h"

typedef unsigned char u8;
typedef unsigned int u16;
u8 code SMG_duan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 code SMG_com[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
u8 SMG_bit[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
u8 buf[12];
u8 send_buf[12];

sbit TX=P1^0;
sbit RX=P1^1;
bit key_flag=0,temp_flag=0,dis_flag=0,flag=0,dac_flag=0,time_delay=0;
u8 Trg=0,Cont=0;
u8 mode=0,display_mode=0;
u8 distance=0;
u8 temp_para=30,dis_para=35;
u8 a=30,b=35;
u8 led_falg=0;
u8 num=0;
float temp_true=0;
u8 led_para=0xff;
u16 xdata temp_num=0,t=0;
u16 xdata degree=0;
u16 xdata count_s6=0,count_s13=0;

void Delay13us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 36;
	while (--i);
}
void Delay3ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 36;
	j = 1;
	do
	{
		while (--j);
	} while (--i);
}


void Initialize()//初始化函数
{
	P0=0xff;P2=(P2&0x1f)|0x80;P2=0x00;
	P0=0x00;P2=(P2&0x1f)|0xa0;P2=0x00;
}

unsigned char Key_Read()//键值获取函数
{
	unsigned char temp = 0;
	P44 = 0;P42 = 1;P35 = 1;P34 = 1;
	if(P33 == 0) temp = 0x88;
	if(P32 == 0) temp = 0x84;
	if(P31 == 0) temp = 0x82;
	if(P30 == 0) temp = 0x81;
	P44 = 1;P42 = 0;P35 = 1;P34 = 1;
	if(P33 == 0) temp = 0x48;
	if(P32 == 0) temp = 0x44;
	if(P31 == 0) temp = 0x42;
	if(P30 == 0) temp = 0x41;
	P44 = 1;P42 = 1;P35 = 0;P34 = 1;
	if(P33 == 0) temp = 0x28;
	if(P32 == 0) temp = 0x24;
	if(P31 == 0) temp = 0x22;
	if(P30 == 0) temp = 0x21;
	P44 = 1;P42 = 1;P35 = 1;P34 = 0;
	if(P33 == 0) temp = 0x18;
	if(P32 == 0) temp = 0x14;
	if(P31 == 0) temp = 0x12;
	if(P30 == 0) temp = 0x11;
	return temp;
}

void KEY_read_true()//按键执行函数
{
	u8 read;
	read=Key_Read();
	Trg=read&(read^Cont);
	Cont=read;
}

void PCF8591_dac(u8 add)//dac函数
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
}
void AT24C02_wrtie(u8 add,u8 val)//存储函数
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(val);
	IIC_WaitAck();
	IIC_Stop();
}
u8 AT24C02_read(u8 add)
{
	u8 temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	return temp;
}

void send_wave()//超声波发波函数
{
	u8 i=8;
	do
	{
		TX=1;
		Delay13us();
		TX=0;
		Delay13us();
	}
	while(i--);
}

void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
}

void Uart_Send(unsigned char *Uart_String)//串口发送字符函数
{
	while(*Uart_String != '\0')
	{
		SBUF = *Uart_String;
		while(TI == 0);
		TI = 0;
		Uart_String++;
	}
}
void UartInit(void)		//4800bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR |= 0x04;		//定时器2时钟为Fosc,即1T
	T2L = 0x8F;		//设定定时初值
	T2H = 0xFD;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
	ES=1;
}
void uart() interrupt 4
{
	if(RI)
	{
		RI=0;
		buf[num]=SBUF;
		num++;
	}
}

void KEY_execute()//按键处理函数
{
	if(key_flag)
	{
		key_flag=0;
		KEY_read_true();
		switch(Trg)
		{
			case 0x18:
				if((mode==1)&&(display_mode==0))
				{
					temp_para-=2;
					if(temp_para==254)
						temp_para=98;
				}
				if((mode==1)&&(display_mode==1))
				{
					dis_para-=5;
					if(dis_para==251)
						dis_para=95;
				}
				break;//s16
			case 0x14:
				if((mode==1)&&(display_mode==0))
				{
					temp_para+=2;
					if(temp_para==100)
						temp_para=0;
				}
				if((mode==1)&&(display_mode==1))
				{
					dis_para+=5;
					if(dis_para==100)
						dis_para=0;
				}
				break;//s17
		}
		if(Cont==0x28)//s12
		{
			count_s6++;
			if(count_s6>=50)//超过1s是长按
				degree=0;
		}
		if((Cont==0x24)&&(led_falg==0))//s13
		{
			count_s13++;
			if(count_s13>=50)
			{
				dac_flag^=1;
				led_falg=1;
			}
		}
		if((Cont==0x00)&&(Trg==0x00))//松手检测
		{
			if(count_s6>=50)
				count_s6=0;
			else if(count_s6!=0)
			{
				count_s6=0;
				if(mode==0)
				{
					if(++display_mode==3)display_mode=0;
				}
				if(mode==1)
				{
					if(++display_mode==2)display_mode=0;
				}
			}
			if(count_s13>=50)
			{
				count_s13=0;
				led_falg=0;
			}
			else if(count_s13!=0)
			{
				count_s13=0;
				display_mode=0;
				if(++mode==2)
				{
					mode=0;
					if((a!=temp_para)||(b!=dis_para))
					{
						degree++;
						a=temp_para;b=dis_para;
					}
				}
			}
		}
		AT24C02_wrtie(0x00,degree/255);
		Delay3ms();
		AT24C02_wrtie(0x01,degree%255);
	}
}

void SMG_execute()//数码管处理函数
{
	u8 j=3,i;
	for(i=0;i<8;i++)
		SMG_bit[i]=0xff;
	if(mode==0)
	{
		switch(display_mode)
		{
			case 0:
				SMG_bit[0]=0x8e;
				SMG_bit[1]=SMG_duan[num];
				SMG_bit[4]=SMG_duan[temp_num/1000];
				SMG_bit[5]=SMG_duan[temp_num/100%10]&0x7f;
				SMG_bit[6]=SMG_duan[temp_num/10%10];
				SMG_bit[7]=SMG_duan[temp_num%10];
				break;
			case 1:
				SMG_bit[0]=0xc7;
				SMG_bit[6]=SMG_duan[distance/10];
				SMG_bit[7]=SMG_duan[distance%10];
				break;
			case 2:
				SMG_bit[0]=0x98;
				SMG_bit[3]=SMG_duan[degree/10000];
				SMG_bit[4]=SMG_duan[degree/1000%10];
				SMG_bit[5]=SMG_duan[degree/100%10];
				SMG_bit[6]=SMG_duan[degree/10%10];
				SMG_bit[7]=SMG_duan[degree%10];
				while(SMG_bit[j]==0xc0)
				{
					SMG_bit[j]=0xff;
					j++;
					if(j==7)break;
				}
				break;
		}
	}
	else
	{
		switch(display_mode)
		{
			case 0:
				SMG_bit[0]=0x92;
				SMG_bit[3]=SMG_duan[1];
				SMG_bit[6]=SMG_duan[temp_para/10];
				SMG_bit[7]=SMG_duan[temp_para%10];
				break;
			case 1:
				SMG_bit[0]=0x92;
				SMG_bit[3]=SMG_duan[2];
				SMG_bit[6]=SMG_duan[dis_para/10];
				SMG_bit[7]=SMG_duan[dis_para%10];
				break;
		}
	}
}
	
void LED_execute()//LED灯处理函数
{
	if(temp_num>temp_para*100)
	{
		led_para&=~(1<<0);
	}
	else
	{
		led_para|=(1<<0);
	}
	if(distance<dis_para)
	{
		led_para&=~(1<<1);
	}
	else
	{
		led_para|=(1<<1);
	}
	if(dac_flag==0)
	{
		led_para&=~(1<<2);
	}
	else
	{
		led_para|=(1<<2);
	}
}

void main()
{
	Initialize();
	degree=AT24C02_read(0x00)*255+AT24C02_read(0x01);
	Timer0Init();
	UartInit();
	while(1)
	{
		if(time_delay)
		{
			time_delay=0;
			if(num>0)
			{
				if(buf[0]=='S' && buf[1]=='T' && num<=2)
				{
					sprintf(send_buf,"$%d,%.2f\r\n",(int)distance,temp_true);
					Uart_Send(send_buf);
					num=0;
				}
				else if(buf[0]=='P' && buf[1]=='A' && buf[2]=='R' && buf[3]=='A' && num<=4)
				{
					sprintf(send_buf,"#%d,%d\r\n",(int)dis_para,(int)temp_para);
					Uart_Send(send_buf);
					num=0;
				}
				else
				{
					sprintf(send_buf,"%d:ERROR\r\n",(int)num);
					Uart_Send(send_buf);
					num=0;
				}
				
			}
		}
		if(temp_flag)
		{
			temp_flag=0;
			temp_true=rd_temperature();
			temp_num=temp_true*100;
		}
		if(dis_flag)
		{
			dis_flag=0;
			send_wave();
			TR1=1;
			while((TF1==0)&&(RX==1));
			TR1=0;
			if(TF1==1)
			{
				TF1=0;
				distance=99;
			}
			else
			{
				t=(TH1<<8)|TL1;
				distance=(unsigned int)(t*0.017);
				if(distance>=99)
					distance=99;
			}
			TH1=0;
			TL1=0;
		}
		if(dac_flag==1)
		{
			PCF8591_dac(255*0.4);
		}
		else
		{
			if(distance>dis_para)
				PCF8591_dac(204);
			else
				PCF8591_dac(102);
		}
		KEY_execute();
		if(flag)
		{
			flag=0;
			SMG_execute();
		}
		LED_execute();
	}
}

void Timer0() interrupt 1
{
	static int smg_count=0,key_count=0,temp_count=0,dis_count=0,count=0,time_count=0,i=0;
	smg_count++;key_count++;temp_count++;dis_count++;count++;time_count++;
	if(time_count==20)
	{
		time_count=0;
		time_delay=1;
	}
	if(count==50)
	{
		count=0;
		flag=1;
	}
	if(dis_count==200)
	{
		dis_count=0;
		dis_flag=1;
	}
	if(temp_count==100)
	{
		temp_count=0;
		temp_flag=1;
	}
	if(key_count==20)
	{
		key_count=0;
		key_flag=1;
	}
	if(smg_count==2)
	{
		smg_count=0;
		P0=led_para;P2=0x80;P2=0x00;
		P0=0x00;P2=0xa0;P2=0x00;
		P0=0xff;P2=0xe0;P2=0x00;
		P0=SMG_com[i];P2=0xc0;P2=0x00;
		P0=SMG_bit[i];P2=0xe0;P2=0x00;
		i++;
		if(i==8)i=0;
	}
}

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

雪菲人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值