蓝桥杯嵌入式备赛相关知识点

2024-04-03 06:20

本文主要是介绍蓝桥杯嵌入式备赛相关知识点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、介绍

​ 蓝桥杯嵌入式使用的单片机是STM32G431RBT6,内核ARM Cortex - M4,MCU+FPU,170MHz/213DMIPS,高达128KB Flash,32KB SRAM,其余的外设就不多介绍了,参照数据芯片数据手册

​ CT117E-M4开发板资源:微控制器STM32G431RBT6、一路USB转串口、2.4寸TFT-LCD、4个功能按键、1个复位按键、8个LED、一个E2PROM(AT24C02)、一个可编程电阻(100K)、2路信号发生器、2个分压电位器、2个扩展接口、一个CMSIS DAP Link调试器

二、初始化Cubemx

1.新建工程

2.下载程序引脚配置

3.启用外部晶振,时钟配置

4.生成工程

如果工程路径不是纯英文则会缺少启动文件

三、下载程序配置

1.LED

1.1 原理图

1.2 引脚配置

其中PD2高电平使能锁存器,PC8-15默认给高电平,放置上电初始化LED亮

1.3 添加库文件夹路径,并新建LED库文件

1.4 相关代码

LED.c

#include "led.h"void LED_Disp(uchar dsLED)
{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); // 所有PC引脚置高HAL_GPIO_WritePin(GPIOC,dsLED<<8,GPIO_PIN_RESET); // 将传入的dsLED位数置低,为了使对应的LED亮HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); // 锁存器置高使能,记住PC的引脚电平HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); // 锁存器置地,锁住PC的引脚电平
}

LED.h

#ifndef _LED_H_
#define _LED_H_#include "main.h"
void LED_Disp(uchar dsLED);#endif
1.5 头文件添加

1.6 工程调试

2.LCD

2.1 原理图

2.2 将比赛提供的液晶显示工程复制到自己工程文件中

2.3 引脚配置

2.4 工程配置

2.5 工程调试

3.按键

3.1 原理图

3.2 引脚配置
3.3 定时器配置

这里按键选择按下触发定时器进入中断 所以需要配置定时器

使用定时器4(通用定时器,使用外部晶振),分频系数为80(从0开始则为80-1),则每1s
1M次,定时评率为为10000,对应1s 1M/10000次,频率为10ms每次,一定记得开启NVIC使能中断

3.4 相关代码

interrupt.c

#include "interrupt.h"
#include "stdio.h"struct keys key[4] = {0,0,0,0,0};void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//中断回调函数
{if(htim->Instance == TIM4)//判断是否来自于定时器4{key[0].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);key[1].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].key_status = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);for(int i=0;i<4;i++){switch(key[i].judge_status){case 0:if(key[i].key_status == 0){key[i].judge_status = 1;key[i].key_time = 0;}break;case 1:if(key[i].key_status == 0){key[i].judge_status = 2;}else{key[i].judge_status = 0;}break;case 2:if(key[i].key_status == 1){key[i].judge_status = 0;if(key[i].key_time < 70){key[i].key_flag = 1;key[i].key_longflag = 0;}else{key[i].key_time++;if(key[i].key_time > 70){key[i].key_longflag = 1;key[i].key_flag = 0;}}}break;}}}
}

interrupt.h

#ifndef __INTERRUPT_H_
#define __INTERRUPT_H_#include "stdbool.h"
#include "main.h"struct keys
{uint8_t judge_status;bool key_flag;bool key_status;bool key_longflag;uint8_t key_time;
};void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);#endif
3.5 工程调试

在interrupt.h定义的结构体须在main.c中用extern再次声明

4.pwm

4.1 pwm输出引脚配置

配置PA6、PA7为输出引脚

频率fre=80 000 000 / (PSC+1)/ (ARR+1)

占空比duty=CRR / ARR

4.2 输入捕获引脚配置

原理图

根据题目需求设置捕获引脚即可 第一个一般是模拟输出频率 第二个则是模拟输出电压 R37~R40分别对应硬件板上的四个旋钮

相关配置

选用PB4, PA15为定时器通道CH1
配置预分频,重装载值(设为最大,防止溢出),启用中断

4.3 相关代码

interrupt.c

#include "interrupt.h"unsigned int Cnta1 = 0,Cnta2 = 0;
unsigned int fre1 = 0,fre2 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2)//获取频率{Cnta1 = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);//得到计时值__HAL_TIM_SetCounter(htim,0);//计时值清0fre1 = (80000000/80)/Cnta1;//获得频率HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);//打开定时器}if(htim->Instance == TIM3){Cnta2 = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);__HAL_TIM_SetCounter(htim,0);fre2 = (80000000/80)/Cnta2;HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);}
}

interrupt.h

#ifndef __INTERRUPT_H_
#define __INTERRUPT_H_#include "main.h"void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);#endif
4.4 工程调试

通过选择R39、R40即可调动频率值

5.ADC

5.1 原理图

5.2 引脚配置

5.3 相关代码

adc1.c

#include "adc1.h"double getADC(ADC_HandleTypeDef *pin)
{unsigned int adc;HAL_ADC_Start(pin);adc = HAL_ADC_GetValue(pin);return adc*3.3/4096;
}

adc1.h

#ifndef __ADC1_H_
#define __ADC1_H_#include "main.h"double getADC(ADC_HandleTypeDef *pin);#endif
5.4 工程调试

通过旋转R37~R38即可调动模拟输出电压

6.I2C

6.1 原理图及芯片资料

芯片资料中前面的nK就是芯片大小 我们只需要看第一行即可 第一行中前面四位固定是1010 后面的A0、A1、A2分别对应原理图中的E1、E2、E3 原理图中E1、E2、E3分别接地 所以在设置地址时设置0即可 最后的R/W位即用来配置是读或者写 0则为写入 1为读取 这对后续配置I2C相关工程有很大关系

6.2 引脚i配置

简单的使能PB6、PB7的引脚为输出模式即可

6.3 将比赛提供库函数移植到自己工程文件中

6.4 相关代码

在复制过来的工程I2C-hal.c底部编写以下函数

unsigned char I2C_Read(unsigned char addr)
{unsigned char data;I2CStart();I2CSendByte(0xa0);//0是写 1是读I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0xa1);I2CWaitAck();data = I2CReceiveByte();I2CSendAck();I2CStop();return data;
}void I2C_Write(unsigned char addr,unsigned char data)
{I2CStart();I2CSendByte(0xa0);//0是写 1是读I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CSendByte(data);I2CWaitAck();I2CStop();
}

头文件中定义

unsigned char I2C_Read(unsigned char addr);
void I2C_Write(unsigned char addr,unsigned char data);
6.5 工程调试

将上面的频率值分别的高八位和低八位分别写入I2C的指定地址 再将其读取

7.UART

7.1 引脚配置

波特率根据题目设定 一般为9600 同时需要开启中断

7.2 相关代码
//发送字符测试
char temp[20];串口调试
sprintf(temp,"fre1 = %d\r\n",fre1);
HAL_UART_Transmit(&huart1,(uint8_t *)temp,strlen(temp),50);//接收字符函数
char rx_Alldata[30];
uint8_t rx_data;
unsigned char rx_pointer;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{rx_Alldata[rx_pointer++] = rx_data;HAL_UART_Receive_IT(&huart1,&rx_data,1);
}
7.3 工程调试
void uart_rx_process()
{if(rx_pointer>0){if(rx_pointer == 22){sscanf(rx_Alldata,"%4s:%4s:%12s",car_type,car_data,car_time);}else{char temp[20];sprintf(temp,"Error");HAL_UART_Transmit(&huart1,(uint8_t *)temp,strlen(temp),50);}rx_pointer = 0;memset(rx_Alldata,0,30);}
}

须在头文件中包含string,h 

8.RTC

8.1 引脚配置

8.2 相关代码
RTC_TimeTypeDef rtc_time;
RTC_DateTypeDef rtc_date;void RTC_Rorcess()
{HAL_RTC_GetTime(&hrtc,&rtc_time,RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc,&rtc_date,RTC_FORMAT_BIN);
}
8.3 工程调试
char text[20];
sprintf(text, "%02d-%02d-%02d",rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);
LCD_DisplayStringLine(Line7, (uint8_t *)text);
sprintf(text, "%04d-%02d-%02d-%d",rtc_date.Year ,rtc_date.Month,rtc_date.Date,rtc_date.WeekDay );
LCD_DisplayStringLine(Line8, (uint8_t *)text

这篇关于蓝桥杯嵌入式备赛相关知识点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/872131

相关文章

JavaScript Array.from及其相关用法详解(示例演示)

《JavaScriptArray.from及其相关用法详解(示例演示)》Array.from方法是ES6引入的一个静态方法,用于从类数组对象或可迭代对象创建一个新的数组实例,本文将详细介绍Array... 目录一、Array.from 方法概述1. 方法介绍2. 示例演示二、结合实际场景的使用1. 初始化二

前端知识点之Javascript选择输入框confirm用法

《前端知识点之Javascript选择输入框confirm用法》:本文主要介绍JavaScript中的confirm方法的基本用法、功能特点、注意事项及常见用途,文中通过代码介绍的非常详细,对大家... 目录1. 基本用法2. 功能特点①阻塞行为:confirm 对话框会阻塞脚本的执行,直到用户作出选择。②

Redis的Zset类型及相关命令详细讲解

《Redis的Zset类型及相关命令详细讲解》:本文主要介绍Redis的Zset类型及相关命令的相关资料,有序集合Zset是一种Redis数据结构,它类似于集合Set,但每个元素都有一个关联的分数... 目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZ

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

关于Maven生命周期相关命令演示

《关于Maven生命周期相关命令演示》Maven的生命周期分为Clean、Default和Site三个主要阶段,每个阶段包含多个关键步骤,如清理、编译、测试、打包等,通过执行相应的Maven命令,可以... 目录1. Maven 生命周期概述1.1 Clean Lifecycle1.2 Default Li

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

Redis的Hash类型及相关命令小结

《Redis的Hash类型及相关命令小结》edisHash是一种数据结构,用于存储字段和值的映射关系,本文就来介绍一下Redis的Hash类型及相关命令小结,具有一定的参考价值,感兴趣的可以了解一下... 目录HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSET

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设