突击蓝桥杯嵌入式(七)——第十三届省赛第一场真题

一、题目概览






二、思路梳理

我们直接在LCD例程的基础上,改需增加的外设如下:

LED灯(配置锁存器PD2),串口(波特率9600,带中断),按键4个,PWM输出。

题目较为简单,其逻辑部分如下:

上电之后,板子初始化,LCD显示为@@@,默认密码为123,PWM脉冲输出1KHZ的方波信号,然后开启串口接收中断(7个数据进入中断),然后中断里对于字符串进行处理,利用ssanf分离出输入的初始密码和新密码,然后对比密码是否正确,如果错误,则不改变原有密码值。

然后按键扫描部分:

按下B1B2B3分别对应密码的123位,其变化规律为0-9-0-9,然后B4确认,如果密码正确,LED1点亮五秒然后熄灭,LCD显示输出界面5s,且PWM输出2KHZ,占空比为百分之10的方波,之后显示三个@@@!!!如果错误,累计次数,超过两次,LED2以0.1s为间隔闪烁,持续五秒。

三、代码

uint8_t str[21];uint8_t LCD_flag = 2;
/******************
LCD分为三个界面,分别为
复位页面(三个@@@)2
密码界面(主页面)0
数据页面(显示频率和占空比)1
******************/
int passward[3];    //现在输入的密码
uint8_t real_passward[3];   //真正的密码
uint8_t rx_passward[3];     //串口接收到的密码
uint8_t count;              //
uint8_t right_flag;         //密码正确标志
uint8_t count_led=0;       //led计数器
uint8_t shock_flag=0;      //led闪烁标志位
uint8_t shock;              //闪烁种的led亮灭标志
uint8_t count_LCD;          //数据页面LCD只能持续5s,所以用一个count计数uint8_t key_value;           //三行代码消抖,没啥好说的
uint8_t key_down;
uint8_t key_up;
uint8_t key_old;
uint8_t rx_buff[7];         //串口接收的消息__IO uint32_t uwTickLCD_Speed; //滴答定时器参量,没啥好说的
__IO uint32_t uwTickKey_Speed;
__IO uint32_t uwTickLED_Speed;

LED灯

void LED_Disp(uint8_t ucled)
{HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15,GPIO_PIN_SET);//灭灯HAL_GPIO_WritePin(GPIOC,ucled<<8,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);}
void LED_Proc()
{if(uwTick - uwTickLED_Speed < 100) return;else uwTickLED_Speed = uwTick;if(count_led<=50&&count_led>0)      //如果触发了闪烁5s或亮5s的标志{if(shock_flag==1)  //若是闪烁标志{if(shock==1) //led2闪烁5s{LED_Disp(0x02);shock^=1;}else if(shock==0){LED_Disp(0x00);shock^=1;}count_led--; //每100ms 标志位-1}else             //当不是闪烁标志{LED_Disp(0x01);   count_led--;}}else if(count_led == 0){    //当计数位为0,也就是过了五秒时候,关闭所有LED和标志位LED_Disp(0x00);shock_flag=0;}
}

LCD

void LCD_main_Dis()          //主页面,显示密码
{sprintf((char *)str,"        PSD          ");LCD_DisplayStringLine(Line1,(uint8_t *)str);if(passward[0] == -1){sprintf((char *)str,"     B1:@            ");LCD_DisplayStringLine(Line3,(uint8_t *)str);}else{sprintf((char *)str,"     B1:%d            ",passward[0]);LCD_DisplayStringLine(Line3,(uint8_t *)str);}if(passward[1] == -1){sprintf((char *)str,"     B2:@            ");LCD_DisplayStringLine(Line4,(uint8_t *)str);}else{sprintf((char *)str,"     B2:%d            ",passward[1]);LCD_DisplayStringLine(Line4,(uint8_t *)str);}if(passward[2] == -1){sprintf((char *)str,"     B3:@            ");LCD_DisplayStringLine(Line5,(uint8_t *)str);}else{sprintf((char *)str,"     B3:%d            ",passward[2]);LCD_DisplayStringLine(Line5,(uint8_t *)str);}
}void LCD_data_Dis()            //数据页面,密码正确时候显示
{sprintf((char *)str,"        STA          ");LCD_DisplayStringLine(Line2,(uint8_t *)str);sprintf((char *)str,"     F:2000HZ            ");LCD_DisplayStringLine(Line4,(uint8_t *)str);sprintf((char *)str,"     D:10%%            ");LCD_DisplayStringLine(Line5,(uint8_t *)str);sprintf((char *)str,"                      ");LCD_DisplayStringLine(Line6,(uint8_t *)str);
}void LCD_Proc()
{if(uwTick - uwTickLCD_Speed < 100) return;else uwTickLCD_Speed = uwTick;if(LCD_flag == 0){LCD_main_Dis();}if(LCD_flag == 1)    //如果密码正确,进入数据页面5s{LCD_data_Dis();count_LCD++;      //100ms +1TIM2->ARR = 500; //改变频率和占空比TIM2->CCR2 = 50;if(count_LCD==50){  //当过了5scount_LCD =0;   //返回主页面,清除LCD计数LCD_flag = 2;TIM2->ARR = 1000;   //复原占空比TIM2->CCR2 = 500;}if(LCD_flag == 2)    {passward[0]=-1;passward[1]=-1;passward[2]=-1;}
}

Key按键

uint8_t Key_Scan()   //扫描哪个键让按下去
{static uint8_t value;if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == GPIO_PIN_RESET){value = 1;}   else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){value = 2;}else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == GPIO_PIN_RESET){value = 3;}else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET){value = 4;}else{value = 0;}return value;
}void Key_Proc()
{if(uwTick - uwTickKey_Speed < 100) return;else uwTickKey_Speed = uwTick;key_value = Key_Scan();key_down = key_value&(key_value^key_old);key_up = ~key_value&(key_value^key_old);key_old = key_value;switch(key_down){case 1:passward[0]++;if(passward[0]>9){passward[0] = 0;}LCD_flag = 0;break;            case 2:passward[1]++;if(passward[1]>9){passward[1] = 0;}LCD_flag = 0;break;case 3:passward[2]++;if(passward[2]>9){passward[2] = 0;}LCD_flag = 0;break;case 4:right_flag = check_passward();if(right_flag){count=0;count_led=50;LCD_flag = 1;passward[0]=-1;passward[1]=-1;passward[2]=-1;}break;}
}uint8_t check_passward()   //检查密码是否正确,正确就返回1,错误就计数,三次之后置1闪烁标志位
{if((passward[0] == real_passward[0])&&(passward[1] == real_passward[1])&&(passward[2] == real_passward[2])){count=0;return 1;}else{count++;if(count>2){shock_flag=1;count_led=50;}return 0;}
}

串口

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{static uint8_t cofirm_passward[3];static uint8_t re_passward[3];   //sscanf从rx_buff读取密码,如果输入的旧密码正确,将修改的密码覆盖原来的密码sscanf((char *)rx_buff,"%1d%1d%1d-%1d%1d%1d",&cofirm_passward[0],&cofirm_passward[1],&cofirm_passward[2],&re_passward[0],&re_passward[1],&re_passward[2]);LCD_DisplayStringLine(Line8,(uint8_t *)str);if((cofirm_passward[0]==real_passward[0])&&(cofirm_passward[1]==real_passward[1])&&(cofirm_passward[2]==real_passward[2])){for(int k=0;k<3;k++){real_passward[k] = re_passward[k];}}HAL_UART_Receive_IT(&huart1,rx_buff,7);
}

主函数,主要是一些初始化

 HAL_TIM_PWM_Init(&htim2);               //一些初始化,没啥好说的HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);LCD_Init();LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);LED_Disp(0X00);real_passward[0] = 1;real_passward[1] = 2;real_passward[2] = 3;HAL_UART_Receive_IT(&huart1,rx_buff,7);while (1){LCD_Proc();Key_Proc();LED_Proc();}

突击蓝桥杯嵌入式(七)——第十三届省赛第一场真题相关推荐

  1. 突击蓝桥杯嵌入式(十二)——第十二届省赛第一场真题 停车场

    突击蓝桥杯嵌入式(十二)--第十二届省赛第一场真题 停车场 一.题干 二.题目解析 所需: PA7 PWM LED(锁存器) 串口9600 LCD 按键4个,整体难在逻辑,我们先配置好硬件,进入工程 ...

  2. 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式国赛程序设计试题以及详细题解

    文章目录 原题展示 原题分析 详细题解 LED模块 按键模块 串口 LCD模块 模拟电压读取(ADC) 脉冲输入输出 文章福利 原题展示 原题分析   本届国赛试题主要包含LCD.LED.按键.EEP ...

  3. 【蓝桥杯嵌入式】第六届省赛程序题项目代码及讲解

    文章目录 蓝桥杯嵌入式第六届省赛 介绍 配置 RTC配置 配置ADC 配置串口: LED和按键的配置 E2PROM 头文件 初始化 串口测试 LCD测试 RTC测试 ADC测试 按键和LED测试 E2 ...

  4. 第八届蓝桥杯(软件类)C++省赛A组真题题解

    文章目录 题目链接 A组真题 题目结构 第一题 迷宫 第二题 跳蚱蜢 第三题 魔方状态 第四题 方格分割 第五题 字母组串 第六题 最大公共子串 第七题 正则问题 第八题 包子凑数 第九题 分巧克力 ...

  5. 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式国赛客观题以及详细题解

    题1 概念题. USRAT:异步串口通信,常用于数据传输: SW-DP:SWD 的全称应该是 The Serial Wire Debug Port (SW-DP),也就是串行调试端口,是 ARM 目前 ...

  6. 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式省赛(第二场)程序设计试题及其题解

    原题展示

  7. 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式省赛客观题以及详细题解

    题1 题解:   概念题. MCO引脚,是单片机对外提供时钟的引脚. HSE,高速外部时钟信号,时钟源由外部晶体/陶瓷谐振器与外部时钟: HSI,高速的内部时钟,由内部8MHz的RC振荡器产生,可直接 ...

  8. 蓝桥杯2022年第十三届省赛真题-纸张尺寸

    题目描述 在 ISO 国际标准中定义了 A0 纸张的大小为 1189mm × 841mm,将 A0 纸沿长边对折后为 A1 纸,大小为 841mm × 594mm,在对折的过程中长度直接取下整(实际裁 ...

  9. 蓝桥杯题目 2682: 蓝桥杯2022年第十三届省赛真题-GCD

    题目描述 给定两个不同的正整数 a, b,求一个正整数 k 使得 gcd(a + k, b + k) 尽可能大,其中 gcd(a, b) 表示 a 和 b 的最大公约数,如果存在多个 k,请输出所有满 ...

最新文章

  1. 中国最大AI预训练模型发布:113亿参数!北京智源研究院、阿里、清华等联手打造...
  2. JQueryEasyUI学习笔记(十四)tree
  3. css3让元素自适应高度
  4. 使用DOM解析常用方法
  5. MySQL 中存储时间的最佳实践
  6. codeblock下载
  7. 数据中心UPS维护和使用十大注意事项
  8. 魅族16s Pro细节曝光:骁龙855plus 未上Flyme 8
  9. linux故障模式,Linux操作系统出现严重故障后的救援模式
  10. 再回首,Java温故知新(六):Java基础之变量
  11. P2422 良好的感觉
  12. 呼和浩特市啥时计算机考试,2021上半年内蒙古自治区呼和浩特市全国计算机等级考试时间...
  13. 2020德勤面试开始了吗_四大面试-德勤面试流程免费给你,还不收好?截止2020年9月...
  14. Java OpenCV 裁剪图片
  15. CentOS解决nginx autoindex 截断文件名,末尾出现乱码
  16. uclinux开发概述
  17. 南方地区数据中心节能架构设计——以深圳地区为例
  18. 可穿戴式设备之智能手环
  19. xoy面上两直线交点算法
  20. MS10-073微软Windows内核Win32k.sys键盘布局本地提权漏洞 fix poc

热门文章

  1. el-table 表头固定
  2. 北京内推 | 微软亚洲互联网工程院NLP Science组招聘NLP研究实习生
  3. 国美通报员工上班摸鱼,企业监控员工上网情况违法吗?
  4. 张益唐的朗道-西格尔零点猜想的论文公布,专家认为该论文尚未完整解决零点猜想
  5. 紫越移动校园建设方案
  6. 企业股权融资应关注的十个要点(下篇)
  7. 辞职有道:最合适的辞职方式
  8. 银河麒麟操作系统日常测试
  9. dnf服务器未响应win7,win7dnf登录黑屏未响应|win7系统未响应黑屏的解决方法
  10. linux下声音调节