两个MCU通过spi通信。N32G455VE是主机,MIMXRT1064是从机。业务流程由从机发起,当从机需要发起业务时,通过1个外部中断引脚通知主机,由主机发起spi通信。
N32G455VE使用SPI2,GPIOD2
SPI主机初始化
void Spi_MasterInit(SPI_Module* SPIx)
{
SPI_InitType SPI_InitStructure;
/* Enable SPI2 clock */
RCC_ConfigPclk2(RCC_HCLK_DIV2); /* PCLK2 = HCLK/2 */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_SPI2, ENABLE);
SPI_I2S_DeInit(SPIx);
/* SPI_MASTER configuration */
SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
SPI_InitStructure.SpiMode = SPI_MODE_MASTER;
SPI_InitStructure.DataLen = SPI_DATA_SIZE_8BITS;
SPI_InitStructure.CLKPOL = SPI_CLKPOL_LOW;
SPI_InitStructure.CLKPHA = SPI_CLKPHA_SECOND_EDGE;
SPI_InitStructure.NSS = SPI_NSS_SOFT; // 片选由软件控制
SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_2;
SPI_InitStructure.FirstBit = SPI_FB_MSB;
SPI_InitStructure.CRCPoly = 7;
SPI_Init(SPIx, &SPI_InitStructure);
/* Enable SPI */
SPI_Enable(SPIx, ENABLE);
}
SPI2 DMA发送配置
void spi2_dma_tx_config(uint8_t * u8TxBuff, uint32_t u32TxBuffSize)
{
DMA_InitType DMA_InitStructure;
/* SPI_Tx_DMA_Channel configuration ---------------------------------------------*/
DMA_DeInit(DMA1_CH5);
DMA_InitStructure.PeriphAddr = (uint32_t)(SPI2_BASE + 0x0C);//SPI数据寄存器偏移地址是0x0c
DMA_InitStructure.MemAddr = (uint32_t)u8TxBuff;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;//目的地是外设
DMA_InitStructure.BufSize = u32TxBuffSize;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(DMA1_CH5, &DMA_InitStructure);
/* Enable SPI_Tx Int */
DMA_ConfigInt(DMA1_CH5, DMA_INT_TXC, ENABLE);
/* Enable SPI_Tx request */
SPI_I2S_EnableDma(SPI2, SPI_I2S_DMA_TX, ENABLE);
/* Enable DMA Channel */
DMA_EnableChannel(DMA1_CH5, ENABLE);
}
SPI2 DMA接收配置
void spi2_dma_rx_config(uint8_t * u8RxBuff, uint32_t u32RxBuffSize)
{
DMA_InitType DMA_InitStructure;
/* SPI_Rx_DMA_Channel configuration ---------------------------------------------*/
DMA_DeInit(DMA1_CH4);
DMA_InitStructure.PeriphAddr = (uint32_t)(SPI2_BASE + 0x0C);
DMA_InitStructure.MemAddr = (uint32_t)u8RxBuff;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = u32RxBuffSize;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(DMA1_CH4, &DMA_InitStructure);
/* Enable SPI_Rx Int */
DMA_ConfigInt(DMA1_CH4, DMA_INT_TXC, ENABLE);
/* Enable SPI_Tx request */
SPI_I2S_EnableDma(SPI1_MASTER, SPI_I2S_DMA_RX, ENABLE);
/* Enable DMA Channel */
DMA_EnableChannel(DMA1_CH4, ENABLE);
}
DMA1 channel5中断响应
void DMA1_Channel5_IRQHandler(void)
{
if(DMA_GetIntStatus(DMA1_INT_TXC5, DMA1) == SET)
{
DMA_ClrIntPendingBit(DMA1_INT_TXC5, DMA1);
}
}
DMA1 channel4中断响应
void DMA1_Channel4_IRQHandler(void)
{
if(DMA_GetIntStatus(DMA1_INT_TXC4, DMA1) == SET)
{
DMA_ClrIntPendingBit(DMA1_INT_TXC4, DMA1);
}
}
GPIOD2设置为外部中断输入引脚
void InitConnectAdIo1Interrupt(void)
{
EXTI_InitType EXTI_InitStructure;
NVIC_InitType NVIC_InitStructure;
/*GPIOD2配置为外部中断引脚*/
GPIO_ConfigEXTILine(GPIOD_PORT_SOURCE, GPIO_PIN_SOURCE2);
/*外置中断配置为双沿触发*/
EXTI_InitStructure.EXTI_Line = EXTI_LINE2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitPeripheral(&EXTI_InitStructure);
/* 配置外部中断优先级 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
外部中断2响应函数
void EXTI2_IRQHandler(void)
{
if (RESET != EXTI_GetITStatus(EXTI_LINE2))
{
spi_send_default_msg();//spi通信由主机发起
gSpi.send_receive = 1;
}
EXTI_ClrITPendBit(EXTI_LINE2);
}