IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【GD32F310 开发板试用】三轴加速度计的使用 -> 正文阅读

[嵌入式]【GD32F310 开发板试用】三轴加速度计的使用

首发极术社区。如对兆易创新GD32F310 MCU感兴趣,欢迎添加微信 aijishu2020 加入GD32技术讨论群。

非常感谢极术社区和GigaDevice 给我机会可以进行 GD32F310G-START 开发板的试用,也感谢极术小姐姐,物流非常给力。

我拿到的开发板实际板载的 MCU 是 GD32F310G8,QFN28pin 封装,基于 ARM CORTEX M4 内核,主频 72MHz, 芯片内置 64KB flash,8KB SRAM, 两路 I2C 外设。

整体概述

首先感谢极术社区给我试用GD32开发板的机会,让我体验一下近几年国产MCU开发体验。该芯片是基于arm cortex-M4内核,主频72Mhz,flash 64k,ram 8k,以及丰富的外设。

本次试用是一个读取三轴加速度计的实验,主要使用的是硬件iic。

硬件连接

如下图所示
cc15ac20cc51a78ba47c65a03ece4a4.jpg

传感器介绍

SC7A20 是一款高精度 12bit 数字三轴加速度传感器芯片,内置功能 更丰富,功耗更低,体积更小,测量更精确。

芯片通过 IC2/SPI 接口与 MCU 通信,加速度测量数据以中断方式或 查询方式获取。INT1和INT2中断管脚提供多种内部自动检测的中断信号, 适应多种运动检测场合,中断源包括 6D/4D 方向检测中断信号、自由落体 检测中断信号、睡眠和唤醒检测中断信号、单击和双击检测中断信号。芯 片内置高精度校准模块,对传感器的失调误差和增益误差进行精确补偿。 ±2G、±4G、±8G 和±16G 四种可调整的全量程测量范围,灵活测量外 部加速度,输出数据率 1HZ 和 400HZ 间可选。

软件功能

该软件主要使用了GD32开发板的硬件iic,外部中断以及串口,这三部分功能,串口的配置在其他文章的当中已经有叙述,本文只主要介绍iic和外部中断的使用.
硬件iic

初始化gpio
在这里插入图片描述

配置硬件iic
image.png

根据厂商提供的库函数(具体参考gd32f3x0_i2c.c文件),我们可以很容易的初始化iic。剩下的就是对传感器进行配置了,该传感器需要配置寄存器较多,厂商直接提供了一份demo程序,只需要适配读取写入的接口就可以很快的使用了。
image.png
我需要做的就是把iic的读取和写入进行适配适配函数如下:

void I2C_LeaderWrite(uint16_t followerAddress, , uint8_t targetAddress, uint8_t *txBuff,
                     uint8_t numBytes) {
    /* wait until I2C bus is idle */
    while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY))
        ;
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C0);
    /* wait until SBSEND bit is set */
    while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
        ;
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C0, followerAddress, I2C_TRANSMITTER);
    /* wait until ADDSEND bit is set */
    while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
        ;
    /* clear ADDSEND bit */
    i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
    /* wait until the transmit data buffer is empty */
    while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
        ;

    for (i = 0; i < numBytes; i++) {
        /* data transmission */
        i2c_data_transmit(I2C0, txBuff[i]);
        /* wait until the TBE bit is set */
        while (!i2c_flag_get(I2C0, I2C_FLAG_TBE))
            ;
    }
    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2C0);
    /* wait until stop condition generate */
    while (I2C_CTL0(I2C0) & 0x0200)
        ;
}
void I2C_LeaderRead(uint16_t followerAddress, uint8_t targetAddress, uint8_t *rxBuff,
                    uint8_t numBytes) {
    /* wait until I2C bus is idle */
    while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY))
        ;

    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C0);

    /* wait until SBSEND bit is set */
    while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
        ;

    /* send slave address to I2C bus */
    i2c_master_addressing(I2C0, followerAddress, I2C_TRANSMITTER);

    /* wait until ADDSEND bit is set */
    while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
        ;

    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);

    /* wait until the transmit data buffer is empty */
    while (SET != i2c_flag_get(I2C0, I2C_FLAG_TBE))
        ;

    /* enable I2C0*/
    i2c_enable(I2C0);

    /* send the EEPROM's internal address to write to */
    i2c_data_transmit(I2C0, targetAddress);

    /* wait until BTC bit is set */
    while (!i2c_flag_get(I2C0, I2C_FLAG_BTC))
        ;

    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C0);

    /* wait until SBSEND bit is set */
    while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND))
        ;

    /* send slave address to I2C bus */
    i2c_master_addressing(I2C0, followerAddress, I2C_RECEIVER);

    /* wait until ADDSEND bit is set */
    while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
        ;

    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);

    /* while there is data to be read */
    for (int i = 0; i < numBytes; i++) {
        /* code */

        /* read a data from I2C_DATA */
        rxBuff[i++] = i2c_data_receive(I2C0);
        /* send a stop condition */
        i2c_stop_on_bus(I2C0);
    }

    /* wait until the stop condition is finished */
    while (I2C_CTL0(I2C0) & 0x0200)
        ;

    /* enable acknowledge */
    i2c_ack_config(I2C0, I2C_ACK_ENABLE);

    i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
}

然后把这两个函数适配:
image.png

然后对传感器进行设置
image.png

外部中断
使用外部中断可以使用用于唤醒mcu,这对设计低功耗的产品很有意义,当传感器超过设定的阈值的时候,那么就会产生一个中断来通知mcu,需要进一步的处理数据,外部中断的配置如下所示:

void exit_wakeup_interrupt_config(void)
{
     /* configure the priority group */
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);

    /* enable the key wakeup clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_CFGCMP);

    /* configure button pin as input */
    gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0);

    /* enable and set key wakeup EXTI interrupt to the higher priority */
    nvic_irq_enable(EXTI0_1_IRQn, 2U, 0U);

    /* connect key wakeup EXTI line to key GPIO pin */
    syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN0);

    /* configure key wakeup EXTI line */
    exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
    exti_interrupt_flag_clear(EXTI_0);
}

数据处理

由于我们使用的是三轴传感器,对于姿态位置的计算并不是很精确,因此,此处只用简单角度计算,倾角的计算原理如下
image.png

计算代码如下:

#define DEG_TO_RAD(x) ((x) * 0.01745329252)
#define RAD_TO_DEG(x) ((x) * 57.2957795131)
void angle_calculation() {
    double pitch, roll, paw;
    pitch = atan(xyz_mg[X] / sqrt(pow(xyz_mg[Y], 2) + pow(xyz_mg[Z], 2)));
    roll = atan(xyz_mg[Y] / sqrt(pow(xyz_mg[X], 2) + pow(xyz_mg[Z], 2)));
    paw = atan(sqrt(pow(xyz_mg[X], 2) + pow(xyz_mg[Y], 2)) / xyz_mg[Z]);

    printf("[RAD]pitch:%.2f | roll:%.2f | paw:%.2f \r\n", pitch, roll, paw);
    printf("[DEG]pitch:%.2f° | roll:%.2f° | paw:%.2f° \r\n", RAD_TO_DEG(pitch), RAD_TO_DEG(roll),
           RAD_TO_DEG(paw));
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:49:03  更:2022-05-18 17:49:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 1:16:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码