Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
国民技术_N32G45x
N32G45x MDK下使用出现的问题【解决SPI数据收发问题】
发布于 2022-03-25 14:20:49 浏览:1052
订阅该版
[tocm] 据说,安装完 Nationstech.N32G45x_DFP.1.0.4 包之后,就可以使用MDK进行开发了。 ## 一、缺少文件 之前也在群里吵炸了,说这个装不上,那个装不上的,但是个人的计算机上是可以正常安装的。由于本次搞那个457开发板时,用的是RT-thread studio进行开发的,对这个事情也没有太过于关心。 这不,这次自己做了一个455的板了,studio里面没有现成的模板了,就基于MDK来搞一下。使用MDK进行开发时,发现如果使用RTE进行配置的话,会出现问题,在复制文件时出现错误。 ![image.png](https://oss-club.rt-thread.org/uploads/20220325/41024e78fdbb73bb64494e9e0cc67821.png) 打开一看,这个目录下,就不有那个文件夹,怎么可能复制成功呢? 看了一下里面的文件,基本上就是下载算法,啥也没有呀! ## 二、复制文件 打开2.0的库文件一看,里面有个文件夹和那个名字一样。 ![image.png](https://oss-club.rt-thread.org/uploads/20220325/99a200c5cfd48fec9e6616207dcb215d.png) 不管它37-21的,先来个CV大法,搞过去,工程都不让哥快乐的建立,还搞啥子呢? ![image.png](https://oss-club.rt-thread.org/uploads/20220325/1f055d09a34a824af09d173afad2d543.png) 这下可以建立工程啦 ![image.png](https://oss-club.rt-thread.org/uploads/20220325/4ac05bc9047cc31651a1688569274635.png) 当然,可以基于库里的工程进行复制进行开发,还可以使用RTT中的bsp进行开发。 但是经过文件对比,发现bsp里面的库,好像不是最新的,又看了一下studio里面的库文件,发现和2.0的还真的是不一样的。 因此,可以认为,BSP中的库文件和studio的库文件,都没有更新到2.0。 过会试一下,使用2.0的库文件进行全面覆盖,会不会有影响,先写到这里。 ## 三、屏蔽报警 要选上这个,不然会有一警告出现。 ![image.png](https://oss-club.rt-thread.org/uploads/20220325/a051a58c474bcd8d913e71f635f3b5f1.png) ## 四、开启FPU 开FPU,很多地方地说选择上就可以了,但实际看代码里面,并非如此呀。点来点去,死活就是没有开呀。V5的编译器很扯,下面这个直接就跳过了,V6的编译器,还好一点,下面的代码可以编译进来,但是m4.h中的__FPU_USED定义还是0,说明没有生效呀,这个宏别的地方还有用呢。 ```c #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10 and CP11 Full Access */ #endif ``` 于是这里就有两种方法来搞,第一种,简单粗爆型,直接给C/C++中直接定义好,__FPU_PRESENT=1,__FPU_USED =1。注意要写全了 ![image.png](https://oss-club.rt-thread.org/uploads/20220325/8297d173373875903670076866e24fc2.png) 第二种方法,上面那个是肯定是脚本里面加进来的嘛,肯定在哪个脚本里面有那么一个定义,直接找到目录下的脚,打开看看,哪个能对上的,发现有好几个文件都有出现CPPDEFINES = ['xxx'] 等字样,对了,就是它,给它加上就可以了,自动加上,不用再手写了。如图所示,加在了board文件夹下的脚本 ![image.png](https://oss-club.rt-thread.org/uploads/20220326/baf5a98c2d5b7086b7eee617532a5333.png) ## 五、悲剧的 SPI3 被这个搞得要崩溃,搞到开始怀疑人生,jtag_sw那个已搞过,只有sw功能,剩下的引脚可用,SPI3=PB3,4,5。有msp.c里面也加了相关的初始化代码。参考了网上的文章和库文件中带的代码,最终还是没有搞好,本来一个很简单的东西,怎么就这么费劲了呢?很郁闷呀。 ```c //---------------------------------spi --------------------------------// #ifdef BSP_USING_SPI void n32_msp_spi_init(void *Instance) { GPIO_InitType GPIO_InitCtlStruct; SPI_Module *SPIx = (SPI_Module *)Instance; GPIO_InitStruct(&GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_50MHz; #ifdef BSP_USING_SPI1 if (SPI1 == SPIx) { RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_SPI1, ENABLE); #if defined (BSP_USING_SPI1_PIN_RMP1) //PA15,PB3,4,5 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP1_SPI1, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_15; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_3 | GPIO_PIN_5; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_4; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); #elif defined (BSP_USING_SPI1_PIN_RMP2) //PB2,PA5,6,7 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP2_SPI1, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_2; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_5 | GPIO_PIN_7; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_6; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); #elif defined (BSP_USING_SPI1_PIN_RMP3) //PB2,PE7,8,9 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOE, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP3_SPI1, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_2; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_7 | GPIO_PIN_9; GPIO_InitPeripheral(GPIOE, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_8; GPIO_InitPeripheral(GPIOE, &GPIO_InitCtlStruct); #else //PA4,5,6,7 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_4; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_5 | GPIO_PIN_7; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_6; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); #endif } #endif #ifdef BSP_USING_SPI2 if (SPI2 == SPIx) { RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_SPI2, ENABLE); #if defined (BSP_USING_SPI1_PIN_RMP1) //PC6,7,8,9 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP1_SPI2, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_6; GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_7 | GPIO_PIN_9; GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_8; GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); #elif defined (BSP_USING_SPI2_PIN_RMP2) //PE10,11,12,13 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOE, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP2_SPI2, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_10; GPIO_InitPeripheral(GPIOE, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_11 | GPIO_PIN_13; GPIO_InitPeripheral(GPIOE, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_12; GPIO_InitPeripheral(GPIOE, &GPIO_InitCtlStruct); #else //PB12,13,14,15 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_12; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_13 | GPIO_PIN_15; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_14; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); #endif } #endif #ifdef BSP_USING_SPI3 if (SPI3 == SPIx) { RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_SPI3, ENABLE); #if defined (BSP_USING_SPI3_PIN_RMP1) //PD2,PC10,11,12 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP1_SPI3, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOD, ENABLE); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_2; GPIO_InitPeripheral(GPIOD, &GPIO_InitCtlStruct); #endif RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_10 | GPIO_PIN_12; GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_11; GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); #elif defined (BSP_USING_SPI3_PIN_RMP2) //PD8,9,11,12 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP2_SPI3, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOD, ENABLE); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_8; GPIO_InitPeripheral(GPIOD, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_9 | GPIO_PIN_12; GPIO_InitPeripheral(GPIOD, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_11; GPIO_InitPeripheral(GPIOD, &GPIO_InitCtlStruct); #elif defined (BSP_USING_SPI3_PIN_RMP3) //PC2,3,PA0,1 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP3_SPI3, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_2; GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_3; GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.Pin = GPIO_PIN_1; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_0; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); #else //PA15,PB3,4,5 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); #if defined (BSP_USING_SPI_NSS_PIN) RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_15; GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); #endif GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitCtlStruct.Pin = GPIO_PIN_3 | GPIO_PIN_5; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitCtlStruct.Pin = GPIO_PIN_4; GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); #endif } #endif /* Add others */ } #endif /* BSP_USING_SPI */ ``` 发现的问题是,这个SPI3接了flash,卡死在spixfer接收数据那块,没有收到返回的数据。永久性地,死在了这里,没有反应了。 ``` /* Wait for SPIy data reception */ while (SPI_I2S_GetStatus(spi_drv->config->module, SPI_I2S_RNE_FLAG) == RESET); ``` 这里也暴露了一个问题,这个驱动肯定是不完善的,怎么允许因为一个外设的问题,导致系统都死掉了呢? 如果没有记错的话,这种死循环,一般都会加入循环次数限制,超过次数了,退出,报错上来,别卡死呀。 下周再看一下是什么地方出现问题,有没有大牛给指点一下呀,谢谢。 **六、真真正正正正真真能用的SPI3驱动** 2022-03-28 不要和俺说啥子网上有,那个自带的drv_spi测试过了,在455片子上真的不能用哦。网上小伙伴都说自己通过了,搞得我怀疑人生了,啥子情况?这么简单的spi口哥都搞不定了? 百般无奈之下,求助国民技术的技术支持。原来的SPI驱动去初始化SPI3会有问题,时钟都不发了,还通信个啥子哦。在国民技术的技术支持,对SPI_FLASH的工程进修改,经测试SPI3正常了。 修改1、SPI初始化代码中添加反初始化代码,然后再重新初始【这个操作像极了低功耗设计里面的操作,记得stm32L里头就是这样搞的】 ``` //spi_flash.h中初始化代码中添,注意这里是从他们的代码中提取出来的关键部分,测试过,后面的注掉没有问题,所以只保留精华部分,减少代码 SPI_Enable(sFLASH_SPI, DISABLE); SPI_I2S_DeInit(sFLASH_SPI); RCC_EnableAPB1PeriphClk(sFLASH_SPI_CLK, DISABLE); ``` 修改2、SPI3的初始化代码中加入 GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_SW_ENABLE, ENABLE); 搞在这里可能也是有道理的吧,真正的占用者,占用去吧。 ``` //spi_flash.c void sFLASH_LowLevel_Init(void) { GPIO_InitType GPIO_InitStructure; /*!< sFLASH_SPI_CS_GPIO, sFLASH_SPI_MOSI_GPIO, sFLASH_SPI_MISO_GPIO and sFLASH_SPI_SCK_GPIO Periph clock enable */ RCC_EnableAPB2PeriphClk( sFLASH_CS_GPIO_CLK | sFLASH_SPI_MOSI_GPIO_CLK | sFLASH_SPI_MISO_GPIO_CLK | sFLASH_SPI_SCK_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE); /*!< sFLASH_SPI Periph clock enable */ RCC_EnableAPB1PeriphClk(sFLASH_SPI_CLK, ENABLE); GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_SW_ENABLE, ENABLE);//这里是后加进来的 /*!< Configure sFLASH_SPI pins: SCK */ GPIO_InitStructure.Pin = sFLASH_SPI_SCK_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitPeripheral(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); /*!< Configure sFLASH_SPI pins: MOSI */ GPIO_InitStructure.Pin = sFLASH_SPI_MOSI_PIN; GPIO_InitPeripheral(sFLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); /*!< Configure sFLASH_SPI pins: MISO */ GPIO_InitStructure.Pin = sFLASH_SPI_MISO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitPeripheral(sFLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); /*!< Configure sFLASH_CS_PIN pin: sFLASH Card CS pin */ GPIO_InitStructure.Pin = sFLASH_CS_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitPeripheral(sFLASH_CS_GPIO_PORT, &GPIO_InitStructure); } ``` 修改3、SPI1的各接口宏改成SPI3的 ``` //spi_flash.h #define sFLASH_SPI SPI3 #define sFLASH_SPI_CLK RCC_APB1_PERIPH_SPI3 #define sFLASH_SPI_SCK_PIN GPIO_PIN_3 /* PB.03 */ #define sFLASH_SPI_SCK_GPIO_PORT GPIOB /* GPIOB */ #define sFLASH_SPI_SCK_GPIO_CLK RCC_APB2_PERIPH_GPIOB #define sFLASH_SPI_MISO_PIN GPIO_PIN_4 /* PB.04 */ #define sFLASH_SPI_MISO_GPIO_PORT GPIOB /* GPIOB */ #define sFLASH_SPI_MISO_GPIO_CLK RCC_APB2_PERIPH_GPIOB #define sFLASH_SPI_MOSI_PIN GPIO_PIN_5 /* PB.05 */ #define sFLASH_SPI_MOSI_GPIO_PORT GPIOB /* GPIOB */ #define sFLASH_SPI_MOSI_GPIO_CLK RCC_APB2_PERIPH_GPIOB #define sFLASH_CS_PIN GPIO_PIN_2 /* PA.15 */ #define sFLASH_CS_GPIO_PORT GPIOD /* GPIOA */ #define sFLASH_CS_GPIO_CLK RCC_APB2_PERIPH_GPIOD ``` 如是修改,SPI3在N32G455REL7上可以正常读写数据。 【不要过于相信网上的东西,要自己动手去试,也不用怀疑自己得到的结论,可能你得到的结论就是对的,可能是板子有关。】 这是国民技术提供的SPI3真实可用的代码,可以参考一下 [N32G455_SPI3_FLASH.rar](https://oss-club.rt-thread.org/uploads/20220328/74a0771d0bca636144b2bcb8540651ed.rar) RTT下可用的drv_spi.c主要修改xfer函数,先看结果 ![image.png](https://oss-club.rt-thread.org/uploads/20220328/b23eb231e140089589001047e5d83c10.png) 直接参考了国民技术提供的文件进行修改 ![image.png](https://oss-club.rt-thread.org/uploads/20220328/820b3b38b442a7634076ff0dedea1a15.png) 好了,收发都正常了。 [drv_spi.c](https://oss-club.rt-thread.org/uploads/20220328/35881dad4ae0ee107475910e34e8b64e.c) 注意,这里上传的驱动,只是能用而已,真正用到项目上,不要这样搞,会卡死,至少加个超时退出。 今天先写到这里。 **添加个超时判断V1.0** ``` //硬加一个超时判断,验证方式,将读取那块直接注掉前半部分,会发现没有卡死,说明超时起作用了 static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) { rt_size_t send_length; rt_uint8_t *recv_buf; const rt_uint8_t *send_buf; /* Init tickstart for timeout management*/ rt_uint32_t tickstart = rt_tick_get(); /* Check Direction parameter */ RT_ASSERT(device != RT_NULL); RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus->parent.user_data != RT_NULL); RT_ASSERT(message != RT_NULL); struct n32_spi *spi_drv = rt_container_of(device->bus, struct n32_spi, spi_bus); struct n32_hw_spi_cs *cs = device->parent.user_data; SPI_Module *spi_handle = spi_drv->config->module; if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS)) { if (device->config.mode & RT_SPI_CS_HIGH) GPIO_SetBits(cs->module, cs->pin); else GPIO_ResetBits(cs->module, cs->pin); } send_length= message->length; recv_buf = message->recv_buf; send_buf = message->send_buf; /* start once data exchange in DMA mode */ if (message->send_buf && message->recv_buf) { LOG_D("%s:%d", __FUNCTION__, __LINE__); } else if (message->send_buf) { while (send_length--) { while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_TE_FLAG) == RESET) { if ((rt_tick_get() - tickstart) > SPI_TIME_OUT) { goto __exit; } } SPI_I2S_TransmitData(spi_handle, *send_buf++); while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_RNE_FLAG) == RESET) { if ((rt_tick_get() - tickstart) > SPI_TIME_OUT) { goto __exit; } } SPI_I2S_ReceiveData(spi_handle); } } else { while (send_length--) { while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_TE_FLAG) == RESET) { if ((rt_tick_get() - tickstart) > SPI_TIME_OUT) { goto __exit; } } SPI_I2S_TransmitData(spi_handle, 0xff); while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_RNE_FLAG) == RESET) { if ((rt_tick_get() - tickstart) > SPI_TIME_OUT) { goto __exit; } } *recv_buf++ = (rt_uint8_t)SPI_I2S_ReceiveData(spi_handle); } } __exit: if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS)) { if (device->config.mode & RT_SPI_CS_HIGH) GPIO_ResetBits(cs->module, cs->pin); else GPIO_SetBits(cs->module, cs->pin); } return message->length; } ``` **提取公共函数V1.1** ``` static inline int HAL_SPI_TransmitReceive(SPI_Module *hspi, uint8_t *tx_buff, uint8_t *rx_buff, uint32_t length, uint32_t timeout) { /* Init tickstart for timeout management*/ uint32_t tickstart = rt_tick_get(); uint8_t dat = 0; if ((tx_buff == RT_NULL) && (rx_buff == RT_NULL) || (length == 0)) { return RT_EIO; } while (length--) { while (SPI_I2S_GetStatus(hspi, SPI_I2S_TE_FLAG) == RESET) { if ((rt_tick_get() - tickstart) > timeout) { return RT_ETIMEOUT; } } SPI_I2S_TransmitData(hspi, *tx_buff++); while (SPI_I2S_GetStatus(hspi, SPI_I2S_RNE_FLAG) == RESET) { if ((rt_tick_get() - tickstart) > timeout) { return RT_ETIMEOUT; } } dat = SPI_I2S_ReceiveData(hspi); if (rx_buff) { *rx_buff++ = dat; } } return RT_EOK; } static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) { rt_size_t send_length; rt_uint8_t *recv_buf; const rt_uint8_t *send_buf; rt_err_t stat = RT_EOK; /* Check Direction parameter */ RT_ASSERT(device != RT_NULL); RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus->parent.user_data != RT_NULL); RT_ASSERT(message != RT_NULL); struct n32_spi *spi_drv = rt_container_of(device->bus, struct n32_spi, spi_bus); struct n32_hw_spi_cs *cs = device->parent.user_data; SPI_Module *spi_handle = spi_drv->config->module; if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS)) { if (device->config.mode & RT_SPI_CS_HIGH) { GPIO_SetBits(cs->module, cs->pin); } else { GPIO_ResetBits(cs->module, cs->pin); } } send_length = message->length; recv_buf = message->recv_buf; send_buf = message->send_buf; /* start once data exchange in DMA mode */ if (message->send_buf && message->recv_buf) { LOG_D("%s:%d", __FUNCTION__, __LINE__); stat = RT_EIO; } else if (message->send_buf) { stat = HAL_SPI_TransmitReceive(spi_handle, (uint8_t *)send_buf, RT_NULL, send_length, SPI_TIME_OUT); } else { rt_memset(recv_buf, 0xff, send_length); stat = HAL_SPI_TransmitReceive(spi_handle, (uint8_t *)recv_buf, (uint8_t *)recv_buf, send_length, SPI_TIME_OUT); } if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS)) { if (device->config.mode & RT_SPI_CS_HIGH) { GPIO_ResetBits(cs->module, cs->pin); } else { GPIO_SetBits(cs->module, cs->pin); } } return send_length; } ```
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
wlof
这个家伙不懒,什么也没写
文章
16
回答
64
被采纳
0
关注TA
发私信
相关文章
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
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
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
xiaorui
1
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部