Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
SPI
英飞凌Infineon
英飞凌XMC7200
英飞凌XMC7200评测 -SPI
发布于 2024-08-14 14:04:22 浏览:175
订阅该版
[tocm] 看的舒服点的链接,~~论坛这个格式调起来好抽象~~ https://wwwangguan.github.io/2024/08/09/qian-ru-shi-ruan-jian/rt-thread/xmc7200evk-spi/ # 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 ``` ![screenshot_202408141359940.png](https://oss-club.rt-thread.org/uploads/20240909/815801e062097060599b146569d5166e.png) 然后在menuconfig开启即可,但是需要修改一下drv_spi.c的引脚 ![screenshot_202408130926156.png](https://oss-club.rt-thread.org/uploads/20240909/a9df0f9d7949247586d65aef41a4f724.png.webp) 引脚修改成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 spitest; ADIS16467_T adi_imu = {0}; void SPIRTTEST() { // LOG_D("SPIRTTEST\n"); rt_pin_mode(GET_PIN(10, 3), PIN_MODE_OUTPUT); rt_kprintf("SPIRTTEST\n"); struct rt_spi_configuration imu_config = { .data_width=16, .mode=RT_SPI_MASTER | RT_SPI_MODE_3 | RT_SPI_MSB, .max_hz=1000000 }; // rt_hw_spi_device_attach("spi6", "spi61", GET_PIN(10, 3)); struct rt_spi_device *imu = (struct rt_spi_device *) rt_device_find("spi61"); if (!imu) { LOG_E("imu not found\n"); } else { // LOG_D("imu found\n"); rt_kprintf("imu found\n"); } rt_spi_bus_attach_device_cspin(imu,"spi61","spi6",GET_PIN(10,3),RT_NULL); rt_spi_configure(imu, &imu_config); adi_imu.spi_device = imu; %% uint16_t send[1]={0x1234}; rt_spi_send(imu,send,1); %% 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) { rt_pin_write(LED2_PIN, PIN_HIGH); rt_thread_mdelay(500); rt_pin_write(LED2_PIN, PIN_LOW); 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); rt_kprintf("Hello World!\n"); 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函数逻分显示是正确的,但是 ![screenshot_Pasted image 20240810164228.png](https://oss-club.rt-thread.org/uploads/20240909/d62d91a44ca281cbce182e429cc86117.png.webp) RTT BSP传输波形,不知道为什么会在后面有BA0,发送的是E880。 # 波形分析 使用ST官方HAL库,ADIS16467可正常运行,驱动链接:[GitHub - WwWangGuan/ADIS16467-2: ADIS16467-2的STM32驱动程序](https://github.com/WwWangGuan/ADIS16467-2) ![screenshot_Pasted image 20240810191157.png](https://oss-club.rt-thread.org/uploads/20240909/4f90909bd0879dd86db96b39bc1ed01b.png.webp) 该函数使用的寄存器如图所示 ![screenshot_Pasted image 20240810191240.png](https://oss-club.rt-thread.org/uploads/20240909/cb1cf846e51a4462533929a2cfba4000.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设备驱动框架测试 上来就没绷住 ![screenshot_Pasted image 20240810204754.png](https://oss-club.rt-thread.org/uploads/20240909/57acd326f6e97af3b8a117ff8e4c751e.png) ![screenshot_Pasted image 20240810204758.png](https://oss-club.rt-thread.org/uploads/20240909/2a5ed789bd205486d85e92999909167a.png) 换用rt_spi_transfer,能发出去了,但是收不到 ![screenshot_Pasted image 20240810205832.png](https://oss-club.rt-thread.org/uploads/20240909/283fa7cdf46c475d2da09c9c1a916886.png) ![screenshot_Pasted image 20240810205857.png](https://oss-club.rt-thread.org/uploads/20240909/37880c38d1efbc1eeef0ae27165f5e46.png) 跟ST的HAL相比,设备驱动框架无论是transfer,send还是send_and_receive都比HAL慢的多 ![screenshot_202408121513515.png](https://oss-club.rt-thread.org/uploads/20240909/de7c1ce5bf0f7e6388dee39b61340d04.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 } ``` 这么写之后的波形是这样的,孩子怪可怜的 ![screenshot_202408121533643.png](https://oss-club.rt-thread.org/uploads/20240909/ba9a9f3c1f88a72101f97011ec3d997f.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) # EVK板载QSPI Flash 换用QSPI,更换逻分之后再尝试 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810170117.png) 原理图如图所示,型号为S25FL512SAGMFMR10,英飞凌自己家的,参数挺好 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810170337.png) 引脚映射在下图 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810170201.png) 使用SPI0/SPI3模式 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810170802.png) 支持SFDP,这下好办了,可以直接使用RTT的SFUD ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810171424.png) ## Kconfig文件修改 添加以下内容 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810171833.png) scons重新生成cmakelist之后提示 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810172000.png) 尝试 pkgs -Update,发现无效 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810172154.png) 尝试在menucongfig中启用对应软件包,该软件包对此报错无效,且在HAL中无法找到此文件 ![](https://raw.githubusercontent.com/WwWangGuan/pics/main/Pasted%20image%2020240810180618.png) 问题:有对应的头文件,但是其实现却在drv_flash.c中,疑似官方错误,英飞凌的官方包也没有这个东西,在cmakelist中删除文件后能通过编译,但是AC6编译未能通过。
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
机器人操作系统 (ROS2) 和 RT-Thread 通信
4
国产MCU移植系列教程汇总,欢迎查看!
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总线
ART-Pi
FinSH
USB
文件系统
DMA
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
ESP8266
I2C_IIC
ota在线升级
WIZnet_W5500
UART
flash
packages_软件包
cubemx
PWM
freemodbus
BSP
潘多拉开发板_Pandora
定时器
ADC
中断
flashDB
socket
Debug
GD32
编译报错
msh
keil_MDK
rt_mq_消息队列_msg_queue
C++_cpp
at_device
MicroPython
ulog
本月问答贡献
rv666
7
个答案
2
次被采纳
踩姑娘的小蘑菇
5
个答案
2
次被采纳
张世争
8
个答案
1
次被采纳
用户名由3_15位
7
个答案
1
次被采纳
zchong
6
个答案
1
次被采纳
本月文章贡献
Licy
3
篇文章
1
次点赞
rtt_dmx
1
篇文章
5
次点赞
jaffer
1
篇文章
5
次点赞
flytianya2010
1
篇文章
2
次点赞
BRICK PORTER
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部