学习笔记(1)stm32h743和ADXL355的SPI通信,基于cubeMX和keil5MDK平台,采用HAL库编程,代码已模块化处理
今天是一个特别的日子,为什么呢?哈哈,因为从大四做毕业设计的时候,接触CSDN,到现在一整年了,终于创作了我的第一篇博客,内心难念有些激动!
首先声明,我不是嵌入式领域的技术大牛,只是普通的研一新生,在我的学习过程中,认为有价值拿出来分享,亦或是有意义采用这种方式进行纪念或记录的学习经验,所以有了这一篇博客,希望可以帮到有需要的人,好了言归正传。
想要成功实现stm32h743和ADXL355的SPI通信,前提是,你知道什么是SPI(不胜详略),配置通信参数的时候不会满头雾水;还要熟悉HAL库,关于SPI各个函数and参数的定义;然后,读ADXL355的datasheet,数据手册上会有寄存器列表,从上面可以知道“传感器的配置方法,数据的读取地址等”。要耐心,充分的准备是成功的关键。
关于什么是spi,stm32h7的HAL库SPI部分的介绍,下面这位博主已经写的非常棒了!我就不赘述了。这个是安富莱公司的教程,正点原子H7是没有写SPI的。
【STM32H7教程】第72章 STM32H7的SPI总线基础知识和HAL库API_Simon223的博客-CSDN博客
进行完之前的理论学习之后,正式利用STM32H7进行ADXL355的数据读取了。
在此之前,不妨先过目下面这篇博客,也是我在写STM32H7时候的主要参考!这个是基于STM32F103RC的,原理是类似的。
STM32HAL库实现ADXL355加速度传感器简单记步功能(SPI)_Miller@yuan的博客-CSDN博客_adxl355测加速度程序
下面开始讲解我的具体配置过程:
新建CubeMX工程,选择对应芯片。 进入工程,第一步,使能RCC,选择外部时钟(HES)晶体/陶瓷震荡源,然后如下配置时钟树,可参考正点原子H7教程。
使能usart1,修改usart1的引脚至PA9,PA10,使能NVIC,开启usart1的中断,prior设置为3。
使能spi2,(1,2,3都行) ,我把引脚的默认值修改了。
!!!!请注意,这里踩坑了,用SPI2的NSS作为片选,我设置的是硬件控制,输出,上拉,但是不能用,不知原因。所以一般选择soft_nss模式,此时该端口未用,可以用于正常IO输出。
下图可参考。
接着,弄了两个LED灯的GPIO,随便玩的。
选择MDK,勾选Dont generat the main(),生成代码。
接下来,一起来康康生成的代码是什么样子的,因为是第一篇博客,而且我也是第一次尝试用cubeMX+keil5MDK一起使用,所以内容包含但不限于SPI配置:
首先,生成的main.h中,有在配置LED灯的IO口时,起的别名,别的基本上没啥。
再看main.c,绝大多数配置代码都在这了,为了节省篇幅,就只看这段声明吧,我都打好注释了。
SPI句柄的参数配置,记得按照ADLX355的时钟极性修改。
SPI_HandleTypeDef hspi2; //初始化SPI用的结构体(SPI句柄)UART_HandleTypeDef huart1; //UART句柄/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void); //系统时钟初始化函数,留在main.c中,折叠起来不碍眼,直接调用
static void MX_GPIO_Init(void); //GPIO初始化函数,稍后搬到GPIO模块中
static void MX_SPI2_Init(void); //SPI2初始化函数,稍后搬到SPI模块中
static void MX_USART1_UART_Init(void);//USART1初始化函数,稍后搬到UART模块中
然后,打开stm32h7xx_hal_msp.c,可以看到以下函数。
插入题外话,HAL库和标准库的区别是,例如,标准库配置SPI只需要在一个INIT函数中写清配置信息,而HAL库会把涉及硬件的配置和常规功能配置分开,前文的MX_SPI2_INIT是对SPI的通信模式、速度、校验格式等进行设置,这些设置在M7系列的各种芯片都是通用的,甚至可以兼容到M3,而HAL_SPI_MspInit是进行SPI通信端口的配置,顺便在这个函数里帮你使能了SPI的时钟和SPI用到的GPIO的时钟。这样,在你需要将这个工程一直到同系列的其他芯片上时,只需要修改Mspinit函数里的内容就可以了。
再多说一点,为什么这些函数可以写在这个文件里,因为你的MX_SPI2Init在main.c,maic.c和该文件同时包含main.h,而且main.h包含"stm32h7xx_hal.h",所以MX_SPI2Init可以到HAL_SPI_Init,HAL_SPI_Init可以调用到HAL_SPI_MspDInit,因此我们在模块化设计的时候,把HAL_SPI_MspInit和MX_SPI2Init放在一个模块中,然后在main.c中可以成功调用,若要在其他模块中调用,则该模块应当包含main.h或直接包含stm32h7xx_hal.h。
void HAL_MspInit(void)
{
.... 这个是初始化函数,留在这个文件里就行,其他的函数 我都习惯性搬走。
}void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
(... 这是重写的SPI_Mspinit函数,因为是_week函数,就是给你重写的。)GPIO_InitTypeDef GPIO_InitStruct = {0};if(hspi->Instance==SPI2){/* USER CODE BEGIN SPI2_MspInit 0 *//* USER CODE END SPI2_MspInit 0 *//* Peripheral clock enable */__HAL_RCC_SPI2_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();/**SPI2 GPIO ConfigurationPB13 ------> SPI2_SCKPB14 ------> SPI2_MISOPB15 ------> SPI2_MOSI*/GPIO_InitStruct.Pin = GPIO_PIN_13;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLDOWN;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/* SPI2 interrupt Init */HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);HAL_NVIC_EnableIRQ(SPI2_IRQn);}}void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{
...}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
接下来,直接上我的spi.c和spi.h!!为了可以折叠函数,所以我截图了。想必大家也知道这些函数是从哪里复制而来的了。记得复制配置SPI2的句柄定义。
下面没有折叠的函数,是基于HAL给提供的SPI通信函数,重写的用于读写字节的函数。
spi的全双工的通信-写入n个字节:
1,片选拉低,用我们重写的通信函数,要先写入地址,返回值是你写地址的过程中,MOSI线上的数据,可以不要。
2,再次调用通信函数,写入1个字节的数据,再次调用,写入第2个字节的数据.....片选拉高。
spi的全双工的通信-读取n个字节:
1,片选拉低,用我们重写的通信函数,要先写入地址,返回值是你写地址的过程中,MOSI线上的数据,可以不要。
2,再次调用通信函数,写入0xff或者0x00(根据从机的要求),此时的返回值,就是你读取的第1个字节的数据,再次调用函数写入0xff,返回值为第2个字节.....片选拉高。
!!!如何让从机知道你要读or写,要对原始地址进行处理:左移一位,右边自动补0,为写;左移一位,和0x01或,相当于最低为置1,为读;有些小伙伴会有些疑惑,为什么要在最低位作为读写标志位,标志位位于地址帧的最前位,区别于最高位,最前位我将其定义为:接受方接到地址帧的首个bit。具体看下图,一目了然。
图片来源于:
SPI原理超详细讲解---值得一看_Z小旋-CSDN博客_spi通信的详细讲解
到这里,内容基本上写完了。我相信,现在,你已经可以利用STM32H7读取ADLX355的数据了,可能还不限于ADLX355。
哦对了,还有最重要的一件事!重写printf函数,这样你就可以按照你熟悉的printf方式进行输出了。建议写到uart模块中,记得包含 stdio.h。
#include "stdio.h"int fputc(int ch, FILE *f) //֘¶¨ϲ Printf º¯ʽ
{HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);return ch;
}
俗话说,送佛送到西,我上传了整个工程文件,如果需要可以下载,定个4.9元钱吧,一瓶饮料的价钱。
STM32H743IITX和ADLX355BZ的SPI接口通信,MDK工程。-C文档类资源-CSDN下载
如果想自己写,那我把我的配置方法贴出来供大家参考!
最最最最最后!数据手册说ADXL355支持最大100MHz的SPI通信时钟,但是我用25MHz的时候数据就开始出错,后面找原因,是杜邦线太长了,SPI的通信距离最好在厘米级,进入分米级之后,会限制通信速率。可以开动脑筋想一想,如何尽可能地优化通信可靠性,提示:修改SPI句柄。
。
当你再次用CubeMX生成工程之后,你的自建模块依然在,但其余修改过的地方会复原,除非你写到它要你写到的地方,看着有点乱,所以我会把该工程另存到其他地方保护起来。然后需要配置其他外设的时候,用CubeMX重新生成代码后,搬移到模块中,或者直接用句柄配置。个人认为这样的CubeMX+keil5的编程方式较好。
学习笔记(1)stm32h743和ADXL355的SPI通信,基于cubeMX和keil5MDK平台,采用HAL库编程,代码已模块化处理相关推荐
- ESP8266学习笔记:实现ESP8266的局域网内通信
ESP8266学习笔记:实现ESP8266的局域网内通信 现在就以实例入手.工程使用的是IOT_DEMO,据DEMO文档可以知道ESP8266初始工作模式为softAP+station共存的模式.于是 ...
- K210学习笔记(三) K210与STM32进行串口通信,K210发STM收
文章目录 前言 一.以/r/n为结尾 二.K210端代码 三.STM32端 3.1 main函数 四.测试结果 4.1当收到1时 4.2当收到2时 4.3 测试视频 总结 前言 前面我们讲了STM32 ...
- 「Vue 学习笔记 1」Vue 项目快速搭建,初始项目各个文件夹作用介绍和启动代码执行流程分析
「Vue 学习笔记 1」Vue 项目快速搭建,初始项目各个文件夹作用介绍和启动代码执行流程分析 前言 一.我的开发环境 二.使用 Vue CLI (Vue 脚手架)快速搭建项目 三.初始项目的目录结构 ...
- malloc 源码_【C++学习笔记(九)】之 new运算符的使用/ new 与 malloc的异同(附代码,详细注释)...
new 运算符的使用 一. new的简单介绍: new运算符用于在堆区开辟空间,所有new出来的对象,对返回该类对象的指针. 二. new 与 malloc 的异同点: 1.malloc作用相同, m ...
- 【STC单片机学习】第十四课:SPI通信-实时时钟DS1302
[朱老师课程总结 侵删] 第一部分.章节目录 1.14.1.RTC有关的背景知识 1.14.2.原理图和接线 1.14.3.数据手册带读 1.14.4.时序图的读法1 1.14.5.编程实践1 1. ...
- Vue学习笔记05 组件的自定义事件-组件通信-$nextTick-脚手架解决ajax跨域-插槽-过渡动画
文章目录 Vue学习笔记05 父组件给子组件传值 注意点 子组件给父组件传值 父组件接受子组件的传值 通过函数 组件的自定义事件 事件绑定的第一种写法 @或v-on 事件绑定的第二种写法:使用ref ...
- 单片机学习笔记1--资料下载、环境搭建(基于百问网STM32F103系列教程)
第1篇 资料下载.环境搭建 第一章 百问网视频体系及学习路线 1.1课程视频变化 2011-2020:百问网录制了10年的Linux视频. 2021: 1.首次进入单片机领域,发布单片机课程! 2.重 ...
- STM32F407控制AD7606 采用HAL库的TIM和SPI
前言 本文介绍基于STM32F407的AD7606 8通道同步采集控制方式,总体思路:PWM驱动AD7606完成模数转换,AD7606转换完成后其BUSY引脚给出下降沿,STM32捕获外部中断并在中断 ...
- 学习笔记:Towards Counterfactual Image Manipulation via CLIP 基于CLIP的反事实图像处理研究
[ACM MM-2022] Towards Counterfactual Image Manipulation via CLIP 基于CLIP的反事实图像处理研究 1.背景 2. 方法 2.1 整体框 ...
最新文章
- Apache反向代理设置【转载】
- SQL Server-聚焦WHERE Column = @Param OR @Param IS NULL有问题?
- url采集工具_大数据关键技术浅谈之大数据采集
- 有多少种 “图片格式”?
- 自学Python八 爬虫大坑之网页乱码
- 跑步(【CCF】NOI Online能力测试 入门组第二题)
- 描述计算机专业导论课程的内容结构,计算机专业导论课程学习内容.doc
- java中注释如何换行,java注释中空格和换行符的处理
- 浏览网页隐藏图片 html,Html、Js实现网页图片切换及隐藏
- 防止短信接口验证码被恶意点击
- JD最新青龙面板+诺兰方舟星链计划对接傻妞芝士等机器人网页短信搭建教程+拉库教程+资产一对一推送教程
- js设置延时加载事件
- Hadoop IO 特性详解(1)【数据完整性】
- c++中static的用法详解
- SoapUI-一款强大的Rest和Soap测试工具
- 计算机任务无法结束,简单几步解决win7任务管理器无法结束进程的问题
- 福利贴:最全实时音视频开发要用到的开源工程汇总
- kelvin模型蠕变方程_机织建筑膜材料的广义Kelvin-Voigt蠕变模型
- LOJ#3086. 「GXOI / GZOI2019」逼死强迫症(矩阵快速幂)
- 拓嘉辰丰电商:拼多多店铺SUK如何设置
热门文章
- 2008之囧言囧语集合
- 红米note3 android go,离完美只差一步:MI 小米 红米Note5 智能手机 体验评测(含高通骁龙636性能测试)...
- 【CSDN AI周刊】第14期 | 吴恩达离职百度 CNN之父清华演讲
- 10个可爱的外国互动型网站
- Android OpenGL ES 应用(一)
- WPS文字转Word用什么软件
- 腾讯《QQ堂》上线17年,将于2022年4月20日停服
- project info:
- J2SE、J2EE、J2ME
- pythonic词源_python的意思在线翻译,解释python中文英文含义,短语词组,音标读音,词源【澳典网ODict.Net】...