STM32 SPI SLAVE

发布者:风清扬yx最新更新时间:2019-01-16 来源: eefocus关键字:STM32  SPI  SLAVE 手机看文章 扫描二维码
随时随地手机看文章

一般使用SPI都用MASTER,但是用SLAVE没有用过.参考了ST的例子,发现不能满足自己的使用.于是,自己修改了一下.


初始化配置SPI


/**

  ******************************************************************************

  * @file    app.c

  * @author  MCD Application Team

  * @version V1.1.0

  * @date    19-March-2012

  * @brief   This file provides all the Application firmware functions.

  ******************************************************************************

  * @attention

  *

  *

© COPYRIGHT 2012 STMicroelectronics

  *

  * 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.

  *

  ******************************************************************************

  */ 

 

/* Includes ------------------------------------------------------------------*/ 

 

#include "usbd_cdc_core.h"

#include "usbd_usr.h"

#include "usb_conf.h"

#include "usbd_desc.h"

#define RECV_SIZE (1024 * 16)

u8 g_cbRecvBuffer[RECV_SIZE] = {0};

 

 SPI_InitTypeDef  SPI_InitStructure;

RECV_STRUCT g_sRecvInfo = {0};

 

 

/**

  * @brief  Configures the SPI Peripheral.

  * @param  None

  * @retval None

  */

static 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 --------------------------------------------------*/

  /* GPIO Deinitialisation */

  GPIO_DeInit(SPIx_SCK_GPIO_PORT);

  GPIO_DeInit(SPIx_MISO_GPIO_PORT);

  GPIO_DeInit(SPIx_MOSI_GPIO_PORT);

  

  /* Connect SPI pins to AF5 */  

  GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);

  GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);    

  GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);

  GPIO_PinAFConfig(SPIx_NSS_GPIO_PORT, SPIx_NSS_SOURCE, SPIx_NSS_AF);

 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  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  MISO pin configuration */

  GPIO_InitStructure.GPIO_Pin =  SPIx_MISO_PIN;

  GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure);  

 

  /* SPI  MOSI pin configuration */

  GPIO_InitStructure.GPIO_Pin =  SPIx_MOSI_PIN;

  GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);

  

   /* SPI  NSS pin configuration */

  GPIO_InitStructure.GPIO_Pin =  SPIx_NSS_PIN;

  GPIO_Init(SPIx_NSS_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_Hard;

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

  SPI_InitStructure.SPI_CRCPolynomial = 0;

  

  /* 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);

}

 

/**

  * @brief  Program entry point

  * @param  None

  * @retval None

  */

int main(void)

{

 g_sRecvInfo.lpBuffer = g_cbRecvBuffer;

 g_sRecvInfo.uWritePos = 0;

 g_sRecvInfo.uReadPos = 0;

 g_sRecvInfo.uSize = RECV_SIZE;

 

 

 

  /* SPI configuration */

  SPI_Config();

  

   SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;

  SPI_Init(SPIx, &SPI_InitStructure);

 

  

  /* Enable the Rx buffer not empty interrupt */

  SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_RXNE, ENABLE);

  

  /* Enable the Tx empty interrupt */

  SPI_I2S_ITConfig(SPIx, SPI_I2S_IT_TXE, ENABLE);

  

  /* Enable the SPI peripheral */

  SPI_Cmd(SPIx, ENABLE);

 

 

 

 

  /* Main loop */

  while (1)

  {

 

  }

 

#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

 

/**

  * @}

  */ 

 

 

/**

  * @}

  */ 

 

 

/**

  * @}

  */ 

 

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


中断处理

/**

  * @brief  This function handles SPI interrupt request.

  * @param  None

  * @retval None

  */

void SPIx_IRQHANDLER(void)

{

  /* SPI in Receiver mode */

  if (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_RXNE) == SET)

  {

      SPI_I2S_ReceiveData(SPIx);

  }

  /* SPI in Transmitter mode */

  if (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_TXE) == SET)

  {

    if(g_sRecvInfo.uReadPos != g_sRecvInfo.uWritePos || g_sRecvInfo.bIsWriteNewCycle)

    {

        SPI_I2S_SendData(SPIx, *(g_sRecvInfo.lpBuffer + g_sRecvInfo.uReadPos));

        if(++g_sRecvInfo.uReadPos == g_sRecvInfo.uSize)

        {

          g_sRecvInfo.uReadPos = 0;

   g_sRecvInfo.bIsWriteNewCycle = 0;

        }

    }

    else

    {

        /* Send Transaction data */

        SPI_I2S_SendData(SPIx, 0xFF);

}

  }

}


结构定义及对应IO定义

#include

#include "stm32f4xx_spi.h"

typedef struct _Recv_cb

{

u8 *lpBuffer;

u32 uWritePos;

u32 uReadPos;

u32 uSize;

u8 bIsWriteNewCycle;

}RECV_STRUCT;

 

 

 

#define BUFFERSIZE                       100

 

#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_NSS_PIN                  GPIO_Pin_12

#define SPIx_NSS_GPIO_PORT            GPIOB

#define SPIx_NSS_GPIO_CLK             RCC_AHB1Periph_GPIOB

#define SPIx_NSS_SOURCE               GPIO_PinSource12

#define SPIx_NSS_AF                   GPIO_AF_SPI2

 

#define SPIx_SCK_PIN                   GPIO_Pin_13

#define SPIx_SCK_GPIO_PORT             GPIOB

#define SPIx_SCK_GPIO_CLK              RCC_AHB1Periph_GPIOB

#define SPIx_SCK_SOURCE                GPIO_PinSource13

#define SPIx_SCK_AF                    GPIO_AF_SPI2

 

#define SPIx_MISO_PIN                  GPIO_Pin_14

#define SPIx_MISO_GPIO_PORT            GPIOB

#define SPIx_MISO_GPIO_CLK             RCC_AHB1Periph_GPIOB

#define SPIx_MISO_SOURCE               GPIO_PinSource14

#define SPIx_MISO_AF                   GPIO_AF_SPI2

 

#define SPIx_MOSI_PIN                  GPIO_Pin_15

#define SPIx_MOSI_GPIO_PORT            GPIOB

#define SPIx_MOSI_GPIO_CLK             RCC_AHB1Periph_GPIOB

#define SPIx_MOSI_SOURCE               GPIO_PinSource15

#define SPIx_MOSI_AF                   GPIO_AF_SPI2


注意:另外MASTER设备需要,先发送一个字节的时钟,然后再读取N个字节的时钟.

关键字:STM32  SPI  SLAVE 引用地址:STM32 SPI SLAVE

上一篇:关于 STM32 SPI 从机模式的问题
下一篇:LPC1788启动代码分析

推荐阅读最新更新时间:2024-03-16 16:22

STM32 MAX7219驱动的8*8 LED点阵
STM32驱动8*8的点阵,按照之前的接法试验了很多次,依然还是调不通。已经意识到可能是延时的问题了,在初始化函数中加了延时,在写数据的函数中加了延时,还是搞不定。其实最后解决的方法也挺简单的,只不过自己没经验罢了。开始填坑! 解决方法:在main函数中,一步一步的进行函数初始化,在进行MAX7219初始化之前加一个50MS的延时,竟然正常工作了,真的是坑,哈哈哈。自己虽菜,但是最终解决了问题,还是很不错的。还是我大互联网的功劳啊。 主程序就不贴了,很简单。
[单片机]
STM32 串口初始化时的BUG
单片机:stm32f103vet6 平台:野火STM32开发板 问题描述:串口在初始化(还未发送任何数据)的时候,PC端会接收到一个字节的乱码 状态:未解决 我调试串口的步骤一般是先初始化UART,然后printf重定向,最后在串口助手里面打印出一些数字。调试还算顺利,成功打印出一行数据。但是每次复位的时候,第一个字符之前都有会多出一个乱码,起初以为是TC置1的问题,改了好几遍都没有效果,后来想一想,TC置1的问题是发送的第一个字符丢失,现在的问题是,第一个字符不丢失,而是第一个字符前出现一个乱码。 串口助手设置十六进制显示,发现在最开始的时候会打印一个字符0xFE。 单步调试发现在串口初始化前的GPIO初始化USART1的TXD
[单片机]
STM32 Option Bytes位 重置为出厂设置
TM32 Option Bytes位 重置为出厂设置 JLINK 按照说明,在IAR安装目录下找到指定的运行程序JLinkSTM32.exe(D:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin)在JLink与板子有效连接的情况下运行此程序
[单片机]
<font color='red'>STM32</font> Option Bytes位 重置为出厂设置
STM32F4 SPI2初始化及收发数据使用库函数
我的STM32F4 Discovery上边有一个加速度传感器LIS302DL。在演示工程中,ST的工程师使用这个传感器做了个很令人羡慕的东西:解算开发板的姿态。当开发板倾斜时候,处于最上边的LED点亮,其他LED不亮。同时,用MicroUSB数据线将开发板连接电脑时,开发板就会虚拟成一个鼠标。倾斜开发板时,鼠标指针会向倾斜的方向移动。归根结底,就是牛B的ST工程师用加速度传感器完成了姿态解算。 在开发板上,加速度传感器使用了SPI方式用STM32F4芯片进行通信。STM32F4的SPI1 作为主机,与LIS302Dl进行通信,读取或者写入数据。由于我没有使用过STM32的SPI口,因此在板子的空余资源中找到了SPI2接口来
[单片机]
stm32如何在官网下载标准函数库
PS:st官网要求的是要登陆才能下载,所以大家需要先注册好一个st官网的一个账号 1、进入st官网 官网地址:https://www.st.com/content/st_com/en.html 2、找到stm32 3、选择标准函数库 https://www.st.com/en/embedded-software/stm32-embedded-software.html 4、选择你要下载的系列 5、说在后面的话 st官网的响应十分的慢,大家耐心等待
[单片机]
<font color='red'>stm32</font>如何在官网下载标准函数库
STM32系列可通过FMSC接口外扩并口SRAM
STM32MCU一般情况下配置有1~2MB双块Flash存储器和256KB SRAM,在某些应用设计中会出现内置RAM不足的情况,需要对STM32单片机进行外扩RAM的处理,可以选择更换更高RAM容量的单片机,除了价格贵还需要涉及其他被动器件的更改,STM32系列可以通过FMSC接口外扩并口SRAM,比如采用ISSI的IS62WV51216, IS62WV51216 SRAM芯片是一个8M容量,组织结构为512K*16的高速率低功耗静态随机存储器。IS62WV51216高性能CMOS工艺制造。高度可靠的工艺水准再加创新的电路设计技术,造就了这款高性能,低功耗的器件。使用IS62WV51216的片选引脚和输出使能引脚,可以简单
[单片机]
<font color='red'>STM32</font>系列可通过FMSC接口外扩并口SRAM
工程师实战干货分享:77条STM32知识汇总
以下是工程师结合自己的工作实战经验分享,总共有77条STM32知识汇总,建议收藏!SYSCLK时钟源有三个来源:HSI RC、HSE OSC、PLL等。 1、 SYSCLK时钟源有三个来源:HSI RC、HSE OSC、PLL 2、 MCO 可以提供4源不同的时钟同步信号,PA8 3、 GPIO口貌似有两个反向串联的二极管用作钳位二极管。 4、 ICode总线,DCode总线、系统总线、DMA总线、总线矩阵、AHB/APB桥 5、在使用一个外设之前,必须设置寄存器RCC_AHBENR来打开该外设的时钟 6、 STM32复位有三种:系统复位、上电复位、备份区域复位。其中系统复位除了RCC_CSR中
[单片机]
工程师实战干货分享:77条<font color='red'>STM32</font>知识汇总
SPI总线在51单片机系统中的实现
  一个完整的单片机系统,通常包括键盘输入、显示输出、打印输出、数据采集等许多功能模块。这些功能模块一般是通过I/O端口实现与单片机的数据交换,但是单片机的I/O端口有限,且一般用来处理数字信号,从而产生了总线式传输模式。   现在大多数单片机都是传统的三总线结构,即地址,数据,控制三总线。由于方便控制,三总线得到广泛的应用。但是作为并行总线,它也有一定的局限性。不适合远距离的传输。与I/O口的数目存在矛盾。随着电子技术的进步,发展出很多新的总线接口,如USB、I2C、CAN、SPI、1-Wire等。这些总线的特点都是串行接口,只需要几根甚至一根线就可以实现数据的传输。本文通过对支持SPI总线的AD器件MAX189性能分析,简要介
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved