蓝桥杯单片机设计与开发题目分析与源码(智能门锁)

本文详细介绍了一款基于STC单片机的智能门锁项目,包括界面设计、数码管显示、矩阵键盘扫描、e2prom数据存储与初次上电检测。通过Keil5和Stc-isp开发环境,实现密码输入、错误提示及上电标志管理。适合学习者参考和交流改进意见。
摘要由CSDN通过智能技术生成

蓝桥杯单片机设计与开发(智障门锁)
内附完整工程 代码仅供参考,如有建议疑问欢迎留言讨论

程序设计部分
智能门锁—任务指导书


开发环境
Keil5
Stc-isp
国兴天长开发板

任务分析
任务逻辑梳理
不多赘述具体逻辑,我直接将我的流程图分享,各位可根据任务指导书梳理


界面设计
根据任务指导书可知,界面(数码管)共有四种:

默认状态
全部熄灭

输入状态


打开状态


修改状态

LED状态:

LED 1 ON
密码错误,点亮5s

LED 7 ON
输入状态,其他状态熄灭

LED 8 ON
修改状态,其他状态熄灭

LED OFF

键盘定义
矩阵键盘4*4 没啥好分析的看图就行

e2prom分析
初次上电检测
根据任务需求,需要设值一个掉电还能保存的标志,用于检测是否为第一次上电
思路:在e2prom中选择一个字节用于存储一个标志,设备启动时读取这个字节,判断该字节是否等于程序中的标志位。如果不是则为初次上电;如果相等则不是初次上电
密码存取
因为按照需求,密码为6位,所以可以连续选取六个连续字节存储谬码;
请参考英文使用手册:

参看CSDN文章:有关iic和at24读写详解(里面详细说了连续读写)
代码实现
首先根据日内瓦公约(毫无瓜西)
数码管的使用:
使用定时器刷新数码管
可以用stcisp一键生成定时器(定时器刷新时间建议500us,低了会影响刷新效果,高了会闪(自己把握))
/*    
    0-9
    10-0xff
    11-0xf7 _
    12-14 0x8c P
        0x86 E
        0xc8 n
    15 0xc6 C
*/
uchar code seg_table[]={0xc0,0xf9,0xa4,0xb0,0x99,
                        0x92,0x82,0xf8,0x80,0x90,
                        0xff,0xf7,0x8c,0x86,0xc8,0xc6};

uchar show_tab[]={10,10,10,10,10,10,10,10};    //显示缓冲区
void seg_show(uchar n)    //显示数字(n代表数码管的位)
{
    P0=0x00;
    Y6;
    P0=(0x01<<n);
    Y0;
    P0=0xff;
    Y7;
    P0=seg_table[show_tab[n]];
    Y0;
}
void Timer0Init(void)        //500微秒@11.0592MHz
{
    AUXR |= 0x80;        //定时器时钟1T模式
    TMOD &= 0xF0;        //设置定时器模式
    TL0 = 0x66;        //设置定时初始值
    TH0 = 0xEA;        //设置定时初始值
    TF0 = 0;        //清除TF0标志
    TR0 = 1;        //定时器0开始计时
    ET0=1;
    EA=1;
}
void Timer0() interrupt 1
{
    static int n=0;
    seg_show(n);    //循环显示
    n++;
    if(n==8)
        n=0;
}

键盘扫描
键值计算可以参考原理图,列三个3元1次方程组就能解决(解决不了的去小学吧)
/*********4*4键盘扫描***********
对应键值关系
1     2    3    4        S7    S11    S15    S19
5    6    7    8        S6    S10    S14    S18
9    10    11    12        S5    S9    S13    S17
13    14    15    16        S4    S8    S12    S16


***************************/
unsigned char key_scanf()
{
    uchar x=0,y=0;
    P30=0;P31=0;P32=0;P33=0;
    P34=1;P35=1;P42=1;P44=1;
    if(!(P34&P35&P42&P44))
    {
        Delay20us();        //消抖
        if(!(P34&P35&P42&P44))
        {
            if(!P34)
                x=4;
            if(!P35)
                x=3;
            if(!P42)
                x=2;
            if(!P44)
                x=1;
            P30=1;P31=1;P32=1;P33=1;
            P34=0;P35=0;P42=0;P44=0;
            if(!P30)
                y=1;
            if(!P31)
                y=2;
            if(!P32)
                y=3;
            if(!P33)
                y=4;
            while(!(P30&P31&P32&P33));
            return (x+4*y-4);    //计算键值
        }
    }
    return 0;
}

eeprom函数
#define FIRST_FLAG 0x14        //检测标志

void check_first()
{
    uchar temp=0;
    LED_OFF();                //关闭led

    temp=e2prom_read(0xf5);    //读取标志位内容

    if(temp==FIRST_FLAG)    //如果内容一致,则不是第一次上电
    {
        read_pas();            //读取存储的密码
        //测试部分
//        set_tab(10,10,cor_pas[0],cor_pas[1],cor_pas[2],cor_pas[3],cor_pas[4],cor_pas[5]);
//        while(1);
        return;
    }
    
    //首次上电
    write_pas(cor_pas);        //将密码存入
    Delay5ms();                //等待存储
    e2prom_write(0xf5,FIRST_FLAG);    //写入标志位
}

//读取一个字节
uchar e2prom_read(uchar addr)
{
    uchar dat;
    
    IIC_Start();
    IIC_SendByte(0xa0);
    IIC_WaitAck();
    IIC_SendByte(addr);
    IIC_WaitAck();
    IIC_Stop();
    
    IIC_Start();
    IIC_SendByte(0xa1);
    IIC_WaitAck();
    dat=IIC_RecByte();
    IIC_SendAck(0);
    IIC_Stop();
    
    return dat;
}

//写入一个字节
void e2prom_write(uchar addr,dat)
{
    IIC_Start();
    IIC_SendByte(0xa0);
    IIC_WaitAck();
    IIC_SendByte(addr);
    IIC_WaitAck();
    IIC_SendByte(dat);
    IIC_WaitAck();
    IIC_Stop();
}

//连续写入数组
void write_pas(uchar* tab)
{
    unsigned char i=0;
    IIC_Start();
    IIC_SendByte(0xa0);
    IIC_WaitAck();
    IIC_SendByte(0x10);
    IIC_WaitAck();
    for(;i<6;i++)
    {
        IIC_SendByte(tab[i]);
        IIC_WaitAck();
    }
    IIC_Stop();
}

//连续读出数组
void read_pas()
{
    unsigned char i=0;
    IIC_Start();
    IIC_SendByte(0xa0);
    IIC_WaitAck();
    IIC_SendByte(0x10);
    IIC_WaitAck();

    IIC_Start();
    IIC_SendByte(0xa1);
    IIC_WaitAck();
    cor_pas[0]=IIC_RecByte();
    for(;i<5;i++)
    {
        IIC_SendAck(0);
        cor_pas[i+1]=IIC_RecByte();
    }
    IIC_Stop();
}

主函数部分
不贴了,最后给出所有文件
所有资料
压缩包目录

demo_smartlock(项目工程)
AT24C02英文资料
AT24C02中文资料
hex文件
REDME
任务指导书
逻辑图
————————————————
版权声明:本文为CSDN博主「不知足额」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45698227/article/details/121807134

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值