2020蓝桥杯省赛单片机2

尽量不用XBYTE[]写法

XBYE写法由于暂时不了解其内部工作原理,在国信长天2020版本的51板子上 P42 P44与按键相连。如果用XBYTE数码管显示虽然方便但如果在中断中有矩阵键盘写法的按键扫描,使P42 P44强制拉低或拉高 会出现乱七八糟的的不可预判的BUG,如数码管不可显示 矩阵键盘失效。
推荐直接用P端口写法,在架构处列出

尽量不用三行按键扫描

三行按键扫描这种大佬级的玩意,发明的人固然两个字 NB 但如果P3其他端口有PWM(特别是P34 专门空出来接排针) 这个三行按键扫描就是一个BUG 里面的trg 和 cont值就不是可以预判的了,推荐使用国信长天的矩阵键盘程序,超好用
三行按键扫描:

//PINB是某个端口 

unsigned char Trg = 0;
unsigned char Cont = 0;
void KeyRead(void)
{
    unsigned char ReadData = PINB^0xff;   // 1
    Trg = ReadData & (ReadData ^ Cont);   // 2用于判断触发,长按的话也只出现一次 
    Cont = ReadData;                      // 3长按键 
}

定时器优先级问题

串口>PWM>数码管显示(数码管显示最低)

规范命名,代码间隔等写法

与时代接轨,与其他面向对象编程语言接轨
函数:小写_小写_小写()
如: void oled_show(void);

变量:小写直接组合起来
如:timebuff[0]

#define:全部大写
如:#define CHWEI(); P2 &= 0x1f; P2 |= 0xbf;
当然单词太长了可以简写

蓝桥杯省赛一般架构

#include "headfile.h"


#define CHWEI();      P2 &= 0x1f; P2 |= 0xc0;
#define CHDUAN();     P2 &= 0x1f; P2 |= 0xe0;
#define CHLED();      P2 &= 0x1f; P2 |= 0x80;
#define CH0();        P2 &= 0x1f;


void main(void)
{
	初始化关闭蜂鸣器和LED灯
	初始化定时器(谁重要谁先开)
	while (1)
	{
		if (keyval == xxxx)
		{
			while (keyval == xxxx);			
			xxxxxxxxxxxx
		}
		else if (keyval == xxxx)
		{
			while (keyval == xxxx);
			xxxxxxxxxxxx
		}
	}
}


void isrt_imer0(void)
{
	if (!(ms%5)) key_scan();
	if (flag == 1) time_show();
	else if (flag == 2) temp_show();
	else off_show();
}

void temp_show(void)
{
	static uchar i = 0;
	
	CHDUAN();
	P0 = 0xff;
	CHWEI();
	P0 = (0x01 << i);
	CHDUAN();
	P0 = tempbuff[i];
	CH0();
	if (++i > 7) i = 0;
}

void read_keyboard(void)
{
    static unsigned char hang;
	static unsigned char key_state=0;	
	switch(key_state)
	{
		case 0:
		{
			P3 = 0x0f; P42 = 0; P44 = 0;
			if(P3 != 0x0f) //有按键按下
			key_state=1;	
		}break;
		case 1:
		{
			P3 = 0x0f; P42 = 0; P44 = 0;
			if(P3 != 0x0f) //有按键按下
			{
				if(P30 == 0)hang = 1;
				if(P31 == 0)hang = 2;
				if(P32 == 0)hang = 3;
				if(P33 == 0)hang = 4;//确定行	    
				switch(hang){
					case 1:{P3 = 0xf0; P42 = 1; P44 = 1;
						if(P44 == 0) {key_value=0;key_state=2;}
						else if(P42 == 0) {key_value=1;key_state=2;}
						else if(P35 == 0) {key_value=2;key_state=2;}
						else if(P34 == 0) {key_value=3;key_state=2;}
					}break;
					case 2:{P3 = 0xf0; P42 = 1; P44 = 1;
						if(P44 == 0) {key_value=4;key_state=2;}
						else if(P42 == 0) {key_value=5;key_state=2;}
						else if(P35 == 0) {key_value=6;key_state=2;}
						else if(P34 == 0) {key_value=7;key_state=2;}
					}break;
					case 3:{P3 = 0xf0; P42 = 1; P44 = 1;
						if(P44 == 0) {key_value=8;key_state=2;}
						else if(P42 == 0) {key_value=9;key_state=2;}
						else if(P35 == 0) {key_value=10;key_state=2;}
						else if(P34 == 0) {key_value=11;key_state=2;}
					}break;
					case 4:{P3 = 0xf0; P42 = 1; P44 = 1;
						if(P44 == 0) {key_value=12;key_state=2;}
						else if(P42 == 0) {key_value=13;key_state=2;}
						else if(P35 == 0) {key_value=14;key_state=2;}
						else if(P34 == 0) {key_value=15;key_state=2;}
					}break;
				}	
			}
			else
			{
				key_state=0;	
			}  	   
		}break;
		case 2:     
		{
			P3 = 0x0f; P42 = 0; P44 = 0;
			if(P3 == 0x0f) //按键放开
			key_state=0;	
		}break;
						
    } 
}

官方给的代码的坑

①读写EEPROM记得完成一次加点delay
②DS18B20单总线延迟那个函数要在while 里面写个
for (i = 0; i < 12; i++)
③从STC_ISP复制的定时器代码 要注意晶振大小和 记得加!!!

ET0 = 1;	//开定时器0中断
IE2 |= 0x04;	//开定时器2中断
EA = 1;		//开总中断

蓝桥杯历史

1-7届省赛中有客观题、AD画图、程序题 部分,所以说程序部分比较简单
8届及以后仅有程序和客观题 所以说程序题要难些
也有人说 第十届省赛难度 = 第七届国赛

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值