Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
SPI
英飞凌Infineon
英飞凌XMC7200
英飞凌XMC7200评测 -SPI
发布于 2024-08-14 14:04:22 浏览:287
订阅该版
[tocm] # BSP修改与SPI配置 首先在board/Kconfig里面加入SPI配置 ~~~bash menuconfig BSP_USING_SPI bool "Enable SPI BUS" select RT_USING_SPI default n if BSP_USING_SPI menuconfig BSP_USING_SPI0 bool "Enable SPI0 BUS" default n menuconfig BSP_USING_SPI3 bool "Enable SPI3 BUS" default n if BSP_USING_SPI3 config BSP_USING_SPI3_SAMPLE bool "Enable SPI3 BUS Sample" default n endif menuconfig BSP_USING_SPI6 bool "Enable SPI6 BUS" default n endif ~~~ ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408141359940.png) 然后在menuconfig开启即可,但是需要修改一下drv_spi.c的引脚 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408130926156.png) 引脚修改成EVK上对应的引脚即可,我这里用的是Arduino接口上的SPI,也是官方例程使用的SPI。 配置与应用代码如下所示。 ~~~C /* * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2024-05-22 LZero first version */ #include
#include
#include "ADIS16467-2.h" #include "drv_gpio.h" #include "drv_spi.h" #include "rtdbg.h" #define DBG_LVL DBG_ #define LED_PIN GET_PIN(16, 1) #define LED2_PIN GET_PIN(16,2) rt_thread_t IMU_thread; ADIS16467_T adi_imu = {0}; void SPIRTTEST() { rt_pin_mode(GET_PIN(10, 3), PIN_MODE_OUTPUT); rt_kprintf("IMU Thread Start!\n"); struct rt_spi_configuration imu_config = { .data_width=16, .mode=RT_SPI_MASTER | RT_SPI_MODE_3 | RT_SPI_MSB, .max_hz=1000000 }; struct rt_spi_device* imu_device = (struct rt_spi_device*)rt_malloc(sizeof(struct rt_spi_device)); rt_spi_bus_attach_device_cspin(imu,"spi61","spi6",GET_PIN(10,3),RT_NULL); struct rt_spi_device *imu = (struct rt_spi_device *) rt_device_find("spi61"); if (!imu) { rt_kprintf("imu not found\n"); } else { rt_kprintf("imu found\n"); } rt_spi_configure(imu, &imu_config); adi_imu.spi_device = imu; ADIS16467_Init(&adi_imu); ADIS16467_Check(&adi_imu); ADIS16467_imuInfo(&adi_imu); rt_kprintf("IMU ProdID : %X", adi_imu.ProdId); rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT); while (1) { ADIS16467_Read_Temp(&adi_imu); ADIS16467_Read_Accel(&adi_imu); ADIS16467_Read_Gyro(&adi_imu); ADIS16467_Read_DeltaAngle(&adi_imu); rt_kprintf("Accel X :%f Accel Y: %f Accel Z: %f \n",adi_imu.ADIS_Accel.HP_Accel_X, adi_imu.ADIS_Accel.HP_Accel_Y,adi_imu.ADIS_Accel.HP_Accel_Z); // adi_imu.ADIS_Gyro.HP_Gyro_X, adi_imu.ADIS_Gyro.HP_Gyro_Y, adi_imu.ADIS_Gyro.HP_Gyro_Z, // adi_imu.ADIS_DeltaAng.HP_DeltaAngle_X, adi_imu.ADIS_DeltaAng.HP_DeltaAngle_Y,adi_imu.ADIS_DeltaAng.HP_DeltaAngle_Z); rt_thread_mdelay(500); } } int main(void) { spitest = rt_thread_create("spitest", SPIRTTEST, RT_NULL, RT_MAIN_THREAD_STACK_SIZE, 20, 20); rt_thread_startup(spitest); rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); for (;;) { rt_pin_write(LED_PIN, PIN_HIGH); rt_thread_mdelay(500); rt_pin_write(LED_PIN, PIN_LOW); rt_thread_mdelay(500); } } ~~~ # 实际使用 原计划使用SPI驱动ADIS16467-2,这是一个ADI的精密陀螺仪,在STM32上已经有完整实现,计划在本次实践中使用XMC7200嵌入RTT官方BSP,但是始终无法驱动起来。sendandsend函数逻分显示是正确的,但是 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810164228.png) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810164228.png) RTT BSP传输波形,不知道为什么会在后面有BA0,发送的是E880。 # 波形分析 使用ST官方HAL库,ADIS16467可正常运行,驱动链接:[GitHub - WwWangGuan/ADIS16467-2: ADIS16467-2的STM32驱动程序](https://github.com/WwWangGuan/ADIS16467-2) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810191157.png) 该函数使用的寄存器如图所示 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810191240.png) 正确的读取数据如下图所示 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810191439.png) 下图为逻分捕捉波形(rangeModel读取) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810191415.png) 即正常波形为:Master发送5E00,从机回答07 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810191607.png) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810191628.png) 接下来是写寄存器 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810191728.png) 此函数的目的是为了在开机时重启陀螺仪(写值0x1000 0000/0x80h) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810191844.png) 那么如何写一个寄存器呢?datasheet这么说 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810192129.png) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810192203.png) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810200227.png) 也就是说 对于每一个16位的数据,写寄存器之前先将最高位置1,然后加上寄存器地址到高八位,低八位是你要写的数据 来看看逻辑分析仪的波形 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810192726.png) 函数实现是这个样子 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810192502.png) 也明显,分成三步: 1. 地址先或一个0x80h(0x1000 0000),因为要写寄存器。 2. 地址左移8位,”或“上你的数据 3. 开始通信。 ## RTThread SPI设备驱动框架测试 上来就没绷住 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810204754.png) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810204758.png) 换用rt_spi_transfer,能发出去了,但是收不到 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810205832.png) ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810205857.png) 跟ST的HAL相比,设备驱动框架无论是transfer,send还是send_and_receive都比HAL慢的多 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408121513515.png) 上面有四帧数据,~~能看出来吗~~ 感觉是API调的不对,再换。 ~~~C void ADIS16467_Init(ADIS16467_T *imu) { // ADI_Write_Reg(imu, GLOB_CMD_REG, 0x80); //software reset // ADI_Write_Reg(imu, GLOB_CMD_REG + 1, 0x80); uint16_t send[2] = {((GLOB_CMD_REG | 0x80) << 8) | 0x80, (((GLOB_CMD_REG + 1) | 0x80) << 8) | 0x80}; uint16_t receive[2] = {0}; rt_spi_send_then_recv(imu->spi_device, send, 2, receive, 2); imu->K_G = 40; imu->KG_Reciprocal = (float) (1 / imu->K_G); rt_thread_mdelay(2000); // wait for reboot } ~~~ 这么写之后的波形是这样的,孩子怪可怜的 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408121533643.png) 对比HAL的波形 ~~~C void ADIS16467_Init(ADIS16467_T *imu) { uint16_t send[2] = {((GLOB_CMD_REG | 0x80) << 8) | 0x80, (((GLOB_CMD_REG + 1) | 0x80) << 8) | 0x80}; uint16_t receive[2] = {0}; HAL_SPI_TransmitReceive(imu->hspi, (uint8_t *) send, (uint8_t *) receive, 2, 0xFFFF); imu->K_G = 40; imu->KG_Reciprocal = (float) (1 / imu->K_G); HAL_Delay(4000); // wait for reboot } ~~~ 波形这个样子 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408121544664.png) 能看出来RTT跟HAL的处理方式截然不同,RTT是,我先把TX的东西发完,再收两个 但是只有这么写,波形才对,读出来的数据也是正确的 ~~~C void ADIS16467_Init(ADIS16467_T *imu) { ADI_Write_Reg(imu, GLOB_CMD_REG, 0x80); //software reset ADI_Write_Reg(imu, GLOB_CMD_REG + 1, 0x80); imu->K_G = 40; imu->KG_Reciprocal = (float) (1 / imu->K_G); HAL_Delay(4000); // wait for reboot } int8_t ADI_Write_Reg(ADIS16467_T *imu, uint8_t addr, uint8_t value) { addr |= 0x80; //写数据的掩码 uint16_t Tx_tmp = (addr << 8) | value; ADI_flame_TandR(imu, Tx_tmp); return 0; } uint16_t ADI_flame_TandR(ADIS16467_T *imu, uint16_t trans) { HAL_GPIO_WritePin(imu->GPIOx, imu->GPIO_PIN, 0); uint16_t result = 0; static HAL_StatusTypeDef state; state = HAL_SPI_TransmitReceive(imu->hspi, (uint8_t *) &trans, (uint8_t *) &result, 1, 0xFFFF); if (state != HAL_OK) { while (1); } HAL_GPIO_WritePin(imu->GPIOx, imu->GPIO_PIN, 1); sb_delay(500); return result; } ~~~ 就是发一次,停一下再发一次。 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408121543264.png) 使用rt_transfer ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408130856658.png) ~~~C uint16_t ADI_flame_TandR(ADIS16467_T *imu, uint16_t trans) { // HAL_GPIO_WritePin(imu->GPIOx, imu->GPIO_PIN, 0); uint16_t result = 0; // static HAL_StatusTypeDef state; // state = HAL_SPI_TransmitReceive(imu->hspi, (uint8_t *) &trans, (uint8_t *) &result, 1, 0xFFFF); // if (state != HAL_OK) { // while (1); // } // HAL_GPIO_WritePin(imu->GPIOx, imu->GPIO_PIN, 1); // rt_spi_send_then_recv(imu->spi_device, &trans, 1, &result, 1); rt_spi_transfer(imu->spi_device, &trans, &result, 1); return result; } ~~~ 还是慢,两次transfer时间相差15ms ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408130858604.png) HAL对比,函数使用HAL_SPI_TransmitReceive,两次传输时间相差39$\mu s$,怪离谱的。 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408130904775.png) 尝试提升线程优先级? ~~~C int main(void) { spitest = rt_thread_create("spitest", SPIRTTEST, RT_NULL, 4096, 20, 20); rt_thread_startup(spitest); /* set LED2 pin mode to output */ rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT); while (1) { rt_pin_write(LED2_PIN, PIN_HIGH); rt_thread_mdelay(500); rt_pin_write(LED2_PIN, PIN_LOW); rt_thread_mdelay(500); }} ~~~ priority改成10?试了,没用,这真的慢。 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/202408130914709.png) 换用rt_spi_transfer_message,有效 ~~~C uint16_t ADI_flame_TandR(ADIS16467_T *imu, uint16_t trans) { // HAL_GPIO_WritePin(imu->GPIOx, imu->GPIO_PIN, 0); uint16_t result; struct rt_spi_message msg1,msg2; msg1.send_buf = &trans; msg1.recv_buf = &result; msg1.length = 1; msg1.cs_take = 1; msg1.cs_release = 1; msg1.next = RT_NULL; rt_spi_transfer_message(imu->spi_device,&msg1); // rt_spi_transfer(imu->spi_device,&trans,&result,2); // sb_delay(200); return result; } ~~~ 读取成功 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/20241011210657.png) 接下来console输出加速度和角速度值(rt_krpintf输出浮点数需要安装全功能软件包),但是debug下是好使的 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/20241011211502.png) 串口输出结果 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/20241011211935.png)
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
WwWangGuanHeR
这家伙很懒,什么也没写!
文章
1
回答
0
被采纳
0
关注TA
发私信
相关文章
1
BBB的SPI驱动
2
求个SPI上挂两个或多个设备的使用例子
3
SPI设备有个bug
4
spi flash 的fatfs使用一段时间后读写文件出现故障
5
SPI驱动
6
请教rt_spi_configure函数理解
7
SPI FLASH挂载的问题
8
SPI-FLASH 文件系统 SPIFFS
9
求助一个完整的 spi flash 驱动
10
关于同时使用文件系统与SPI FLASH的问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
7
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
3
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部