尽量不用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届及以后仅有程序和客观题 所以说程序题要难些
也有人说 第十届省赛难度 = 第七届国赛