目录

蓝桥杯注意事项

准备事项

考前

答题时

1. 审题,默写框架

2. 测试题目所需基本模块

iic

1)读写EEPROM的代码(需要记忆)

2)读取RB2或光敏电压

3)DA电压输出

DS1302

onewire(需要修改源代码)

超声波:

串口

3. 实现题目所需逻辑功能

答题结束后


2023年赛点资源包数据包下载地址:https://download.csdn.net/download/qq_25218501/87965408

蓝桥杯单片机赛点数据包模块文件使用的注意事项

蓝桥杯单片机赛点数据包模块文件使用的注意事项_竹烟淮雨的博客-CSDN博客

蓝桥杯单片机竞赛主观题总结

蓝桥杯单片机竞赛主观题总结(全)(2.5W字)_竹烟淮雨的博客-CSDN博客

蓝桥杯注意事项


准备事项


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,还是所有是压缩包。

检查项目名,从头开始依次检查所有功能,逐字逐句,不要跳着看,防止有所疏漏!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐