在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。
硬件连接
传感器介绍
sc7a20 是一款高精度 12bit 数字三轴加速度传感器芯片,内置功能 更丰富,功耗更低,体积更小,测量更精确。
芯片通过 ic²/spi 接口与 mcu 通信,加速度测量数据以中断方式或 查询方式获取。int1和int2中断管脚提供多种内部自动检测的中断信号, 适应多种运动检测场合,中断源包括 6d/4d 方向检测中断信号、自由落体 检测中断信号、睡眠和唤醒检测中断信号、单击和双击检测中断信号。
芯片内置高精度校准模块,对传感器的失调误差和增益误差进行精确补偿。 ±2g、±4g、±8g 和±16g 四种可调整的全量程测量范围,灵活测量外 部加速度,输出数据率 1hz 和 400hz 间可选。
软件功能
该软件主要使用了gd32开发板的硬件iic,外部中断以及串口,这三部分功能,串口的配置在其他文章的当中已经有叙述,本文只主要介绍iic和外部中断的使用.
硬件iic
初始化gpio  
配置硬件iic
根据厂商提供的库函数(具体参考gd32f3x0_i2c.c文件),我们可以很容易的初始化iic。剩下的就是对传感器进行配置了,该传感器需要配置寄存器较多,厂商直接提供了一份demo程序,只需要适配读取写入的接口就可以很快的使用了。
我需要做的就是把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);}  
然后把这两个函数适配:
然后对传感器进行设置
外部中断
使用外部中断可以使用用于唤醒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);}  
数据处理
由于我们使用的是三轴传感器,对于姿态位置的计算并不是很精确,因此,此处只用简单角度计算,倾角的计算原理如下
计算代码如下:
#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 rn, pitch, roll, paw); printf([deg]pitch:%.2f° | roll:%.2f° | paw:%.2f° rn, rad_to_deg(pitch), rad_to_deg(roll), rad_to_deg(paw));}


工业机器人产业企业纷纷进入内部转型期
选用合格的电线电缆对于生产生活安全来说是必要的
上新!QR码扫描单元与迷你称重单元
中国人民银行参事李德议 加密货币等虚拟资产或将被纳入民法
华为AI智能音箱2拆解评测 融合了1代与Sound X的支持传音的音箱
在GD32F310G-START开发板上读取三轴加速度计
用芯连接,渠道共创 | 2023英特尔中国区数据中心渠道客户会高能集锦
雷克沙推出新款SSD,读取速度之快可达7GB/s
地板清洁小秘方 蒸汽拖把品牌排行榜
硬件市场冷淡?看看小米6孔插线板就知道了!
无线应用在医院病房监测应用
表贴栈接连接器插头脱落问题讨论
如何为电子产品选择合适的充电器IC?
派克Parker防爆伺服电机使用环境及防爆等级
半导体制造中的清洗工艺技术改进方法
适用于多媒体电脑的功放及音箱
AGV小车自主视觉避障专用SOC设计方案
红外测温枪额温枪方案参数与校准方式分析
油田注水系统中TD2000变频器的应用研究
如何知道电动牙的防水性或密封性是否达到要求