研究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进行比较,如果成功就亮起灯或者熄灭灯。注意:接收到的第一个字节是命令。从第二个字节后开始比较。
整个流程就是这样。谢谢您的注意。