草庐IT

蓝桥杯嵌入式速成-stm32hal库总结-Cubemx配置+代码编写

拾小白 2023-09-03 原文

复习一周进国赛,只讲具体配置方法,原理网上找。

用到最新版的STM32G431,一口气配置完(熟练的话全部配置亲测40分钟搞定)。

把省赛所有基础配置过一遍,内容很多,都是干货,觉得有用记得点赞收藏。

包括时钟配置、中断配置;

外设中常用的GPIO(KEY,LED)、ADC、UART、LCD、I2C、TIM(pwm,cap)、RTC

1.Cubemx配置

1.1 选择芯片

1.2 时钟配置

1.3 GPIO

根据官方的原理图

配置led的GIPO  PC8-PC15+PD2(别把这个忘了)

和key的GPIO PB0-PB2 PA0

 

GPIO配置默认状态就好

1.4 ADC

板上电阻R37和R38连接到PB15和PB12

 

 

 配置如下  两个ADC同样配置方法,以ADC1为例

 

 

选择ADC时钟

 1.5 UART 串口通信

 

 配置接受中断

 1.6 TIM

1.6.1 输入捕获cap

选择TIM2(PA15)作为输入捕获  可以捕捉信号发生器555的信号

 

 

中断

1.6.2 PWM

选择TIM17(PA7)作为PWM发生器,可以产生PWM信号

 

 1.7  RTC时钟

 

 

1.8 创建文件

 

2 基础文件和功能配置

说明:模板创建后保留一份,后期如果修改Cubemx配置在备份的文件里修改,否则后面写的代码会被覆盖掉!!!!

2.1 添加启动文件

1.在官方给的任意项目里找到启动文件复制添加到自己项目中的MDK-ARM文件夹中

 

2. 打开Keil5,添加到项目文件夹中

 

3.编译通过

 2.2 烧录到单片机中

记得板子得插上

 

 烧录完成

 3 代码编写

3.1 LED和KEY

在inc文件夹里创建头文件

在 src文件夹里创建.c文件 

和前面同样的方法,把.c文件加入项目

 左侧可以看到添加的文件,打开编写代码

 代码如下:

#include "ledAndKey.h"

//led1-led8
void Led_Disp(unsigned char c)
{
		//关闭所有灯
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
		//根据输入打开灯
	  HAL_GPIO_WritePin(GPIOC, c<<8, GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);	
}

//按键检测
unsigned char Key_Scan(void)
{
	unsigned char s;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == GPIO_PIN_RESET)
	{
		s = 1;
	}
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET)
	{
		s = 2;
	}
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == GPIO_PIN_RESET)
	{
		s = 3;
	}
	else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
	{
		s = 4;
	}
	return s;
}

 打开头文件

 

#include "main.h"

void Led_Disp(unsigned char c);
unsigned char Key_Scan(void);

 主函数实现(通过灯来测试配置是否成功):

添加头文件

 3.2 lcd配置

添加官方给的lcd的文件

 

 和前面一样的方法添加进项目

 主函数添加头文件

#include "lcd.h"

lcd初始化

	LCD_Init();

lcd例程中可以找到常用的lcd函数

	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	LCD_DisplayStringLine(Line0, (uint8_t *)"                    ");

 3.3 ADC配置

在ADC的.c文件末尾处添加两个函数

int GetADC1(void)
{
	int Value;
	HAL_ADC_Start(&hadc1);
	Value = HAL_ADC_GetValue(&hadc1);
	return Value;
	
}
int GetADC2(void)
{
	int Value;
	HAL_ADC_Start(&hadc2);
	Value = HAL_ADC_GetValue(&hadc2);
	return Value;
}

头文件声明

int GetADC1(void);
int GetADC2(void);

初始化

  MX_ADC1_Init();
  MX_ADC2_Init();

3.4 UART串口配置

    MX_USART1_UART_Init();	 //初始化
    HAL_UART_Transmit(&huart1,str,strlen(str),50);  //发送
	HAL_UART_Receive_IT(&huart1,str,1);  //接受中断

接受中断函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

3.5 I2C配置

添加官方给的.c文件和.h文件

 在i2c.c文件后添加读和写函数,并在头文件添加函数声明

void I2CWrite(unsigned char *p,unsigned char data,unsigned char num)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(data);
	I2CWaitAck();
	
	while(num--)
	{
		I2CSendByte(*p++);
		I2CWaitAck();
	}
	I2CStop();
	delay1(500);
}

void I2Cread(unsigned char *p,unsigned char data,unsigned char num)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(data);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	
	while(num--)
	{
		*p++ = I2CReceiveByte();
		if(num)
			I2CSendAck();
		else
			I2CSendNotAck();
	}
	I2CStop();
}

主函数初始化

I2CInit();

3.6 TIM配置

3.6.1 输入捕获配置

初始化,打开定时器,开启捕获中断

	MX_TIM2_Init();
	HAL_TIM_Base_Start(&htim2);
	HAL_TIM_OC_Start_IT(&htim2,HAL_TIM_ACTIVE_CHANNEL_1);
	HAL_TIM_OC_Start_IT(&htim2,HAL_TIM_ACTIVE_CHANNEL_2);

捕获中断回调函数

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
	{
		//上升沿中断
	}
	else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
	{
		//下降沿中断
	}
}

3.6.2   PWM函数

	MX_TIM17_Init();
	HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
	__HAL_TIM_SET_COMPARE (&htim17,TIM_CHANNEL_1,500);//设置占空比
	__HAL_TIM_SET_AUTORELOAD(&htim17,4999); //设置频率

3.7 RTC时钟

创建日期和时间结构体

RTC_TimeTypeDef TIME;
RTC_DateTypeDef DATE;

初始化 获得时间

	MX_RTC_Init();
	HAL_RTC_GetDate(&hrtc,&DATE,FORMAT_BIN);
	HAL_RTC_GetTime(&hrtc,&TIME,FORMAT_BIN);

有关蓝桥杯嵌入式速成-stm32hal库总结-Cubemx配置+代码编写的更多相关文章

  1. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  2. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  3. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  4. ruby-on-rails - 如何为空白字段编写 rspec? [Rails3.1] - 2

    我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona

  5. ruby-on-rails - 尝试为 Rails 中的用户名验证编写 REGEX - 2

    我正在尝试用Ruby(Rails)编写一个正则表达式,以便用户名的字符仅包含数字和字母(也没有空格)。我有这个正则表达式,/^[a-zA-Z0-9]+$/,但它似乎没有用,我在Rails中收到一个错误,说“The如果正则表达式使用多行anchor(^或$),这可能会带来安全风险。您是要使用\A和\z,还是忘记添加:multiline=>true选项?"我的user.rb模型中此实现的完整代码是:classUser我做错了什么以及如何修复此正则表达式,使其仅对数字和字母有效而不对空格有效?谢谢。 最佳答案 简短回答:使用/\A[a-z

  6. ruby-on-rails - 如何编写跨模型、 Controller 和 View 的 Rails mixin - 2

    为了减少我的小Rails应用程序中的代码重复,我一直致力于将我的模型之间的通用代码放入它自己的单独模块中,到目前为止一切顺利。模型的东西相当简单,我只需要在开头包含模块,例如:classIso这工作正常,但是现在,我将有一些Controller和View代码,这些代码也将在这些模型之间通用,到目前为止,我有这个用于我的可发送内容:#Thisisamodulethatisusedforpages/formsthatarecanbe"sent"#eitherviafax,email,orprinted.moduleSendablemoduleModeldefself.included(kl

  7. ruby - 在不添加 "end"的情况下编写 Ruby 的任何方法? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭11年前。Ruby是一种美丽的语言,但有一个我讨厌写很多次的关键词“结束”。有什么方法可以写出简洁的代码而不用每次都写“end”吗?

  8. 蓝桥杯备赛(二) - 2

    目录前言: 一、ASC分析代码实现二、 卡片分析代码实现三、 直线分析代码实现四、货物摆放分析代码实现小结:前言:  在刷题的过程中,发现蓝桥杯的题目和力扣的差别很大。让人有一种不一样的感觉,蓝桥杯题目偏向对于实际问题用编程去的解决,而力扣给人感觉很锻炼自己的编程思维,逻辑能力。两者结合去刷,相信会有不一样的收获。 一、ASC  已知大写字母A的ASCII码为65,请问大写字母L的ASCII码是多少?分析  这道题目看上去很简单,我们需确定自己计算的准确,所以我建议用编程去解决。代码实现publicclassTest8{publicstaticvoidmain(String[]args){Sy

  9. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

  10. ruby - 如何为字母、元音和辅音等德语字符类编写正则表达式? - 2

    例如,我设置了这些:L=/[a-z,A-Z,ßäüöÄÖÜ]/V=/[äöüÄÖÜaeiouAEIOU]/K=/[ßb-zBZ&&[^#{V}]]/因此/(#{K}#{V}{2})/匹配"azAZßäÜ"中的"ßäÜ"。有没有更好的方法来处理它们?我能否将这些常量放在我的Ruby安装文件夹中某个文件中的模块中,这样我就可以在我在计算机上编写的任何新脚本中包含/要求它们?(我是新手,我知道我混淆了这个术语;请纠正我。)此外,我能否只获取元字符\L、\V和\K(或任何尚未在Ruby中设置)以在正则表达式中代表它们,所以我不必一直做字符串插值? 最佳答案

随机推荐