STM32 SPI SLAVE
2015-06-24 18:49
435 查看
一般使用SPI都用MASTER,但是用SLAVE没有用过.参考了ST的例子,发现不能满足自己的使用.于是,自己修改了一下.
初始化配置SPI
中断处理
结构定义及对应IO定义
注意:另外MASTER设备需要,先发送一个字节的时钟,然后再读取N个字节的时钟.
初始化配置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 * * <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. * ****************************************************************************** */ /* 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 <string.h> #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个字节的时钟.
相关文章推荐
- image sensor 关于像素的误解
- java和andorid开发所需的环境的搭建
- CentOS 6.4安装配置LAMP服务器(Apache+PHP5+MySQL)
- Comparing randomized search and grid search for hyperparameter estimation
- CentOS 6.4安装配置LAMP服务器(Apache+PHP5+MySQL)
- What's the difference between Template and Table in Smartforms
- 10-【MongoDB入门教程】 Journaling日志机制
- windows server 2012 iis8.0部署mvc报错:未能加载文件或程序集“System.Web.Http.WebHost
- sdl 使用介绍网址
- 解决“只能通过Chrome网上应用商店安装该程序”的方法
- Bluemix云平台实践: CLI应用之DB2控制台(1)
- 限制 UITextField 输入长度
- loadrunner-thinktime
- 【LeetCode】204. Count Primes
- label字体闪烁效果
- 极客学院视频下载
- js--小结⑦---格式转换
- 如何开始创业
- android5.0 imx6 some TF car(micro sd card) boot failed
- 什么是Hessian协议呢?