HAL库控制STM32F103C8T6微控制器通过I2C接口读取ADXL345加速度传感器的数据

ADXL345三轴加速度传感器

详细的代码和cubemx的配置附后,请需要的同学们直接拉到后面。

特性:
  1. 可选分辨率:10位固定分辨率,13位全分辨率。
  2. 数字输出位16位二进制补码格式。
特殊检测功能
  1. 活动和非活动检测功能通过比较任意轴上的加速度与用户设置的阈值来检测有无运动发生。
  2. 敲击检测功能可以检测任意方向的单振和双振动作。
  3. 自由落体检测功能可以检测器件是否正在掉落。

这些功能可以独立映射到两个中断输出引脚中的一个

引脚配置和功能描述:
image-20240808092511448
引脚功能描述:
引脚编号引脚名称描述
1VDD数字接口电源电压
2GND接地
3保留
4GND接地
5GND接地
6vs电源电压
7CS片选
8INT1中断1输出
9INT2中断2输出
10NC内部不练接
11保留
12SDO/ALT ADDRESS串行数据输出(SPI 4线)/备用I2C地址选择(I2C
13SDA/SDI/SDIO串行数据(I2C)/串行数据输入(SPI 4线)/串行数据输入和输出(SPI 3线)。
14SCL/SCLk串行通信时钟。 SCL为I2C时钟, SCLK为SPI时钟
工作原理

既能测量运动或冲击导致的动态加速度,也能测量静止加速度,例如重力加速度,使得器件可作为倾斜传感器使用

施加VS,器件进入待机模式,此时功耗最小。

器件等待施加V DD I/O和接收进入测量模式的命令。(此命令可以通过设置POWER_CTL寄存器(地址0x2D)的测量位(位D3)启动。)此外,器件处于待机模式时,任何寄存器可以写入或读取,以配置器件。建议在待机模式配置器件,然后使能测量模式。清除测量位,器件返回到待机模式。

电源时序
条件VSVDD描述
关断该器件完全关断,但可能存在通信总线冲突
总线禁用该器件开启,进入待机模式,但通信不可用,并且与通信总线冲突
总线使能无功能可用,但该器件不会与通信总线冲突
待机或测量模式上电时,器件处于待机模式,等待进入测量模式的命令,所有传感器功能关闭。该器件得到指示后进入测量模式,所有的传感器功能都可用
低功耗模式:

要进入低功耗模式,在BW_RATE寄存器(地址0x2C)中设置LOW_POWER位(位4)。

自动休眠模式

如果ADXL345在静止期间自动切换到休眠模式,可以省电。要使能此功能,在THRESH_INACT寄存器(地址0x25)和TIME_INACT寄存器(地址0x26)设置一个值表示静止(适当值视应用而定),然后在POWER_CTL寄存器(地址0x2D)中设置AUTO_SLEEP位(位D4)和链接位(位D5)。

待机模式

更低功率操作,也可以使用待机模式。待机模式下,功耗降低到0.1 μA(典型值)。该模式中,无测量发生。在POWER_CTL寄存器(地址0x2D)中,清除测量位(位D3),

串行通信

可采用I2C和SPI数字通信。上述两种情况下, ADXL345作为从机运行。 CS引脚上拉至V DD I/O, I2C模式使能。 CS引脚应始终上拉至V DD I/O或由外部控制器驱动,因为CS引脚无连接时,默认模式不存在。因此,如果没有采取这些措施,可能会导致该器件无法通信。 SPI模式下, CS引脚由总线主机控制。 SPI和I2C两种操作模式下, ADXL345写入期间,应忽略从ADXL345传输到主器件的数据

这个器件可以使用IIC和SPI,因我我选择使用的IIC所以只有IIC的东西,关于SPI请大家自行了解。

IIC

1口和7口都接3.3V,

PB7<---->13 //数据线

PB6<---->14 //信号线

设备地址:0x53

因为是HAL库开发,所以只要配置好cubemx就只需在main.c中收发即可。

1、使用I2C1

默认即可

2、打开串口(uarrt1)

波特率和你串口调试助手设置一样即可(通常连接电脑的串口一般都设置为115200)

3、时钟图

4、一些注意事项

<img src="C:\Users\小胖\AppData\Roaming\Typora\typora-user-images\image-20240808234537692.png" alt="image-20240808234537692" style="zoom:50%;" />

5、生成代码

点击完之后会跳出来一个提示框,选择打开项目,他自己直接就跳到keil中了。

6、进入keil的第一件事情就是重定义printf
int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,HAL_MAX_DELAY);//循环发送,直到发送完毕

    return ch;
}

将这段代码加在main.c中,点击魔术棒,按照下图勾选**(很多情况下,串口不打印都是这个地方没勾选)**

并且添加头文件#include "stdio.h"

如果你嫌麻烦直接全选附后代码,我将整个main.c复制过来了。直接替换你的.c 文件即可

找到了一段可以不勾选的代码,但是报错,还没解决。(就先用这个吧)

7、附一张串口输出

8、main.c代码
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#define ADXL345_ADDR 0x53
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,HAL_MAX_DELAY);//循环发送,直到发送完毕

    return ch;
}

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_TIM3_Init();
    MX_USART1_UART_Init();
    MX_I2C1_Init();
    /* USER CODE BEGIN 2 */
    printf("串口测试行hello 全西安最帅的嵌入式Linux工程师\n");


// 启用测量模式
    uint8_t data[] = {0x2D, 0x08}; // 寄存器0x2D,值0x08表示启用测量
    HAL_I2C_Master_Transmit(&hi2c1, ADXL345_ADDR << 1, data, 2, HAL_MAX_DELAY);

    //uint8_t buf[100] = {0};
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        // 读取加速度数据
uint8_t regAddr = 0x32; // 加速度数据起始寄存器地址
uint8_t dataRaw[6]; // 6个字节分别存储X、Y、Z轴的加速度数据

HAL_I2C_Master_Transmit(&hi2c1, ADXL345_ADDR << 1, &regAddr, 1, HAL_MAX_DELAY);
HAL_I2C_Master_Receive(&hi2c1, ADXL345_ADDR << 1, dataRaw, 6, HAL_MAX_DELAY);

int16_t accelerometer_data[3]; // 存储解析后的加速度数据

accelerometer_data[0] = (int16_t)((dataRaw[1] << 8) | dataRaw[0]); // X轴数据
accelerometer_data[1] = (int16_t)((dataRaw[3] << 8) | dataRaw[2]); // Y轴数据
accelerometer_data[2] = (int16_t)((dataRaw[5] << 8) | dataRaw[4]); // Z轴数据
printf("x = %d\n",accelerometer_data[0]);
			printf("y = %d\n",accelerometer_data[1]);
			printf("z = %d\n",accelerometer_data[2]);
        HAL_Delay(1000);
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /** Initializes the RCC Oscillators according to the specified parameters
    * in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }

    /** Initializes the CPU, AHB and APB buses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        Error_Handler();
    }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    __disable_irq();
    while (1)
    {
    }
    /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

  • 30
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM32F103C8T6是一款基于ARM Cortex-M3内核的微控制器,而ADXL345是一款低功耗、三轴加速度传感器。要在这款STM32读取ADXL345数据,你需要完成以下几个步骤: 1. **硬件连接**: - 将ADXL345的SCL和SDA线连接到STM32I2C通信接口。 - 如果ADXL345需要外部电源,确保供电稳定。 2. **初始化I2C**: - 配置I2C模块,包括设置时钟速率、地址(通常是0x53或0x1D,取决于模式)等。 3. **打开I2C通信**: - 发起从设备(ADXL345)的读取请求。 4. **数据传输和读取**: - 使用I2C的`read()`或`receive()`函数读取传感器的命令字节(如测量启动)以及数据结果。 5. **处理数据**: - ADXL345通常会返回三个轴的加速度值,解析并转换成合适的单位(比如g)。 6. **数据存储和显示**: - 把读取到的加速度数据保存在STM32的内存里,然后如果需要,可以在LCD、LED或其他外设上显示。 下面是一个简单的伪代码示例: ```cpp #include "stm32f1xx_hal.h" #include <i2c.h> #include "adxl345.h" void readAdxl345(void) { I2C_HandleTypeDef hi2c; uint8_t data; // 初始化I2C HAL_I2C_Init(&hi2c); // 发送读取命令 writeCommand(ADXL345_MEASURE_CMD); // 读取数据 HAL_I2C_Master_Transmit(&hi2c, ADXL345_ADDRESS, (uint8_t*)data, 6, 1000); // 解析数据并处理 float x = convertData(data, data); float y = convertData(data[2], data); float z = convertData(data, data); // 存储和显示数据... }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牲码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值