蓝桥杯嵌入式的学习总结

一. 前言

        嵌入式竞赛实训平台(CT117E-M4) 是北京国信长天科技有限公司设计,生产的一款 “ 蓝桥杯全国软件与信息技术专业人才大赛-嵌入式设计与开发科目 “ 专用竞赛平台,平台以STM32G431RBT6为主控芯片,预留扩展板接口,可为用户提供丰富的实验场景。

以下内容都是小编自己在学习中所总结摘抄下来内容以及对嵌入式竞赛实训平台的相关理解,如有不到位之处,可尽情指出。如果全部完全理解掌握,拿个省二完全绰绰有余。

二. 学习CT117E-M4开发板

        1. 首先需要了解开发板资源,可以通过查看CT117E-M4的产品手册获取相对应的知识。另外在开始学习前,需要准备好相对应的软件环境,包括嵌入式集成开发环境(Keil Realview MDK) 以及STM32CubeMx的相关环境配置。值得注意的是如果使用keil 5 集成开发环境,就得使用集成开发环境自带的Pack installer安装STM32G4系列器件包。这些资源我都会放在我主页的资源当中,如果有需要可以取走。

        2. 在蓝桥云课上的右上角的搜索处输入蓝桥杯大赛历届真题即可查找到历届真题。

        3. LED是由PC8~PC15这8个GPIO口控制,在低电平时候点亮,所以我们在初始化时就可以在CubeMX中让它们都置高。如下所示:

如上图所示,就实现了将PC8~PC15所有的GPIO口都置为高,因此刚开始所以LED灯都会灭。

        4.  GPIO端口总共有八种模式,输入模式有四种:上拉输入模式,下拉输入模式,浮空输入,模拟输入。输出模式有:推挽输出,开漏输出,复用推挽,复用开漏。

        5. 这里简单介绍下这八种模式的概念:

1)上拉输入模式:上拉开关闭合,下拉开关断开,肖特基触发器打开。当IO引脚没有外部输入时,GPIO引脚会默认输入一个高电平,可以通过读取输入数据寄存器来读取到此时的IO电平。

2)下拉输入模式则跟上拉输入模式相反。

3)浮空输入模式:上拉开关和下拉开关均断开,肖特基触发器打开。此时,如果外部的IO引脚什么都不接(即悬空状态),此时GPIO引脚的电平将是一个不确定的状态。它将完全由外部的输入电平来确定。

4)模拟输入模式:肖特基触发器关闭,数据不再经过触发器模块。并且内部上下拉全部断开。该模式一般是给芯片内部的ADC外设来使用的。在该模式下,可以知道MCU将无法通过读取输入数据寄存器获得IO引脚的电平变化状态。

5)推挽输出模式:可输出高低电平,驱动能力强。

6)开漏输出模式:只能输出低电平,需要外部上拉电阻才能输出高电平。

7)复用推挽输出模式:用于特殊功能如UART、SPI等,由其他外设控制输出。

8)复用开漏输出模式:同样用于特殊功能,由其他外设控制输出。

        6. 代码书写的位置:

1)private includes:用户头文件的引用。

2)private typedef:用户自定义数据类型。

3)private macro:用户宏函数定义。

4)private variables:用户常量和变量定义。

5)private function prototypes:用户函数说明。

6)private usercode:功能实现位置。

7)Initialize all configured peripherals:各种初始化位置。

        7. 大家在安装完Keil集成开发环境后,需要选择CMSIS-DAP Debugger调试器,然后点击setting就能进入下面这个界面,然后再在Flash选项卡下,勾选Reset and Run。

 

三. 开发板各个外设的配置及使用

        1. 首先从LED灯开始,由于上面已经讲过LED的CubeMx配置,所以我们直接来看下由CubeMx生成的keil 5工程代码中LED相关代码。

#include"led.h"void LED_Disp(uchar dsLED)
{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);	//hign pinHAL_GPIO_WritePin(GPIOC,dsLED<<8,GPIO_PIN_RESET);	//some lowHAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);	//open LatchHAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);	//close Latch
}

 

其中,HAL_GPIO_WritePin这个就是HAL库中的一个内置函数,用来设置引脚电平。

下面我们再来看下led.h的代码,我们在每创建一个.c和.h文件后都要保存到相应工程目录的一个文件夹中,这里可以统一命名为bsp。

#ifndef _LED_H_
#define _LED_H_#include "main.h"void LED_Disp(uchar dsLED);#endif

 

其中bsp文件夹就是存放的我们各种.c和.h文件,MDK-ARM中就有我们的keil5工程,下面那个test.ioc就是我们相应的CubeMx配置。在有了文件夹后,别忘了在keil5工程左侧目录中添加这个文件夹哦。最后一步就是让这个包含所有内容的总文件夹成为我们keil5工程的环境变量,点击keil5工程上方一个类似魔法棒的东西,然后选择其中的Include Paths如下所示:

  

        2.  关于LCD的相关代码在官方给出的资料当中就有,我们可以直接拿过来使用。这里小编后面也会整理在我主页的资料当中。

        3. 按键控制,通过查询产品手册,可以知道按键主要由PB1,PB2,PB0,PA0控制。

相关按键代码示例如下:

#include "interrupt.h"
#include "main.h"struct keys key[4]={0,0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM1){key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);for(int i=0;i<4;i++){switch(key[i].judge_sta){case 0:{if(key[i].key_sta==0){key[i].judge_sta=1;key[i].key_time=0;}}break;case 1:{if(key[i].key_sta==0){key[i].judge_sta=2;}else{key[i].judge_sta=0;	}}break;case 2:{if(key[i].key_sta==1){key[i].judge_sta=0;if(key[i].key_time<70){key[i].single_flag=1;}}else{key[i].key_time++;if(key[i].key_time>70){key[i].long_flag=1;}}}break;}}}
}

 

这里包含了按键的点击,长按的判断,并且使用到了定时器作为中断,用来间隔很短的时间来查询按键是否被按下。

下面我们来看下相关的CubeMx配置。

 

这里我们使用的是定时器TIM1,需要设置Clock Source为Internal Clock内部时钟源。并且在下面设置好分频系数(Prescaler)以及重装载值(Counter Period)。这里为什么设置成80-1,主要是根据频率和时间的关系来确定的。我们知道频率的倒数就是所间隔的时间,例如50Hz就是0.02s。因为在我们的产品手册中说明了频率为80MHz,也就是80000000,我们用这个数除以分频系数,再除以重装载值就是我们最后的定时器间隔时间。这里80000000除以80得1000000,再除以10000,得100,也就是100Hz,0.01s,10ms。之所以减一是因为这里从0开始。

为了方便,这里我把我们今天所讲到的内容所涉及到的GPIO配置直接给出来。

3. PWM输入捕获

        与PA6和PA7有关,选择TIM16_CH1和TIM17_CH1。

 

 

 

double ccrl_val1a=0,ccrl_val2a=0;
uint ccrl_val1b=0,ccrl_val2b=0;
uint frq1=0,frq2=0;
float duty1=0,duty2=0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){ccrl_val1a=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);ccrl_val1b=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);__HAL_TIM_SetCounter(htim,0);frq1=(80000000/80)/ccrl_val1a;duty1=(ccrl_val1b/ccrl_val1a)*100;HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);}}if(htim->Instance==TIM3){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){ccrl_val2a=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);ccrl_val2b=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);__HAL_TIM_SetCounter(htim,0);frq2=(80000000/80)/ccrl_val2a;duty2=(ccrl_val2b/ccrl_val2a)*100;HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);}}
}

4. ADC数模转化

        

 

#include "badc.h"double getADC(ADC_HandleTypeDef *pin)
{double abc;HAL_ADC_Start(pin);abc = HAL_ADC_GetValue(pin);return (abc*3.3)/4096.0;
}

 

5. IIC通信

相关硬件配置如下: 

        

由此可以得出我们的IIC通信跟PB6和PB7有关。

关于IIC通信的相关代码,我们也可以直接使用官方所给的资料当中的代码,我们只需要在此基础上再添加两个代码即可,也就是IIC通信的读取和写入。如下所示:

unsigned char eeprom_read(unsigned char addr)
{unsigned char dat;I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0xa1);I2CWaitAck();dat=I2CReceiveByte();I2CSendAck();I2CStop();return dat;
}void eeprom_write(unsigned addr,unsigned char dat)
{I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();
}

以上便是我们今天的全部内容,如还有些许疑问,可以直接私信我或者在评论区底下留言。另外所需的资源数据包以及相关的完整源代码文件可在我主页中进行查找,或者找我拿取。

 

         

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147201.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

正点原子RK3588(二)——lenet测试和modelzoo模型

文章目录 一、lenet二、modelzoo模型2.1 介绍2.2 测试 一、lenet import cv2 import numpy as np from rknnlite.api import RKNNLite RKNN_MODEL LeNet5_mnist_model.rknndef show_top5(result):output result[0].reshape(-1)output_sorted sorted(output, reverseTrue)to…

AI资深导师指导-ChatGPT深度科研工作应用、论文撰写、数据分析及机器学习与AI绘图

2022年11月30日&#xff0c;可能将成为一个改变人类历史的日子——美国人工智能开发机构OpenAI推出了聊天机器人ChatGPT3.5&#xff0c;将人工智能的发展推向了一个新的高度。2023年4月&#xff0c;更强版本的ChatGPT4.0上线&#xff0c;文本、语音、图像等多模态交互方式使其在…

Fyne ( go跨平台GUI )中文文档-绘图和动画(三)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…

GAMES101(15节,辐射,BRDF)

Irradiance辐射度量学 辐射度量学在渲染领域&#xff0c;可以帮助理解基于物理的光照模型 radiant energy辐射能量Q&#xff0c;累计总能量&#xff08;单位J joule焦耳&#xff09;&#xff0c;就像太阳能板&#xff0c;光照时间越长接收能量越多&#xff0c;收到的能量总和…

python是什么语言写的

Python是一种计算机程序设计语言。是一种面向对象的动态类型语言。现今Python语言很火&#xff0c;可有人提问&#xff0c;这么火的语言它的底层又是什么语言编写的呢&#xff1f; python是C语言编写的&#xff0c;它有很多包也是用C语言写的。 所以说&#xff0c;C语言还是很…

解密的军事卫星图像在各种民用地理空间研究中都有应用

一、美军光学侦察卫星计划概述 国家侦察局 &#xff08;NRO&#xff09; 负责开发和操作太空侦察系统&#xff0c;并为美国国家安全开展情报相关活动。NRO 开发了几代机密锁眼 &#xff08;KH&#xff09; 军事光学侦察卫星&#xff0c;这些卫星一直是美国国防部 &#xff08;D…

Upload-Labs 文件上传靶场 通关

Pass-01 (本pass在客户端使用js对不合法图片进行检查&#xff01;) Pass-02 Pass-02 (本pass在服务端对数据包的MIME进行检查!) Pass-03 Pass-03 (本pass禁止上传.asp|.aspx|.php|.jsp后缀文件&#xff01;) AddType application/x-httpd-php .php .phtml .php3 .php4 .p…

Java-Part 0

Advanced Java and Cutting-edge Applications Part 0: Course presentation Part 1 其实就是个括号匹配问题&#xff0c;Stack 经典问题&#xff0c;但是好久没用Java&#xff0c;有一点点生疏&#xff0c;感觉老师的版本要简洁的多 package tiei.ajp.test;import java.uti…

java项目之基于spring boot的多维分类的知识管理系统的设计与实现源码

项目简介 基于spring boot的多维分类的知识管理系统的设计与实现实现了以下功能&#xff1a; 基于spring boot的多维分类的知识管理系统的设计与实现的主要使用者管理员可以管理用户信息&#xff0c;知识分类&#xff0c;知识信息等&#xff0c;用户可以查看和下载管理员发布…

Python|OpenCV-实现识别目标图像中的圆圈(20)

前言 本文是该专栏的第22篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 在处理图像检测项目的时候,可能会遇到需要检测目标图像中的“圆圈”需求。笔者在这里举个例子,如下图所示: 在图中有一个篮球,但是我们要找的目标对象并不是篮球,而是篮球它本身的这个…

BUUCTF-MISC-数据包中的线索

下载题目文件&#xff0c;解压发现是一段流量包 使用Wireshark打开 首先过滤HTTP数据流 然后追踪HTTP数据流 通过追踪数据流可以发现 流7 当中有一段base64编码&#xff0c;我们尝试解码 base64基本特征 Base64编码只包含64个字符&#xff1a;大写字母&#xff08;A-Z&#x…

(四)悟说几个特殊矩阵及矩阵函数

上一期介绍了矩阵的出现源于解线性方程组。但是&#xff0c;矩阵出现之后&#xff0c;就犹如打开了潘多拉的盒子&#xff0c;会产生许多魔法。 1 旋转矩阵 我们知道用矩阵左乘某个向量&#xff0c;相当于对该向量做线性变换。那么是否有一种矩阵&#xff0c;能让向量旋转&…

2D目标检测常用loss

在2D目标检测任务中&#xff0c;常用的损失函数&#xff08;Loss&#xff09;主要用于优化以下三个关键方面&#xff1a; 类别分类&#xff08;Classification&#xff09;&#xff1a;用于区分检测到的对象属于哪一类。边界框回归&#xff08;Bounding Box Regression&#x…

《代码整洁之道:程序员的职业素养》

作者&#xff1a;【美】Robert C. Martin 第1章 专业主义 专业主义就意味着担当责任&#xff0c;软件开发太复杂了&#xff0c;不可能没什么 bug。但很不幸&#xff0c;这并不能为你开脱。人体太复杂了&#xff0c;不可能尽知其全部&#xff0c;但医生仍要发誓不伤害病人。如…

基于单片机的智能温控风扇系统的设计

&#xff3b;摘 要&#xff3d; 设计一种基于单片机的智能温控风扇系统&#xff0c;系统由 STC 系列的 51 单片机 、 温度传感器 、 LED 数码管和风扇等模块组成。 本系统具有对外界温度感知以及对感知数据进行分析处理 、 智能调节等功能&#xff0c;避免因温度过高而产生…

6.定期自动执行脚本,让你的金融数据库及时更新!

上一节课我们配置好了我们的运行环境&#xff0c;今天我来教大家怎么在不同的环境下配置定时任务&#xff0c;从而自动执行脚本以更新数据库。 一、Windows下定时执行脚本 如果你的电脑是Windows&#xff0c;并且你没有一台支持Docker的NAS、也没有一台Linux服务器&#xff0…

text2sql方法:RESDSQL和DAIL-SQL

之前介绍了text2sql的综述&#xff0c;但是对一些方法的描述不够详细&#xff0c;所以将一些感兴趣的方法思路也整理一下。 RESDSQL RESDSQL出自2023年2月的论文《RESDSQL: Decoupling Schema Linking and Skeleton Parsing for Text-to-SQL》(github)。它使用seq2seq PLM(pr…

[笔记] 走行电机控制器 防摇摆功能的技术细节

防摇摆用于走行电机控制&#xff0c;一般用于小车。这里参考了数重的彩页&#xff1a; 1.原理 这个无效和有效的控制是靠启动时的幔起&#xff0c;和停车时的缓停实现的。他似乎对加速过程的力矩曲线做了某种控制&#xff0c;能够让启停时&#xff0c;必然的角度变化在运动中逐…

【时时三省】(C语言基础)指针笔试题3

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 笔试题3 首先创建了一个数组 数组里面放了1 2 3 4 &a取出的是数组的地址 数组地址加1 如下图 直接从1跳到了四后面 然后强制类型转换成了int* 转换成int*之…

ModbusTCP通讯错误的排查

Modbus是一种由MODICON公司开发的工业现场总线协议标准&#xff0c;是一项应用层报文传输协议。该协议用于传输数字和模拟变量[1]。有关该协议的报文具体格式&#xff0c;以及一些基本概念&#xff0c;见[1]。 本文以一个例子&#xff0c;阐述当ModbusTCP通讯出现错误的时候&a…