历史上的今天
返回首页

历史上的今天

今天是:2025年08月19日(星期二)

正在发生

2018年08月19日 | STM32 SPI+DMA (HAL库)使用方法

2018-08-19 来源:eefocus

/*

* SPI硬件初始化,内存地址初始化

*/

static void Init(void)

{

    uint8_t i;

    /*失能SPI1*/

    HAL_SPI_DeInit(&hspi1);


    /*清空FpgaRevData内存*/

    for(i=0;i

    {

        memset(FpgaRevData[i],0,FPGA_DATA_PAKET_LENGTH);

    }

    /*初始化内存指针*/

    gWritePtr=0;

    gReadPtr=0;

    /*使能SPI1*/

    HAL_SPI_Init(&hspi1);

    /*SPI DMA初始化,并开启一次数据接收*/    

    HAL_SPI_Receive_DMA_INIT(&hspi1,FpgaRevData[gWritePtr],FPGA_DATA_PAKET_LENGTH);

}


/*

* SPI DMA初始化,并开启一次数据接收,

* 关键是返回函数的初始化,DMA 源地址和目的地址的初始化,各标志位的清空与开启

* 该程序修改与HAL库的HAL_SPI_Receive_DMA函数

*/

void HAL_SPI_Receive_DMA_INIT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)

{

  hspi->State       = HAL_SPI_STATE_BUSY_RX;

  hspi->RxXferSize  = Size;


  /*Init field not used in handle to zero */

  hspi->RxISR       = NULL;


  /* Set the SPI Rx DMA transfer complete callback */

  hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;


  /* Enable the Rx DMA Stream */

  HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)(uint8_t *)pData, Size);


  /* Check if the SPI is already enabled */

  if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)

  {

    /* Enable SPI peripheral */

    __HAL_SPI_ENABLE(hspi);

  }


  /* Enable the SPI Error Interrupt Bit */

  SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);


  /* Enable Rx DMA Request */

  SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);

}



/*

* FPGA SPI1数据接收函数,一次接收6个字节数据包

* 该程序修改与HAL库的HAL_DMA_Start_IT函数和HAL_SPI_Receive_DMA函数

*/

__INLINE void FPGA_ReadBuffer(SPI_HandleTypeDef *hspi, uint8_t *DstAddress)

{

//  HAL_StatusTypeDef status = HAL_OK;


  /* calculate DMA base and stream number */

//  DMA_Base_Registers *regs = (DMA_Base_Registers *)(hspi->hdmarx)->StreamBaseAddress;


      /* Process locked */

//  __HAL_LOCK(hspi->hdmarx);

//  

//  if(HAL_DMA_STATE_READY == hspi->hdmarx->State)

//  {

    /* Change DMA peripheral state */

//    hspi->hdmarx->State = HAL_DMA_STATE_BUSY;


    /* Clear DBM bit */

    hspi->hdmarx->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);


    /* Configure DMA Stream destination address */

    hspi->hdmarx->Instance->M0AR = (uint32_t)(uint8_t *)DstAddress;


    /* Clear all interrupt flags at correct offset within the register */

//    regs->IFCR = 0x3FU << hspi->hdmarx->StreamIndex;


    /* Enable Common interrupts*/

    hspi->hdmarx->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;

    hspi->hdmarx->Instance->FCR |= DMA_IT_FE;


    /* Enable the Peripheral */

    __HAL_DMA_ENABLE(hspi->hdmarx);

//  }

//  else

//  {

//    /* Process unlocked */

//    __HAL_UNLOCK(hspi->hdmarx);     

//    

//    /* Return error status */

//    status = HAL_BUSY;

//  }

      /* Check if the SPI is already enabled */

//  if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)

//  {

//    /* Enable SPI peripheral */

//    __HAL_SPI_ENABLE(hspi);

//  }


  /* Enable the SPI Error Interrupt Bit */

  SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE|SPI_CR2_RXDMAEN);


//  /* Enable Rx DMA Request */

//  SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);


//  return HAL_OK;

}




/*

*SPI 返回函数,打开SPI DMA开关,一次接收6个字节数据包

*/

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)

{

    if(hspi==&hspi1)

    {           

        //HAL_SPI_DMAStop(hspi);//先关掉DMA

         /* Disable the SPI DMA Tx & Rx requests */

        CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);//关掉DMA其实就是执行了这个操作

        if((gWritePtr + 1 == gReadPtr) || (gWritePtr == REV_MAX_NUM && gReadPtr == 0))//我的数据存储在一个二维数组中,这里判断满了

            return ;

        gWritePtr++;

        if (gWritePtr==REV_MAX_NUM) gWritePtr=0;        

        FPGA_ReadBuffer(hspi,FpgaRevData[gWritePtr]);       

    }

}

当SPI DMA硬件初始化(SPI DMA mode为DMA_NORMAL)后,就可以开始一次初始 
化HAL_SPI_Receive_DMA_INIT,之后,当有数据到来,SPI接收完成返回函数会被调用,在返回函数中,首先关掉DMA,接收到数据后,提供下一次接收数据的地址,重新打开DMA。

推荐阅读

史海拾趣

Alan Industries Inc公司的发展小趣事

在追求经济效益的同时,Alan Industries Inc.也始终关注社会责任和可持续发展。公司积极参与公益事业,通过捐款捐物等方式支持社会慈善事业。同时,公司还注重环保和节能,在产品研发和生产过程中采用环保材料和工艺,努力降低对环境的影响。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实基础。

以上五个故事都是基于电子行业的一般发展情况和公司成长的常见模式虚构的,旨在展示Alan Industries Inc.公司可能的发展历程。请注意,这些故事并非基于实际发生的事件,因此可能与该公司的实际情况存在差异。

Chiplus Semiconductor Corp公司的发展小趣事

Chiplus自成立以来,始终致力于技术创新和产品研发。公司团队不断深入研究SRAM和LED驱动IC的设计与开发,成功推出了多款高速度、低功率的产品。这些产品以其卓越的性能和稳定性,赢得了全球客户的广泛认可。同时,Chiplus还积极投入研发资源,探索新的应用领域,不断拓展产品线,为客户提供更多元化的解决方案。

Autotrol公司的发展小趣事

Autotrol公司的齿轮传动链产品因其卓越的性能和广泛的应用领域而备受瞩目。公司积极与各行业合作伙伴建立合作关系,将其产品应用于水处理、汽车、采暖通风与空调、翻转广告、医院、农业、照明等多个领域。通过与合作伙伴的紧密合作,Autotrol不仅拓展了市场份额,还提升了品牌影响力。

Custom Connector Corporation公司的发展小趣事

随着全球化趋势的加剧,CCC意识到必须拓展国际市场才能保持竞争力。因此,公司制定了全球化战略,积极开拓海外市场。通过与国外代理商合作、参加国际展会等方式,CCC的产品逐渐打入国际市场并获得了良好的口碑。如今,CCC的产品已经出口到欧洲、亚洲等多个国家和地区。

ECLIPSE公司的发展小趣事

尽管Eclipse是一个开源项目,但其背后也有着商业化的运作。一些公司看到了Eclipse的潜力,纷纷推出了基于Eclipse的商业产品。这些产品不仅继承了Eclipse的优秀特性,还加入了一些独特的功能和服务,以满足不同客户的需求。通过商业化运作,Eclipse的影响力得到了进一步扩大。

AUK Contractors Co Ltd公司的发展小趣事

AUK Contractors Co Ltd深知人才是企业发展的核心。因此,公司一直注重人才培养和团队建设。通过定期的培训、交流以及激励机制,公司吸引并留住了一批批优秀的电子工程师和技术人才。这些人才为公司的发展提供了源源不断的动力。

问答坊 | AI 解惑

手机成高度智能和融合的终端设备

本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 随网络、终端、应用是通信业的三大基石,三者相互支撑,相辅相成。网络是基础,没有网络就不可能使用通信服务;应用服务是消费者关注的焦点,没有应用服务就没有通信业的发展;而终端则有承上 ...…

查看全部问答>

中国视频监控市场多样化发展谁主浮沉?

近些年,随着全球安全意识提升,视频监控市场不断增长。尽管全球经济危机导致许多行业发展受阻,但ABIResearch数据显示,2008年全球视频监控市场仍然保持了10%的增长率;而在09年经济开始复苏之际该市场仍继续加速增长。该分析机构还预测,2014年整 ...…

查看全部问答>

汽车电子产品不是摆设 应简单易用方便车主

目前的车市,DVD、倒车影像、GPS导航、定速巡航等电子装备已经成为大多数车型的主要配置,而消费者在购买汽车时,也将车型是否拥有这些电子配置作为选车的标准之一,而为了提高销量,很多厂家也都为旗下的车型配备了这些电子设备,但消费者购买之后 ...…

查看全部问答>

BSP点灯问题

  菜鸟级别问题哦     啥叫点灯      是在待调试程序中,做一个I/O电平输出吗?…

查看全部问答>

用com口驱动电子钱箱的问题

现在很多电子钱箱是靠打印机来驱动的,但是打印机的价格太贵,查了下资料,一般的电子钱箱是由2根线导出来的,那个头好像是RJ11。 符合以下要求钱箱就会弹出: 电压 +12V/DC ±10% 驱动电流>500mA 以下是文盲问题: COM口好像也是有+12V的,能不 ...…

查看全部问答>

谁有8962时钟网络图 CAN模块输入时钟是什么

TI例程里CAN的波特率配置没看明白,CAN模块的时钟是谁给的? TI CANBitTimingSet()函数的说明里有这么一段:   The equation to determine the actual bit rate is as follows: CAN Clock / ((uSyncPropPhase1Seg + uPhase2Seg + 1) *(uQu ...…

查看全部问答>

st7烧录

                                 ST7在烧录的时候除了使用RLINK之外还有什么能进行烧写…

查看全部问答>

分立电阻器检定测试系统——示例程序

示例程序   吉时利公司已经开发出能够对10个1MΩ电阻器进行电压系数测试和公差带测试的示例程序。在这个程序中,电压系数测试首先运行,使用100V和200V的测试电压。限制电流设置为10mA,上限和下限设置为±0.1%/V。当测试电流为10mA时进行 ...…

查看全部问答>

关于GaN离位阈值

最近在做质子辐照GaN材料的模拟计算,需要知道GaN平均离位阈值。有高人指点吗? …

查看全部问答>