蓝桥杯单片机 第十二届 国赛

总体感受

蓝桥杯第十二届,模块都比较常规,感觉都和省赛差不多,主要是麻烦在数据处理上,而我们处理的数据又要在界面中显示出来。

总体框图

在这里插入图片描述
对比之前的第十届,其实题目差不多,并且少了串口收发这一比较难的模块。但是多了max,min,avg三个超声波数据的处理。所以按道理时间方面应该是花的差不多。

做题顺序

先是smg,再是按键,再是led检测按键是否写对,然后写DS1302顺便将它的smg界面写了,然后AD/DA模块,先数码管显示光敏数值,检测此模块是否写对,最后超声波&界面(检测超声波模块是否写对)

其实单纯写这些模块并不会花费很长时间,花时间的是将他们和界面串起来。

  1. 写按键S4跳转数据界面和参数界面
  2. S5页面间跳转0,1,2对应数据三个界面; 奇数对应时间参数界面,偶数对应距离参数界面。
  • 完善参数界面

S5(利用奇数偶数)跳转 采集时间 和 距离参数界面
S9 采集时间变化 距离参数相加

  • 完善数据界面

时间&距离&记录
填充数据进去,在距离界面还要有S8控制测距方式
记录时间可以直接用数组进行计算,只不过min初值设置成最大值,max的初值设为0即可,然后每一次进行判断,即可得到测量过程中的最大值和最小值。
AVG的算法:用for循环,记录测量的次数,然后将每次测量值相加再/(测量次数)即可得到平均值。

  1. 写led灯亮了,就再每个判断的地方进行判断那个灯亮还是灭。
    最后进行汇总相加就可以了。
void led_cmd()
{
	led(led1+led2*2+led3*4+led4*8+led5*16+led6*32);
}

附上源码

写得有点乱,请见谅呀

mian.c

#include<stc15f2k60s2.h>
#include<ds1302.h>
#include<iic.h>
#include <intrins.h>
#define somenop  {_nop_();  _nop_();  _nop_();  _nop_();  _nop_();  _nop_();  _nop_();  _nop_();  _nop_();  _nop_();  }
u8 code T_duan[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码

sbit h1 = P3^0;
sbit h2 = P3^1;
sbit h3 = P3^2;
sbit h4 = P3^3;
sbit l1 = P4^4;
sbit l2 = P4^2;
sbit l3 = P3^5;
sbit l4 = P3^4;
sbit TX = P1^0;
sbit RX = P1^1 ;
u8 count;
u8 smg_i,table[8];
u8 keyval,key_state;
u8 shi,fen,miao,miaoo;
u8 distance,warning1,warning2,warning3;
u8 light;
u8 index_time[6]={2,3,5,7,9},time_i,index_distance = 20,index_distance1 = 20,index_time1 = 2;
u8 mode;//press s5
u8 max = 0,min  = 90,jilu_mode;
u8 i,led1,led2,led3,led4,led5,led6;
u8 a,b;
u16 c;
u16 AVG;
bit key_flag,key500ms;
bit dat_index_flag;
bit trg_count_flag,liang_flag;

void Timer1Init();
void Timer0Init();		//100微秒@12.000MHz;
void allinit();
void smg();
void smg_dis();
void led(u8 dat);
void r_distance();
void sendsonic();
void disance_record();
void led_cmd();
u8 key_scan();
u8 test_i,distance_test[20] = 0;

void tm1_isr() interrupt 3 using 1
{
    if (count-- == 0)               //1ms * 1000 -> 1s
    {
        count = 1000;               //reset counter
    }
		if(count %2 == 0) smg();
		if(count %10 == 0) key_flag = 1;
		if(count %500 == 0) key500ms = 1;
}



void main()
{
	 Timer1Init();
	 Timer0Init();	
	 allinit();
	set_time(20,20,1);
	a = 240; b = 30;
	c= a+b;
	if(trg_count_flag == 0) led4 = 1; else led4 = 0;
	 while(1)
	 {
		 

		 
		 if(key500ms)
		 {
			 key500ms = 0;
			 miao = Read_Ds1302_Byte(0x81)/16*10+Read_Ds1302_Byte(0x81)%16;
			 
			 fen = Read_Ds1302_Byte(0x83)/16*10+Read_Ds1302_Byte(0x83)%16;
			 shi = Read_Ds1302_Byte(0x85)/16*10+Read_Ds1302_Byte(0x85)%16;
			 if(trg_count_flag == 1 && miao%index_time1 == 1)
			 {
			 r_distance(); disance_record();
				 
			  warning3 = warning2; warning2 = warning1;  warning1 = distance; 
	     if(warning3 +5-index_distance1<11 &&warning2 +5-index_distance1<11&&warning2 +5-index_distance1<11) led5 = 1;
	     else led5 = 0;
			 }
			 miaoo = miao;
			 
		 }
		 if(key_flag)
		 {
			 led_cmd();
			 light = r_light();  if(light>50) led6 = 1; else led6 = 0;
			 	if(trg_count_flag == 0)
			 {
				   //light<40视为暗
				 if(liang_flag == 1)            //判断上一个状态
				 {
					 if(light<51) {r_distance(); liang_flag = 0; disance_record();}
				 }
				 if(light>50) {liang_flag = 1;}

				 
			 }
			 
			 smg_dis();
			 key_flag = 0;
			 keyval = key_scan();
			 switch(keyval)
			 {
				 case 4: dat_index_flag = ~dat_index_flag;  if(dat_index_flag) {led1 = 0; led2 = 0; led3 = 0;}  mode = 0;   index_distance1 = index_distance;  index_time1 = index_time[time_i]; jilu_mode = 0; break;
				 case 5: mode++; if(mode == 3) mode = 0;       jilu_mode = 0; break;
				 case 8: if(mode == 2){jilu_mode++; if(jilu_mode == 3) jilu_mode = 0;}
                 else if(mode == 1) trg_count_flag = ~trg_count_flag; 		if(trg_count_flag == 0) led4 = 1; else led4 = 0;		 break;
				 case 9: if(mode%2 == 0) {time_i++; if(time_i == 5) time_i = 0;}
                 else { index_distance += 10; if(index_distance == 90) index_distance = 10; }				 break;
			 }
		 }
	 }
}

void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x20;		//设置定时初值
	TH1 = 0xD1;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	ET1 = 1;
	EA = 1;
}

void Timer0Init(void)		//100微秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x9C;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 0;		//定时器0开始计时
}

void allinit()
{
	led(0x00);
	P2 = (P2&0x1f)|0xa0; P0 = 0x00; P2 = (P2&0x1f);
}
void led(u8 dat)
{
	P2 = (P2&0x1f)|0x80; P0 = ~dat; P2 = (P2&0x1f);
}
void smg()
{
	P2 = (P2&0x1f)|0xc0; P0 = T_COM[smg_i]; P2 = (P2&0x1f);
	P2 = (P2&0x1f)|0xe0; P0 = ~table[smg_i]; P2 = (P2&0x1f);
	smg_i++;
	smg_i &= 0x07;
}
void smg_dis()
{

	if(dat_index_flag != 1)
	{
			if(mode == 0)
			{
			led1 = 1; led2 = 0; led3 = 0;
			table[0] = T_duan[shi/10%10];
			table[1] = T_duan[shi%10];
			table[2] = 0x40;
			table[3] = T_duan[fen/10%10];
			table[4] = T_duan[fen%10];
			table[5] = 0x40;
			table[6] = T_duan[miao/10%10];
			table[7] = T_duan[miao%10];		
			}
			else if(mode == 1)
			{
			led1 = 0; led2 = 1; led3 = 0;
			table[0] = 0x38;
			table[1] = 0x39;
			table[2] = 0x00;
			table[3] = 0x00;
			table[4] = 0x00;
			if( distance/100 == 0) table[5] = 0x00; else  table[5] = T_duan[distance/100%10];
			table[6] = T_duan[distance/10%10];
			table[7] = T_duan[distance%10];				
			}
			else
				{
					led1 = 0; led2 = 0; led3 = 1;
				if(jilu_mode == 0)
				{
				table[0] = 0x76;
				table[1] = 0x01;
				table[2] = T_duan[c/100%10];
				table[3] = T_duan[c/10%10];
				table[4] = 0x00;		
				if(max/100 == 0) table[5] = 0x00; else table[5] = T_duan[max/100%10];		
				if(max/10 == 0) table[6] = 0x00; else table[6] = T_duan[max/10%10];			
				table[7] = T_duan[max%10];	
				}
				else if(jilu_mode == 1)
				{
					table[0] = 0x76;
					table[1] = 0x40;
					table[2] = 0x00;
					table[3] = T_duan[test_i %10];
					if(AVG/1000 > 0) table[4] = T_duan[AVG/1000%10];		 else table[4] = 0x00;		
					if(AVG/100 > 0) table[5] = T_duan[AVG/100%10];		 else table[5] = 0x00;
					table[6] = T_duan[AVG/10%10]|0X80;			
					table[7] = T_duan[AVG%10];					
				}	
			else
			{
				table[0] = 0x76;
				table[1] = 0x08;
				table[2] = 0x00;
				table[3] = 0x00;
				table[4] = 0x00;		
				if(min/100 == 0) table[5] = 0x00; else table[5] = T_duan[min/100%10];		
				if(min/10 == 0) table[6] = 0x00; else table[6] = T_duan[min/10%10];			
				table[7] = T_duan[min%10];			
			}		
				}
	}
	//****************************************************************index_interface***************************************************
	else
	{
		
		if(mode%2 == 0)  //collect time index
		{
			table[0] = 0x73;
			table[1] = T_duan[1];
			table[2] = 0x00;
			table[3] = 0x00;
			table[4] = 0x00;		
			table[5] = 0x00;		
			table[6] = 0x00;			
			table[7] = T_duan[index_time[time_i]];	
		}
		else
		{
			table[0] = 0x73;
			table[1] = T_duan[2];
			table[2] = 0x00;
			table[3] = 0x00;
			table[4] = 0x00;		
			table[5] = 0x00;		
			table[6] = T_duan[index_distance/10%10];							
			table[7] = T_duan[index_distance%10];				
		}	
	}

	


	
}
u8 key_scan()
{
	u8 key = 99,key_return = 99;
	h1 = 1; h2 = 1; h3 = 1; h4 = 1;
	l1 = 0; l2 = 1; l3 = 1; l4 = 1;
	if(h3 != 1) key = 5;
	if(h4 != 1) key = 4;
	
	h1 = 1; h2 = 1; h3 = 1; h4 = 1;
	l1 = 1; l2 = 0; l3 = 1; l4 = 1;
	if(h3 != 1) key = 9;
	if(h4 != 1) key = 8;
	switch(key_state)
	{
		case 0: if(key!=99) key_state = 1; break;
		case 1: if(key==99) key_state = 0; else { key_state = 2; key_return = key; } break;
		case 2: if(key==99) key_state = 0; break;
	}
	return key_return;
}

void sendsonic()
{
	TX = 1;
	somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
	TX = 0;
	somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
	
}

void r_distance()
{
	u8 i = 0;
  for(i=0; i<8; i++)	
	{
		sendsonic();
	}
	TR0 = 1;
	while(TF0 != 1 && RX != 0);
	TR0 = 0;
	if(TF0 == 1)
	{
		TF0 = 0;
		TH0 = 0;
		TL0 = 0;
		distance = 80;
	}
	if(RX == 0)
	{
		distance = (TL0+TH0*256)*0.017;
		TH0 = 0;
		TL0 = 0;
	}
}

void disance_record()
{
	distance_test[test_i] = distance; test_i++; if(test_i==20) test_i = 0; if(distance>max && distance != 120) max = distance; if(distance<min && distance != 0) min = distance;

	AVG = 0;
	for (i=0;i<test_i;i++)   
	{
		AVG = (AVG+distance_test[i]);
	}
	  AVG = AVG*10/test_i;

}

void led_cmd()
{
	led(led1+led2*2+led3*4+led4*8+led5*16+led6*32);
}
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值