【HAL库】HAL库STM32cubemx快速使用

文章目录

    • 整体框图
    • 一、基础工程
      • 1 新建工程
      • 2 配置RCC
      • 3 配置SYS
      • 4 工程设置
      • 5 生成代码
      • 6 keil设置下载&复位
    • 二、必备外设
      • 1 目录规范
      • 2 LED
      • 2 RTC
      • 3 USART
      • 4 KEY
    • 三、其他外设
      • 1 OLED(模拟IIC、模拟SPI)
      • 2 BH1750光强检测
      • 3 MQ2烟雾检测
      • 3 MQ4甲醛检测
      • 4 DHT11温湿度
      • 5 SIM900A GSM模块

整体框图

image-20230404092859237

软件:keil5、STM32Cubemx
硬件:淘宝的STM32F103C8T6最小系统

一、基础工程

1 新建工程

image-20230403143250580

image-20230403143526045

2 配置RCC

选择外部时钟源。

image-20230403144245550

设置外部晶振输入值,我这块板子是8M。
然后手动输入最大时钟频率,然后回车让他自动配置时钟树。我这块板子是72M。

image-20230403144558704

3 配置SYS

我的下载器是SWD两根线的,所以我选这个。(一定配置完下载模式再进行程序下载,不然单片机变砖,需要从串口下载进行恢复)

image-20230403144726224

4 工程设置

image-20230403145108357

img

5 生成代码

点击生成代码

img

打开keil工程

image-20230403145259140

6 keil设置下载&复位

选择下载器类型,我用的是DAP。点击后面的Setting。

image-20230403145424797

进入后勾选自动复位,表现为每次下载程序后单片机自动复位运行程序。
设置完点击OK。

image-20230403145616759

二、必备外设

1 目录规范

在工程目录下,新建一个ICODE文件夹,用于存放自己写的各种外设文件。

image-20230403145833040

2 LED

1 导入.c.h文件(就是将.c.h文件导入keil工程,后面不再叙述此环节)

将之前写好的 LED文件夹复制到本工程的ICODE目录下。
里边有led.c led.h文件夹。

image-20230403150423937

在工程中,创建ICODE文件夹,添加led.c文件。

image-20230403150845428

在工程中,添加led.h文件。

image-20230403151117553

image-20230403151200248

2 Cubemx配置

配置板子LED引脚,推挽输出模式。我这块板子是 PC13。
重新生成代码。

image-20230403151836114

3 修改 .h 文件

更改为其他引脚,只需更改LED端口号和引脚PIN。我这块板子是PC13。

image-20230403152111448

4 测试

在main.c中添加 #include “led.h”
在while里添加下面代码。LED灯闪烁。

LED_Contrary();
HAL_Delay(500);//500ms

2 RTC

1 导入.c.h文件(不再赘述,详细见LED部分)

2 Cubemx配置

和PC13冲突,核心板PC13是LED,所以禁用RTC OUT。

3 修改 .c 文件

在中断.c里,填加led头文件,在RTC中断函数里,加入500ms,LED电平反转函数。

#include "led.h"

static uint16_t rtccnt=0;
rtccnt++;
if(rtccnt>500) rtccnt=0,LED_Contrary();

image-20230404190141584

4 测试

LED闪烁。

3 USART

1 导入.c.h文件(不再赘述,详细见LED部分)

在keil工程中导入之前写好的.c.h文件。

image-20230404190406936

2 Cubemx配置

使用串口1,波特率默认,异步通信。

image-20230404185429185
开启中断
image-20230404093133924

3 修改 .h 文件

代码默认使用串口1。添加其他串口可以在.h里,复制,改名。

image-20230404183337374

4 测试

串口发送/接收函数:

HAL_UART_Transmit();串口发送数据,使用超时管理机制 
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送  
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收

串口中断函数:

HAL_UART_IRQHandler(UART_HandleTypeDef *huart);  //串口中断处理函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);  //串口发送中断回调函数
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);  //串口发送一半中断回调函数(用的较少)
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);  //串口接收中断回调函数
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数(用的较少)
HAL_UART_ErrorCallback();串口接收错误函数

常用的发送函数为:HAL_UART_Transmit();

常用的接收函数为:HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

HAL库串口中断调用流程:

image-20230404105922320

发送:

1 printf重映射:

/* printf重映射 */
#include <stdio.h>
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    //具体哪个串口可以更改huart1为其它串口
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1 , 0xffff);
    return ch;
}

2 printf发送:

printf("hello \r\n"); //发送字符串

float Data=1.11;
printf("Data=%.2f \r\n",Data);	//发送变量

3 Hal库自带发送函数:

#include <stdio.h>

HAL_UART_Transmit(&huart1,"hello\r\n",sizeof("hello\r\n"),0xffff);//发送字符串

uint8_t Data1[]={"hello\r\n"};
HAL_UART_Transmit(&huart1,Data1,sizeof(Data1),0xffff);//发送字符串

uint8_t Databuffer[20]={0};
float Data=1.11;
sprintf(Databuffer,"Data=%.2f \r\n",Data);
HAL_UART_Transmit(&huart1,Databuffer,strlen(Databuffer),0xffff);//发送变量 用strlen

中断接收:

1 定长

 /*	
		串口接收中断
		定长接收	
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
		if(huart == &huart1)
		{
			HAL_UART_Transmit(&huart1,(uint8_t *)&Uart1_RxData,1,0xffff);//原样返回
			while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
			HAL_UART_Receive_IT(&huart1,(uint8_t *)&Uart1_RxData, 1); //&取地址
		}
}

2 不定长

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
	
	if(huart == &huart1)
	{
		if(Uart1_Rx_Cnt >= 255)  //溢出判断
		{
			Uart1_Rx_Cnt = 0;
			memset(Uart1_RxBuffer,0x00,sizeof(Uart1_RxBuffer));
			HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF); 	
		}
		else
		{
			Uart1_RxBuffer[Uart1_Rx_Cnt++] = Uart1_RxData;   //接收数据转存
		
			if((Uart1_RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(Uart1_RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位\r\n。0x0D是\r,0x0A是\n
			{
				/*	此处添加用户代码	*/

				HAL_UART_Transmit(&huart1, (uint8_t *)&Uart1_RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
				while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束

				/*	此处添加用户代码	*/
				Uart1_Rx_Cnt = 0;
				memset(Uart1_RxBuffer,0x00,sizeof(Uart1_RxBuffer)); //清空数组
			}
		}
		HAL_UART_Receive_IT(&huart1, (uint8_t *)&Uart1_RxData, 1);   //再开启接收中断
	}
}

4 KEY

1 导入.c.h文件(不再赘述,详细见LED部分)

在keil工程中导入之前写好的.c.h文件。

2 Cubemx配置

3 修改 .h 文件

4 测试

三、其他外设

1 OLED(模拟IIC、模拟SPI)

1 导入.c.h文件(不再赘述,详细见LED部分)

在keil工程中导入之前写好的.c.h文件。选择IIC的或者SPI的。(模拟IIC和模拟SPI)

image-20230404190842999

image-20230404191104861

2 Cubemx配置

任选对应OLED引脚个数的GPIO,设置成推挽输出。设置为高速。

image-20230404192656241

3 修改 .h 文件

更改为其他引脚,只需更改OLED端口号和引脚PIN

image-20230404191352126

4 测试

OLED 显示字体大小 16*16 最合适。能放4行:0 16 32 48。

添加头文件

#include "oled.h"

添加初始化

OLED_Init();
OLED_ColorTurn(0);			//0正常显示,1 反色显示
OLED_DisplayTurn(0);		//0正常显示 1 屏幕翻转显示

1 显示字符:

OLED_ShowString(0,0,"hello",16,1); 
OLED_Refresh();//更新0

2 显示变量:

uint8_t Databuffer[20]={0};
float Data=1.11;
sprintf(Databuffer,"Data=%.2f \r\n",Data);//sprintf
OLED_ShowString(0,16,Databuffer,16,1);  
OLED_Refresh();

3 显示中文:


2 BH1750光强检测

1 导入.c.h文件(不再赘述,详细见LED部分)

在keil工程中导入之前写好的.c.h文件。

2 Cubemx配置

3 修改 .h 文件

4 测试

添加头文件

添加初始化

3 MQ2烟雾检测

1 导入.c.h文件(不再赘述,详细见LED部分)

在keil工程中导入之前写好的.c.h文件。

2 Cubemx配置

3 修改 .h 文件

4 测试

添加头文件

添加初始化

3 MQ4甲醛检测

4 DHT11温湿度

1 导入.c.h文件(不再赘述,详细见LED部分)

在keil工程中导入之前写好的.c.h文件。

image-20230404194748385

2 Cubemx配置

任选一个IO口,配置为高速,推挽输出。

3 修改 .h 文件

定义DHT11总线连接的GPIO端口, 只需要修改下面2行代码即可任意改变DATA的引脚

image-20230404194855017

4 测试

添加头文件

#include "dht11.h"

添加初始化

DHT11_Init();						//DHT11温湿模块初始化

读取温湿度

uint8_t DHT11_DATA[2]={0};		//用于存放DHT11温湿度数据
DHT11_ReadData(DHT11_BUF);		//读出DHT11传感器数据(参数是存放数据的数组指针)
printf("湿度:%2d% 温度:%2d℃\r\n",DHT11_BUF[0],DHT11_BUF[1]);//串口打印湿度温度

5 SIM900A GSM模块

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于蓄电池进行调峰和频率调节研究【超线性增益的联合优化】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。⛳座右铭&#…

第04章_运算符

第04章_运算符 &#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xff0c;目前在某公…

该不该放弃嵌入式,单片机这条路?

本文几乎浓缩了我从业10几年的精华&#xff0c;内容涵盖我转行、打工、创业的经历。 建议从头到尾不要错过一字一句&#xff0c;因为字里行间的经验之谈&#xff0c;或许能成为你人生重要转折点。 全文3700多字&#xff0c;写了6个多小时&#xff0c;如果你赶时间&#xff0c;建…

【17】核心易中期刊推荐——深度学习 | 遥感图像处理

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

【学会这几个VSCode插件,让你的Python代码更优秀】

VSCode&#xff08;Visual Studio Code&#xff09;是由微软研发的一款免费、开源的跨平台文本&#xff08;代码&#xff09;编辑器&#xff0c;一般主要用于轻量级的编程代码工作&#xff0c;就非常适合Python&#xff0c;同时在前端开发方面也有举足轻重的地位。但如果想用于…

蓝桥杯集训·每日一题Week3

Trie AcWing 835. Trie字符串统计&#xff08;算法基础课&#xff09; 思路&#xff1a; Trie是一种高效地存储和查找字符串集合的数据结构,适用于字符串不太复杂的情况。其形状是一个以0为根节点的树&#xff0c;查询和插入的效率都比较高&#xff0c;有插入和查询两种操作。…

制造业的寒冬真的要来了吗?

制造业的寒冬真的要来了吗&#xff1f;其实当前&#xff0c;我国制造业发展水平是处于全球第三阵列&#xff0c;排名第四的&#xff1a; 但能处第三序列靠前&#xff0c;还是因为“规模发展”起了重要支撑——依靠规模拉动发展。所以如果从“质量效益”、“结构优化”、“持续发…

【AI探索】我问了ChatGPT几个终极问题

终于尝试了一把ChatGPT的强大之处&#xff0c;问了一下关心的几个问题&#xff1a; chatGPT现在在思考吗&#xff1f;有没有什么你感兴趣的问题&#xff1f; 你认为AI会对人类产生哪些方面的影响&#xff1f; 你对人类所涉及到的学科有了解吗&#xff1f;你认为在哪些方面与人类…

JetPack Compose之Modifier修饰符

前言 在Compose中&#xff0c;每一个组件都是带有Compose注解的函数&#xff0c;被称为Composable。Compose已经预置了很多的Compose UI组件&#xff0c;这些组件都是基于Material Design规范设计的&#xff0c;例如Button&#xff0c;TextField&#xff0c;TopAPPBar等。在布…

IOC、AOP、和javca面试题

一、 1、控制反转&#xff08;IOC&#xff09; 将创建管理对象的工作交给容器来做。在容器初始化&#xff08;或在某个时间节点&#xff09;通过反射机制创建好对象&#xff0c;在使用时直接从容器中获取。 控制反转&#xff1a;将对象的控制权反过来交给容器管理。 IOC实现…

既然有http 请求,为什么还要用rpc调用?

先弄明白什么是RPC。 RPC&#xff08;Remote Procedure Call&#xff09;—远程过程调用&#xff0c;它是一种通过网络从远程计算机程序上请求服务&#xff0c;而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在&#xff0c;如TCP或UDP&#xff0c;为通信程序之…

【面试】Java并发编程面试题

文章目录基础知识为什么要使用并发编程多线程应用场景并发编程有什么缺点并发编程三个必要因素是什么&#xff1f;在 Java 程序中怎么保证多线程的运行安全&#xff1f;并行和并发有什么区别&#xff1f;什么是多线程多线程的好处多线程的劣势&#xff1a;线程和进程区别什么是…

基于java+ssm+vue病人跟踪治疗信息管理系统的搭建及源码

源码获取方式见文末 一.需求简介 病人治疗信息管理系统采用B/S模式&#xff0c;实现安全、快捷、高效的病人跟踪治疗信息管理。传统手工管理模式效率低下&#xff0c;已无法满足病人需求。 信息化时代的到来&#xff0c;使得开发病人跟踪治疗信息管理系统成为必然。 本系统采…

Linux 串口RS232/485/GPS 驱动实验(移植minicom)

目录Linux 下UART 驱动框架I.MX6U UART 驱动分析硬件原理图分析RS232 驱动编写移植minicomRS232 驱动测试RS232 连接设置minicom 设置RS232 收发测试RS485 测试RS485 连接设置RS485 收发测试GPS 测试GPS 连接设置GPS 数据接收测试串口是很常用的一个外设&#xff0c;在Linux 下…

python入门(一)conda的使用,创建修改删除虚拟环境,以及常用命令,配置镜像

文章目录背景1.conda的下载地址:2.安装3.执行常用命令1&#xff09;查看版本2&#xff09;查看所有虚拟环境3&#xff09;创建虚拟环境4&#xff09;激活虚拟环境5&#xff09;关闭虚拟环境6&#xff09;删除虚拟环境7&#xff09;创建python2.7的虚拟环境8&#xff09;使用pyt…

命令行上的数据科学第二版 二、开始

原文&#xff1a;https://datascienceatthecommandline.com/2e/chapter-2-getting-started.html 贡献者&#xff1a;Ting-xin 在这一章中&#xff0c;我需要确定你能够利用命令行做数据科学&#xff0c;为此你需要能满足一些条件。条件主要分为三个部分&#xff1a;&#xff08…

SQLyog图形化界面工具【超详细讲解】

目录 一、SQLyog 介绍 二、SQLyog 社区版下载 三、SQLyog 安装 1、选择Chinese后点击OK 2、点击“下一步” 3、选择“我接受”后点击“下一步” 4、点击“下一步” 5、修改安装位置&#xff08;尽量不要安装在C盘&#xff09;&#xff0c;点击“安装” 6、安装后点击“…

剥茧抽丝,细数模块化的前世今生

写在前面 本篇是前端工程化打怪升级的第 1 篇&#xff0c;关注专栏 | 小册传送门 | 案例代码 近几年&#xff0c;时常会感叹&#xff0c;前端&#xff0c;发展的太迅猛了。日新月异的新概念&#xff0c;异彩纷呈的新思想泉水般涌出&#xff1b;前端项目的复杂度、开发成本、维护…

Python 自动化指南(繁琐工作自动化)第二版:十五、使用 PDF 和 WORD 文档

原文&#xff1a;https://automatetheboringstuff.com/2e/chapter15/ PDF 和 Word 文档是二进制文件&#xff0c;这使得它们比纯文本文件复杂得多。除了文本&#xff0c;它们还存储大量的字体、颜色和布局信息。如果您想让您的程序读写 PDF 或 Word 文档&#xff0c;您需要做的…

【从零开始学习 UVM】3.5、UVM TestBench架构 —— UVM Sequencer [uvm_sequencer]

文章目录 Usage(用法)Custom Sequencer(自定义sequencer)Class Hierarchy一个 sequencer 生成数据事务作为类对象并将其发送到driver以执行。建议扩展uvm_sequencer基类,因为它包含了允许sequence与driver通信所需的所有功能。基类是由可以被sequencer处理的requset和resp…
最新文章