蓝桥杯单片机竞赛考前注意事项
目录
2023年赛点资源包数据包下载地址:https://download.csdn.net/download/qq_25218501/87965408
蓝桥杯单片机赛点数据包模块文件使用的注意事项
蓝桥杯单片机竞赛主观题总结
蓝桥杯注意事项
准备事项
1. 携带准考证、身份证和考试用笔;
2. 提前30分钟入场,比赛开始30分钟后不得入场;
3. 考试期间有任何问题可联系监考老师;
4. 填空题提交后可以进行修改。在主界面的2个子卷部分,可以重新点击进入修改。
考前
1. 到考场后,立刻开机,敲框架代码,测试开发板。若有问题,及时调换考位和开发板。考试期间遇
到任何问题,请与监考老师联系。
2. 查看单片机资源数据包,打开烧录软件,插上比赛用板,检查能否识别端口;
3. 如果无法识别,打开单片机资源数据包中的USB驱动安装,完成后再次插入板子检查是否成功识
别;
4. 选择烧录软件中 Keil 仿真设置 的添加型号和头文件,鼠标悬停以查看安装步骤,通常安装在
C:\keil\C51 ;
5. 以题目要求(通常是准考证号,但也有可能是别的,按要求操作即可)新建项目,选择匹配的型
号。
6. 考场电脑最后一个盘没有写保护,注意备份。
答题时
1. 审题,默写框架
调整跳帽,根据题意选择晶振频率和键盘,定时器初始化的频率要匹配
常见问题:
1)定时器中断 ET0 和总中断 EA 未打开,会导致数码管不显示;
2)P2、P0敲错,可能导致数码管乱码、卡死等;
3)矩阵键盘未将 P42 和 P44 的值赋给 P36 和 P37 ,会导致矩阵键盘出错;
4)负责计数的 xxx_count 达到对应数值后未置 0 ,会导致定时出错,数码管不显示,按键无反应等;
5)负责计数的值的取值范围溢出,除非内存不够,否则可以尽量用 int 类型,减少变量溢出问题出现
的概率。
6)使用的标志位在执行过程中记得清零。
7)关于按键长按与短按的功能不要产生冲突。
8)测频率的P34引脚和NET_SIG引脚,不用时一定不要用跳帽短接,会影响键盘或者其他功能。超声波
的收发键帽要归位。
2. 测试题目所需基本模块
确保读取外设数据正确,否则后期添加模块出错时无法判断时逻辑出错还是驱动出错。
iic
1)读写EEPROM的代码(需要记忆)
void write_24C02(unsigned char add,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char read_24C02(unsigned char add)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp;
}
2)读取RB2或光敏电压
add=1时为光敏,add=3时RB2;若两者都要读,则要交换add的值或者对同一个值读取两次以确保数据正确
unsigned char AD_Get(unsigned char add)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp;
}
3)DA电压输出
dat取值0—255,对应0—5V
电压输出有时会干扰AD读取,其中一种解决方法是在读取之前关中断,然后开中断。
void DAC_out(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
DS1302
读写实时时钟:以下代码无需修改原始驱动,传入参数为一个Time[]数组,Time[0]为秒,Time[1]为分,Time[2]为时
void setTime(unsigned char Time[])
{
Write_Ds1302_Byte(0x8e, 0);
Write_Ds1302_Byte(0x80, Time[0] / 10 * 16 + Time[0] % 10);
Write_Ds1302_Byte(0x82, Time[1] / 10 * 16 + Time[1] % 10);
Write_Ds1302_Byte(0x84, Time[2] / 10 * 16 + Time[2] % 10);
Write_Ds1302_Byte(0x8e, 0x80);
}
void getTime(unsigned char Time[])
{
unsigned char bcd;
bcd = Read_Ds1302_Byte(0x81);
Time[0] = (bcd >> 4 & 0x07) * 10 + (bcd & 0x0f);
bcd = Read_Ds1302_Byte(0x83);
Time[1] = (bcd >> 4 & 0x07) * 10 + (bcd & 0x0f);
bcd = Read_Ds1302_Byte(0x85);
Time[2] = (bcd >> 4 & 0x07) * 10 + (bcd & 0x0f);
}
onewire(需要修改源代码)
读取温度:获取的数据乘上0.0625为实际温度,可再如果需要保留n位小数,再乘上10的n次方
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t*=10; //iap15比传统51快8~12倍,因此此处延迟函数需要修改
while(t--);
}
int DS18B20_Get()
{
int low,high;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
high=Read_DS18B20();
return high<<8|low;
}
超声波:
#include <STC15F2K60S2.h>
#include <intrins.h>
#define somenop
{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();}
sbit TX = P1 ^ 0; //发射引脚
sbit RX = P1 ^ 1; //接收引脚
void send_wave()
{
unsigned char i = 8; //发送8个脉冲
do
{
TX = 1;
somenop;somenop;somenop;somenop;somenop;
somenop;somenop;somenop;somenop;somenop;
TX = 0;
somenop;somenop;somenop;somenop;somenop;
somenop;somenop;somenop;somenop;somenop;
} while (i--);
}
unsigned int get_distance()
{
send_wave(); //发送方波信号
TH0 = 0;
TL0 = 0;
TR0 = 1; //启动计时
while (RX && !TF0);//等待收到脉冲
TR0 = 0; //关闭计时
if (TF0)
{
TF0 = 0;
return 99;
}
else
{
return (TH0 * 256 + TL0) * 0.017;
}
}
串口
使用时记得打开串口中断,ES=1
//串口中断服务函数
void isr_uart(void) interrupt 4
{
if (RI)
{
RI = 0; //清除接收标志位
rx = SBUF;
if(判断rx的值)
{
//相关处理
}
}
}
//通过串口发送字符串
void uart_sendstring(unsigned char *str)
{
while (*str != '\0')
{
SBUF = *str++;
while (TI == 0); //等待发送标志位置位
TI = 0;
}
}
3. 实现题目所需逻辑功能
1)如果LED灯的功能较为复杂,建议使用一个unsigned char类型变量LED进行状态存储。可以用位运算,对每个LED进行判断,例如
void set_led()
{
if(/*L1亮的条件*/)
LED=LED|0x01;//L1亮
else
LED=LED&(~0x01);
if(/*L3亮的条件*/)
LED=LED|0x04;//L3亮
else
LED=LED&(~0x04);
P2=0x80;P0=~LED;P2=0x00;
//如何LED出现残影,要把这个函数定时5-10ms运行一次,可以和键盘读取放在一起
}
2)char范围是 -128~127 ,unsigned char范围是 0~255 ,int范围是 -32768~32767 ,unsigned int范
围是 0~65535 ,因此如果和0比较的话,要用带符号型的数据进行比较,同时注意溢出问题
3)蜂鸣器和继电器要一起操作,防止互相产生干扰;
4)读写取外设时需要增加间隔时间,连续存储EEPROM之间插入Delay10ms(),防止下一次的操作打断
上一次的操作,产生未知错误。
如果还不行,读写之前要关中断,读写完再开中断。
5)EEPROM 一个单元只能存储8位数据,注意溢出;
6)涉及到EEPROM的上电初始值问题,建议随机取一个无用的EEPROM地址判断其值是否为自己定义的
数 x ,如果不是则将 x 的值写入此地址,并将相应的初始化值写入相应的地址;
7)如果有不会或不熟悉的模块,可以查看资料包中的芯片手册,可能有助于回忆。
8)涉及长按键短按键时,可以用一个key_up标志位来判断按键是否弹起,在另设press_xx标志位判断短
按键,并在中断中判断长按键,以此实现长短按键冲突的消除。
void key_fuction()
{
if(cont==0)
key_up=1;
if(trg==0x28) //S12
{
key_up=0;
press_12=1;
}
if(trg==0x24) //S13
{
key_up=0;
press_13=1;
}
if(press_12&&key_up) //s12作短按键时
{
...
press_12=0;
}
if(press_13&&key_up) //s13作短按键时
{
...
press_13=0;
}
}
void time0() interrupt 1
{
static int p=0,q=0;
...
if(press_12&&!key_up) s12作长按键时
{
if(++p>=1000)
{
...
press_12=0;
p=0;
}
}
else
p=0;
if(press_13&&!key_up) //s13作长按键时
{
if(++q>=1000)
{
...
press_13=0;
q=0;
}
}
else
q=0;
}
9) 关于温度DS18B20上电显示85度的问题
在进while(1)循环前加入判断: while(DS18B20_Get()*0.0625==85); 即可。
10)频率的测量问题
原理:将定时器0设置为计数器模式,每当P34收到一个脉冲,计数器加一。再设置一个定时器,定时1s读取计数器的值,即可完成测量。
方法1:定时器0设为16位 TMOD |=0x05; ,计算频率时不需要先TR0=0; 再TR0=1;
方法2:定时器0设为16位自动重装载 TMOD |=0x04; ,需要先TR0=0; 再TR0=1;
11)在使用2022版新驱动时,需要将 .h 文件中的 定义及引用 剪切 回 .c 文件中(不建议直接把
reg52.h > 改为< stc15f2k60s2.h >,因为这样修改 ds1302.h 与 IIC.h 仍会有重复定义的问题出现)
答题结束后
提交时,注意文件名要求以什么命名(准考证号还是身份证号还是.......),另外还要注意提交的是hex,还是所有是压缩包。
检查项目名,从头开始依次检查所有功能,逐字逐句,不要跳着看,防止有所疏漏!
更多推荐
所有评论(0)