STM32双机SPI中断通信机制

研究STM32F4的SPI有一阵子了,进步很缓慢,前几天终于鼓起勇气,用手抄了一遍官方的代码,然后自己一个字字的敲进去,然后再调试。历时大约一个星期,终于把SPI的中断发送和中断接收给整清楚了。在没有正确运行出结果之前,一切都是辣么痛苦。此文鼓励我继续往前进步。

先说主机端,首先当然是写SPI驱动文件,也就是SPI的配置,具体文件如下:

SPI.c

#include <stm32f4xx.h>
#include "usart.h"
#include "spi.h"
 

  u8 Master_Temp =0;
  extern SPI_InitTypeDef  SPI_InitStructure;

 u8 Slave_Temp=0;
 static __IO uint32_t TimingDelay;

 void SPI_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
	
  /* Peripheral Clock Enable -------------------------------------------------*/
  /* Enable the SPI clock */
  SPIx_CLK_INIT(SPIx_CLK, ENABLE);
  
  /* Enable GPIO clocks */
  RCC_AHB1PeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK, ENABLE);

  /* SPI GPIO Configuration --------------------------------------------------*/
  /* Connect SPI pins to AF5 */  
  GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);
  GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);
  GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

  /* SPI SCK pin configuration */
  GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN;
  GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure);

  /* SPI  MOSI pin configuration */
  GPIO_InitStructure.GPIO_Pin =  SPIx_MOSI_PIN;
  GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);
	
  /* SPI  MISO pin configuration  */
  GPIO_InitStructure.GPIO_Pin =  SPIx_MISO_PIN;
  GPIO_Init(SPIx_MISO_GPIO_PORT,&GPIO_InitStructure);
 
  /* SPI configuration -------------------------------------------------------*/
  SPI_I2S_DeInit(SPIx);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS  = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  
 /* Configure the Priority Group to 1 bit */                
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* Configure the SPI interrupt priority */
  NVIC_InitStructure.NVIC_IRQChannel = SPIx_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

}

	SPI.H
/**
  ******************************************************************************
  * @file    SPI/SPI_TwoBoards/DataExchangeInterrupt/main.h
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    30-September-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************  
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_H_
#define __SPI_H_

#ifdef __cplusplus
 extern "C" {
#endif 

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm324xg_eval.h"
#include "stm324xg_eval_ioe.h"


/* Exported typedef -----------------------------------------------------------*/
#define countof(a)   (sizeof(a) / sizeof(*(a)))
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

/* Exported define ------------------------------------------------------------*/
/* Uncomment the line below if you will use the SPI peripheral as a Master */
 #define SPI_MASTER
/* Uncomment the line below if you will use the SPI peripheral as a Slave */
//#define SPI_SLAVE  

/* USER_TIMEOUT value for waiting loops. This timeout is just guarantee that the
   application will not remain stuck if the USART communication is corrupted. 
   You may modify this timeout value depending on CPU frequency and application
   conditions (interrupts routines, number of data to transfer, baudrate, CPU
   frequency...). */ 
#define USER_TIMEOUT                    ((uint32_t)0x64) /* Waiting 1s */

/* SPIx Communication boards Interface */
#define SPIx                           SPI2
#define SPIx_CLK                       RCC_APB1Periph_SPI2
#define SPIx_CLK_INIT                  RCC_APB1PeriphClockCmd
#define SPIx_IRQn                      SPI2_IRQn
#define SPIx_IRQHANDLER                SPI2_IRQHandler

#define SPIx_SCK_PIN                   GPIO_Pin_1
#define SPIx_SCK_GPIO_PORT             GPIOI
#define SPIx_SCK_GPIO_CLK              RCC_AHB1Periph_GPIOI
#define SPIx_SCK_SOURCE                GPIO_PinSource1
#define SPIx_SCK_AF                    GPIO_AF_SPI2

#define SPIx_MISO_PIN                  GPIO_Pin_2
#define SPIx_MISO_GPIO_PORT            GPIOI
#define SPIx_MISO_GPIO_CLK             RCC_AHB1Periph_GPIOI
#define SPIx_MISO_SOURCE               GPIO_PinSource2
#define SPIx_MISO_AF                   GPIO_AF_SPI2

#define SPIx_MOSI_PIN                  GPIO_Pin_3
#define SPIx_MOSI_GPIO_PORT            GPIOI
#define SPIx_MOSI_GPIO_CLK             RCC_AHB1Periph_GPIOI
#define SPIx_MOSI_SOURCE               GPIO_PinSource3
#define SPIx_MOSI_AF                   GPIO_AF_SPI2

#define TXBUFFERSIZE   (countof(TxBuffer) - 1)
#define RXBUFFERSIZE   TXBUFFERSIZE


/* Define numbers of bytes to transmit from TxBuffer */
#define CMD_RIGHT_SIZE                   0x01
#define CMD_LEFT_SIZE                    0x05
#define CMD_UP_SIZE                      0x14
#define CMD_DOWN_SIZE                    0x1E
#define CMD_SEL_SIZE                     TXBUFFERSIZE



/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#ifdef SPI_MASTER
 uint8_t GetVar_NbrOfData(void);
#endif

#ifdef __cplusplus
}
#endif

void SPI_Config( void);
void SysTickConfig(void);
void Fill_Buffer(__IO uint8_t *pBuffer, uint16_t BufferLength);

#endif /* __MAIN_H */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

  stm32f4xx_it.c

/**
  ******************************************************************************
  * @file    stm32fxxx_it.c
  * @author  MCD Application Team
  * @version V2.1.0
  * @date    19-March-2012
  * @brief   This file includes the interrupt handlers for the application
  ******************************************************************************

/* Includes ------------------------------------------------------------------*/
#include "usb_bsp.h"
#include "usb_hcd_int.h"
#include "usbh_core.h"
#include <stdio.h>
#include "stm32fxxx_it.h"
#include "spi.h"
#include "main.h"
extern __IO uint8_t CmdTransmitted;
extern __IO uint8_t Tx_Idx;
extern __IO uint8_t CmdStatus;
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

extern USB_OTG_CORE_HANDLE          USB_OTG_Core;
extern USBH_HOST                    USB_Host;

extern uint8_t TxBuffer[];
extern __IO uint32_t TimeOut;
extern __IO uint8_t Counter;

/* Private function prototypes -----------------------------------------------*/
extern void USB_OTG_BSP_TimerIRQ (void);



void SysTick_Handler(void)
{
  /* Decrement the timeout value */
  if (TimeOut != 0x0)
  {
    TimeOut--;
  }
    
  if (Counter < 10)
  {
    Counter++;
  }
  else
  {
    Counter = 0x00;
    STM_EVAL_LEDToggle(LED1);
  }
}

void SPIx_IRQHANDLER(void)
{
	#ifdef SPI_MASTER
	if(SPI_I2S_GetITStatus(SPIx,SPI_I2S_IT_TXE) == SET)
	{
		if(CmdStatus == 0x00)
		{
			SPI_I2S_SendData(SPIx,CmdTransmitted);
			CmdStatus = 0x01;
		}
		else
		{
			if(Tx_Idx < GetVar_NbrOfData())
			{	
//				printf("send data%c\n",TxBuffer[Tx_Idx]);
				SPI_I2S_SendData(SPIx,TxBuffer[Tx_Idx++]);
//				printf("%d\n",Tx_Idx);
//				Tx_Idx++;
			}
			else
			{	printf(" DISABLE IR\n"); SPI_I2S_ITConfig(SPIx,SPI_I2S_IT_TXE,DISABLE);	}
		}
	}
	#endif
}
/**
  * @brief  DebugMon_Handler
  *         This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}


/**
  * @brief  PendSV_Handler
  *         This function handles PendSVC exception.
  * @param  None
  * @retval None
  */
void PendSV_Handler(void)
{
}

/**
  * @brief  EXTI1_IRQHandler
  *         This function handles External line 1 interrupt request.
  * @param  None
  * @retval None
  */
void EXTI1_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line1) != RESET)
  {
      USB_Host.usr_cb->OverCurrentDetected();
      EXTI_ClearITPendingBit(EXTI_Line1);
  }
}
/**
  * @brief  TIM2_IRQHandler
  *         This function handles Timer2 Handler.
  * @param  None
  * @retval None
  */
void TIM2_IRQHandler(void)
{
  USB_OTG_BSP_TimerIRQ();
}


/**
  * @brief  OTG_FS_IRQHandler
  *          This function handles USB-On-The-Go FS global interrupt request.
  *          requests.
  * @param  None
  * @retval None
  */
#ifdef USE_USB_OTG_FS  
void OTG_FS_IRQHandler(void)
#else
void OTG_HS_IRQHandler(void)
#endif
{
  USBH_OTG_ISR_Handler(&USB_OTG_Core);
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


  stm32f4xx_it.h

/**
  ******************************************************************************
  * @file    stm32fxxx_it.h 
  * @author  MCD Application Team
  * @version V2.1.0
  * @date    19-March-2012
  * @brief   This file contains the headers of the interrupt handlers.
  ******************************************************************************
  * @attention
  *
  * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */ 

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32Fxxx_IT_H
#define __STM32Fxxx_IT_H

#ifdef __cplusplus
 extern "C" {
#endif 

/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */

void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void SPIx_IRQHANDLER(void);

#ifdef __cplusplus
}
#endif

#endif /* __STM32Fxxx_IT_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

   main.c

/**
  ******************************************************************************
  * @file    main.c
  * @author  MCD Application Team
  * @version V2.1.0
  * @date    19-March-2012
  * @brief   USB host MSC class demo main file
  ******************************************************************************
  * @attention
  *
  * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */ 
#include <stdlib.h>
#include <string.h>
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usbh_core.h"
#include "usbh_usr.h"
#include "usbh_msc_core.h"
#include "nvic.h"
#include "usart.h"
#include "spi.h"
#include "dma.h"
#include "KBD.h"
#include "terminal.h"

//DMA_InitTypeDef DMA_InitStructure;
SPI_InitTypeDef  SPI_InitStructure; 

uint8_t TxBuffer[] ="SPI Interrupt Example: Communication between two SPI using Interrupts";

//__IO uint32_t TimeOut = 0x0;  
//#ifdef SPI_SLAVE 
// __IO uint8_t uint8_t RxBuffer[RXBUFFERSIZE];
// __IO uint8_t Rx_Idx = 0; 
//#endif

#ifdef SPI_MASTER
	
	__IO uint8_t Tx_Idx =0;
	__IO uint8_t CmdTransmitted = CMD_NONE;
	__IO uint8_t CmdStatus = 0x00;
	__IO uint8_t NumberOfByte = 0;

  __IO uint32_t TimeOut;
  __IO uint8_t Counter;
#endif

//static void SPI_Config(void);
void SysTickConfig(void);

#ifdef SPI_MASTER
static void  TimeOut_UserCallback(void);
#endif
//#ifdef SPI_SLAVE
//	static TestStatus Buffercmp(uint8_t *pBuffer1,__IO uint8_t *pBuffer2,uint16_t BufferLength);
//	static void Fill_Buffer(__IO uint8_t *pBuffe,uint16_t BufferLength);
//#endif
#define Buff_SIZE 32
const uint8_t Buff[Buff_SIZE]= {
																		0xA0,0x00,0x00,0xAA,
                                    0x55,0x55,0x55,0x55,
                                    0x55,0x00,0x00,0x00,
                                    0x00,0x00,0x00,0x00,
                                    0xAA,0xAA,0xAA,0xAA,
                                    0xAA,0xAA,0xAA,0xAA,
                                    0xAA,0xAA,0xAA,0xAA,
                                    0x00,0x00,0xA0,0xAA };	
uint32_t DST_Buffer[BUFFER_SIZE];

/** @addtogroup USBH_USER
* @{
*/

/** @defgroup USBH_USR_MAIN
* @brief This file is the MSC demo main file
* @{
*/ 

/** @defgroup USBH_USR_MAIN_Private_TypesDefinitions
* @{
*/ 
/**
* @}
*/ 

/** @defgroup USBH_USR_MAIN_Private_Defines
* @{
*/ 
/**
* @}
*/ 


/** @defgroup USBH_USR_MAIN_Private_Macros
* @{
*/ 
/**
* @}
*/ 

/** @defgroup USBH_USR_MAIN_Private_Variables
* @{
*/


/* Private function prototypes -----------------------------------------------*/

//#ifdef SPI_MASTER
// static void TimeOut_UserCallback(void);
//#endif

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN USB_OTG_CORE_HANDLE      USB_OTG_Core __ALIGN_END;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN USBH_HOST                USB_Host __ALIGN_END;
/**
* @}
*/ 


/** @defgroup USBH_USR_MAIN_Private_FunctionPrototypes
* @{
*/ 
/**
* @}
*/ 


/** @defgroup USBH_USR_MAIN_Private_Functions
* @{
*/ 

/**
* @brief  Main routine for MSC class application
* @param  None
* @retval int
*/
int main(void)
{
  uint32_t KEY;
	/* SPI configuration -------------------------------------------------------*/
	KBD_Init();
  SPI_Config();
	SysTickConfig();
//	STM_EVAL_LEDInit(LED1);
//	SPI1_DMA_Configuration();
	usart3.initialize(9600);
	terminal.initialize();
	  /* Init Host Library */
	USBH_Init(&USB_OTG_Core, 
#ifdef USE_USB_OTG_FS  
            USB_OTG_FS_CORE_ID,
#else 
            USB_OTG_HS_CORE_ID,
#endif 
            &USB_Host,
            &USBH_MSC_cb, 
            &USR_cb);
	#ifdef SPI_MASTER
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_Init(SPIx,&SPI_InitStructure);
	SPI_Cmd(SPIx,ENABLE);
	while(1)
	{
	/* Host Task handler */
  USBH_Process(&USB_OTG_Core, &USB_Host);  
	//  SPI2_ReadWriteByte(0xAA);
	CmdTransmitted = CMD_NONE;
	KEY = KBD_GetKeys();
	switch(KEY)
		{
			case WAKEUP:
				CmdTransmitted = CMD_UP;
				NumberOfByte = CMD_UP_SIZE;
				printf("\r\n WAKEUP");
			break;
			case TAMPER:
				CmdTransmitted = CMD_SEL;
				NumberOfByte = CMD_SEL_SIZE;
				printf("\r\n TAMPER");
			break;
			default:
//				CmdTransmitted = CMD_LEFT;
//				NumberofByte = CMD_LEFT_SIZE;
			break;
		}	
	
	CmdStatus = 0x00;
	Tx_Idx = 0;
	if(CmdTransmitted != CMD_NONE)
		{
			SPI_I2S_ITConfig(SPIx,SPI_I2S_IT_TXE,ENABLE);
			while(Tx_Idx<GetVar_NbrOfData())
			{}
		}
	}
	#endif
}

 void SysTickConfig(void)
{
  /* Set SysTick Timer for 10ms interrupts  */
  if (SysTick_Config(SystemCoreClock / 100))
  {
    /* Capture error */
    while (1);
  }
  /* Configure the SysTick handler priority */
  NVIC_SetPriority(SysTick_IRQn, 0x0);
}

#ifdef USE_FULL_ASSERT
/**
* @brief  assert_failed
*         Reports the name of the source file and the source line number
*         where the assert_param error has occurred.
* @param  File: pointer to the source file name
* @param  Line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
  ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  
  /* Infinite loop */
  while (1)
  {}
}
#endif

uint8_t GetVar_NbrOfData(void)
{
  return NumberOfByte;
}

 void TimeOut_UserCallback(void)
{
  /* User can add his own implementation to manage TimeOut Communication failure */
  /* Block communication and all processes */
  while (1)
  {   
  }
}
/**
* @}
*/ 

/**
* @}
*/ 

/**
* @}
*/

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
main.h

#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
 extern "C" {
#endif 

#define SPI_MASTER
#define TXBUFFERSIZE   (countof(TxBuffer) - 1)
#define RXBUFFERSIZE   TXBUFFERSIZE
	 
#define USER_TIMEOUT                    ((uint32_t)0x64) /* Waiting 1s */

/* Joystick Commands */
#define CMD_RIGHT                        0x55
#define CMD_LEFT                         0xAA
#define CMD_UP                           0x33
#define CMD_DOWN                         0xCC
#define CMD_SEL                          0xFF 
#define CMD_NONE                         0x00
#define CMD_ACK                          0x66 

/* Define numbers of bytes to transmit from TxBuffer */
#define CMD_RIGHT_SIZE                   0x01
#define CMD_LEFT_SIZE                    0x05
#define CMD_UP_SIZE                      0x14
#define CMD_DOWN_SIZE                    0x1E
#define CMD_SEL_SIZE                     TXBUFFERSIZE

#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */


   从机的SPI的驱动跟主机的是一样的,修改一下主从机就行了。

stm32fxx_it.c的关键代码如下:

void SPI1_IRQHandler(void)
{ 

	#ifdef SPI_SLAVE
	if (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_RXNE) == SET)
  {
		
//		printf("enter RECEIVE IR \r\n");		
		RxBuffer[Rx_Idx++] = SPI_I2S_ReceiveData(SPIx);
//		  printf("%x\r\n",SPI2_ReadWriteByte(0x55));
//			Delay(10);
	}
//	SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_RXNE, DISABLE);
	#endif
}

   main.c的关键代码如下:

/********************************************************************
*¹¤³ÌÃû³Æ£ºARM Cortex-M4 GPIO²âÊÔ
*×÷    ÕߣºÌìϵÄÈË
*ÈÕ    ÆÚ£º2012Äê3ÔÂ23ÈÕ
*********************************************************************/
#include "main.h"
#include "stdio.h"
#include "MagicBlueSTM32BSP.h"
#include "stm32f4_spi.h"
#include "stm32f4x7_eth_bsp.h"
#include "stm32f4x7_eth.h"


/********************************************************************/
SPI_InitTypeDef   SPI_InitStructure;
uint8_t TxBuffer[] = "SPI Interrupt Example: Communication between two SPI using Interrupts";
__IO uint32_t TimeOut = 0;
#ifdef SPI_SLAVE
__IO uint8_t RxBuffer[RXBUFFERSIZE];
__IO uint8_t Rx_Idx = 0 ;
#endif
//DMA_InitTypeDef DMA_InitStructure;
uint8_t Buff[BuffSize] = {  0xAA,0x00,0x00,0xAA,
		            0x55,0x55,0x55,0x55,
	                    0x55,0x00,0x00,0x00,
			    0x00,0x00,0x00,0x00,
			    0xAA,0xAA,0xAA,0xAA,
			    0xAA,0xAA,0xAA,0xAA,
			    0xAA,0xAA,0xAA,0xAA,
			    0x00,0x00,0x00,0xAA};
uint8_t Buffer[64];
uint16_t *Data=0;
/********************************************************************/
void Delay(__IO uint32_t nCount);
void SPI1Init(void);
void SysTickConfig(void);
#ifdef SPI_SLAVE
static TestStatus Buffercmp(uint8_t *pBuffer1,__IO uint8_t *pBuffer2,uint16_t BufferLength);
static void Fill_Buffer(__IO uint8_t *pBuffer,uint16_t BufferLength);
#endif
/********************************************************************/
int main()
  {
//		uint8_t i=0;
		ETH_BSP_Config();
		ETH_WritePHYRegister(0x01,0x00,(0x0001<<11)); 
		SPI1Init();	
		SysTickConfig();
#ifdef SPI_SLAVE
		SPI_I2S_DeInit(SPIx);
		SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
		SPI_Init(SPIx,&SPI_InitStructure);
		SPI_I2S_ITConfig(SPIx,SPI_I2S_IT_RXNE,ENABLE);
		SPI_Cmd(SPIx,ENABLE);
		UART1_Init(115200);
		UART6_Init(115200);
//		SPI1_DMA_Congiguration();
		KeyInit();
		printf("init success!\n");
		LED_Init();
		LED_ON(1);
		LED_OFF(2);
		LED_ON(3);
    Rx_Idx = 0;
		Fill_Buffer(RxBuffer,TXBUFFERSIZE);
	 while(1)
	   {
//			 DMA_DeInit(SPIx_DMA_STREAM);	
//			 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Buff;
//			 DMA_InitStructure.DMA_BufferSize = BuffSize;
//			 DMA_Init(SPIx_DMA_STREAM, &DMA_InitStructure);
//			 SPI_I2S_DMACmd(SPIx,SPI_DMAReq_Rx,ENABLE);
//			 DMA_Cmd(SPIx_DMA_STREAM,ENABLE);
		
		while(RxBuffer[0] == CMD_NONE){}
		TimeOut = 1;
		while (TimeOut != 0x00)
    {
    }
//printf("%d",RxBuffer[0]);
//		printf("%s\r\n",RxBuffer);
//		printf("%d",RxBuffer[1]);
		switch(RxBuffer[0])
		{
				case CMD_UP:
				if(Buffercmp(TxBuffer,&RxBuffer[1],CMD_UP_SIZE) != FAILED)
				{
					
					LED_ON(1);
					LED_ON(2);
					LED_OFF(3);
					printf("CMD_UP recieve!");					
					Rx_Idx = 0;
		      Fill_Buffer(RxBuffer,TXBUFFERSIZE);
				}
				break;
				case CMD_SEL:
				if(Buffercmp(TxBuffer,&RxBuffer[1],CMD_SEL_SIZE)!= FAILED)
				{
					LED_OFF(1);
					LED_OFF(2);
					LED_OFF(3);
					printf("CMD_SEL recieve!");
					Rx_Idx = 0;
		      Fill_Buffer(RxBuffer,TXBUFFERSIZE);
				}
				else
				{
						printf("CMD_SEL_SIZE== FAILED\r\nARxBuffer[1]=%s\r\nRxBuffer[2]=%s\r\n",&RxBuffer[1],TxBuffer);
				}
				break;
				default:
				printf("\r\n enter default");
				Rx_Idx = 0;
		    Fill_Buffer(RxBuffer,TXBUFFERSIZE);
				break;
		}
	
     }
		 #endif
}
  void SysTickConfig(void)
{
  /* Setup SysTick Timer for 10ms interrupts  */
  if (SysTick_Config(SystemCoreClock / 100))
  {
    /* Capture error */
    while (1);
  }

  /* Configure the SysTick handler priority */
  NVIC_SetPriority(SysTick_IRQn, 0x0);
}
/********************************************************************/
/**
  * @brief  Fills buffer.
  * @param  pBuffer: pointer on the Buffer to fill
  * @param  BufferLength: size of the buffer to fill
  * @retval None
  */
static void Fill_Buffer(__IO uint8_t *pBuffer, uint16_t BufferLength)
{
  uint32_t index = 0;

  /* Put in global buffer same values */
  for (index = 0; index < BufferLength; index++ )
  {
    pBuffer[index] = 0x00;
  }
}

static TestStatus Buffercmp(uint8_t* pBuffer1, __IO uint8_t* pBuffer2, uint16_t BufferLength)
{
  while (BufferLength--)
  {
    if (*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }
    pBuffer1++;
    pBuffer2++;
  }
  return PASSED;
}
/********************************************************************/

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* Infinite loop */
  while (1)
  {
  }
}
#endif

//------------------- The end ---------------------------------
    mian.h

///**************************************************************
//*
//*
//*
//***************************************************************/
//#include "stm32f4xx.h"
//#include "stm32f4xx_conf.h"
//#include <stdio.h>
#include"core_cm4.h";
//#include "STM32F4_UART.h"
//#include "SysTick.h"

//#include "MagicBlueSTM32BSP.h"

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
 extern "C" {
#endif 

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4xx_conf.h"
#include <stdio.h>
//#include"core_cm4.h";
#include "STM32F4_UART.h"
#include "SysTick.h"
#include "MagicBlueSTM32BSP.h"
//#include "stm324xg_eval.h"
//#include "stm324xg_eval_ioe.h"

#define SPI_SLAVE
	 
/* Exported typedef -----------------------------------------------------------*/
#define countof(a)   (sizeof(a) / sizeof(*(a)))
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

void SPI1_IRQHandler(void);

#define TXBUFFERSIZE   (countof(TxBuffer) - 1)
#define RXBUFFERSIZE   TXBUFFERSIZE

/* Joystick Commands */
#define CMD_RIGHT                        0x55
#define CMD_LEFT                         0xAA
#define CMD_UP                           0x33
#define CMD_DOWN                         0xCC
#define CMD_SEL                          0xFF 
#define CMD_NONE                         0x00
#define CMD_ACK                          0x66 

/* Define numbers of bytes to transmit from TxBuffer */
#define CMD_RIGHT_SIZE                   0x01
#define CMD_LEFT_SIZE                    0x05
#define CMD_UP_SIZE                      0x14
#define CMD_DOWN_SIZE                    0x1E
#define CMD_SEL_SIZE                     TXBUFFERSIZE
#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

工作的原理大致就是,配置完SPI后就打开SPI中断,首先判断是不是命令,否则判断字节长度是不是小于设定的字节数,然后SPI就发送一个字节,直至达到要发送的字节数,关闭发送中断。接收会触发一个接收中断,然后把接收到数据和TxBuffer进行比较,如果成功就亮起灯或者熄灭灯。注意:接收到的第一个字节是命令。从第二个字节后开始比较。

整个流程就是这样。谢谢您的注意。


  • 12
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
双机SPI通信是指通过SPI总线实现两个STM32微控制器之间的通信。这种通信方式常用于需要高速、可靠传输数据的应用场景,比如传感器节点之间的数据传输、分布式控制系统等。 首先,需要在两个STM32微控制器上分别配置SPI硬件参数。通过设置SPI的时钟极性、时钟相位、数据帧格式等参数,两个微控制器可以在通信时进行匹配。 在发送数据前,发送端的STM32微控制器需要将要发送的数据写入到SPI发送寄存器中,然后启动SPI传输。传输过程中,发送端的STM32会自动将数据发送到SPI总线上,接收端的STM32则会从SPI总线上读取到这些数据。 在接收数据时,接收端的STM32需要不断读取SPI接收寄存器中的数据,直至传输完成。传输完成后,接收端的STM32可以根据接收到的数据进行相应的处理,比如存储到缓冲区、进行运算等操作。 需要注意的是,为了保证数据的准确性和传输的可靠性,双机SPI通信需要在发送端和接收端进行协议设计,比如确认应答机制数据校验等。在传输过程中,发送端和接收端可以通过特定的协议进行数据的确认和校验,以确保传输的准确性。 总之,双机SPI通信是一种高效、可靠的通信方式,可以在两个STM32微控制器之间实现快速的数据传输。通过合理地配置SPI硬件参数和协议设计,可以满足不同应用场景对数据传输的要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值