历史上的今天
今天是: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。
史海拾趣
|
本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 随网络、终端、应用是通信业的三大基石,三者相互支撑,相辅相成。网络是基础,没有网络就不可能使用通信服务;应用服务是消费者关注的焦点,没有应用服务就没有通信业的发展;而终端则有承上 ...… 查看全部问答> |
|
近些年,随着全球安全意识提升,视频监控市场不断增长。尽管全球经济危机导致许多行业发展受阻,但ABIResearch数据显示,2008年全球视频监控市场仍然保持了10%的增长率;而在09年经济开始复苏之际该市场仍继续加速增长。该分析机构还预测,2014年整 ...… 查看全部问答> |
|
目前的车市,DVD、倒车影像、GPS导航、定速巡航等电子装备已经成为大多数车型的主要配置,而消费者在购买汽车时,也将车型是否拥有这些电子配置作为选车的标准之一,而为了提高销量,很多厂家也都为旗下的车型配备了这些电子设备,但消费者购买之后 ...… 查看全部问答> |
|
现在很多电子钱箱是靠打印机来驱动的,但是打印机的价格太贵,查了下资料,一般的电子钱箱是由2根线导出来的,那个头好像是RJ11。 符合以下要求钱箱就会弹出: 电压 +12V/DC ±10% 驱动电流>500mA 以下是文盲问题: COM口好像也是有+12V的,能不 ...… 查看全部问答> |
|
TI例程里CAN的波特率配置没看明白,CAN模块的时钟是谁给的? TI CANBitTimingSet()函数的说明里有这么一段: The equation to determine the actual bit rate is as follows: CAN Clock / ((uSyncPropPhase1Seg + uPhase2Seg + 1) *(uQu ...… 查看全部问答> |
|
示例程序 吉时利公司已经开发出能够对10个1MΩ电阻器进行电压系数测试和公差带测试的示例程序。在这个程序中,电压系数测试首先运行,使用100V和200V的测试电压。限制电流设置为10mA,上限和下限设置为±0.1%/V。当测试电流为10mA时进行 ...… 查看全部问答> |




