当前位置: 首页 > news >正文

STM32-SPI数据发送/接收代码

#include "stm32f10x.h"

void App_SPI1_Init(void);//APP表示应用层代码,也就是用户自己写的
void APP_SPI_MasterTransmitReceive(SPI_TypeDef *SPIx, const uint8_t *pDataTx, uint8_t *pDataRx, uint16_t Size);

int main(void)
{
void App_SPI1_Init();
while(1)
{
}
}

void App_SPI1_Init(void){
//#1.初始化IO引脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE);

GPIO_InitTypeDef GPIO_InitStruct;

//PB3 SCK AF_PP 2MHz
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOB, &GPIO_InitStruct);

//PB4 MOSI IPU
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;

GPIO_Init(GPIOB, &GPIO_InitStruct);

//PB5 MISO AF_PP 2MHz
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOB, &GPIO_InitStruct);

//PA15 普通IO Out_PP 2MHz
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOA, &GPIO_InitStruct);

//#2.对SPI本身进行初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

SPI_InitTypeDef SPI_InitStruct;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;

SPI_Init(SPI1, &SPI_InitStruct);

SPI_NSSInternalSoftwareConfig(SPI1, SPI_NSSInternalSoft_Set);//向NSS引脚输入1,接到高电压防止主机被当作从机
}

void APP_SPI_MasterTransmitReceive(SPI_TypeDef *SPIx, const uint8_t *pDataTx, uint8_t *pDataRx, uint16_t Size){

//#1.闭合总开关
SPI_Cmd(SPIx, ENABLE);

//#2.发送第一个字节
SPI_I2S_SendData(SPIx, pDataTx[0]);//若不发第一个字节,RDR中无数据可读,也无法开始接收数据。

//#3.循环Size-1次
for(uint8_t i=0; i<Size-1; i++){
//发送字节(先等待TxE,再循环,直至发到第i+1个字节)
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE)== RESET);
SPI_I2S_SendData(SPIx, pDataTx[i+1]);

//接收字节(先等待RxNE,再循环,直至接收到第i个字节)
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE)== RESET);
pDataRx[i] = SPI_I2S_ReceiveData(SPIx);
}

//#4.接收最后一个字节(第Size-1个)
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE)== RESET);
pDataRx[Size-1] = SPI_I2S_ReceiveData(SPIx);

//#5.断开总开关
SPI_Cmd(SPIx,DISABLE);
}

http://www.cnnetsun.cn/news/15566.html

相关文章:

  • ImageGPT技术解析:像素序列预测如何重构视觉AI底层架构
  • Beyond Compare 5 密钥生成完整指南:从原理到实战应用
  • 手艺人札记:在开源系统中重塑技术的温度
  • 5种方法彻底解决番茄小说离线下载难题
  • 史诗级漏洞警报:ASP.NET Core 被曝 CVSS 9.9 分漏洞,几乎所有.NET 版本无一幸免!
  • Cider音乐播放器终极指南:跨平台Apple Music体验全解析
  • 力扣刷题:最大子数组和
  • ⭐力扣刷题:岛屿数量
  • Screenbox媒体播放器:深度解析Windows平台的现代播放解决方案
  • 5步重构OpenSTM扫描隧道显微镜项目架构
  • DXVK终极配置手册:Linux游戏性能优化的完整解决方案
  • 活字格低代码平台:企业数字化转型的技术架构与实践剖析
  • NVIDIA CUDA 13.1权威指南:CUDA Tile驱动下一代GPU编程,性能全面提升
  • Figma中文界面完整指南:快速实现设计工具本地化
  • 重新定义AI视觉评估:多维度评分系统深度解析
  • Hap视频编解码器:专业级QuickTime硬件加速终极指南
  • 阿里Wan2.1开源:消费级GPU如何重塑视频创作生态
  • 40亿参数改写边缘AI规则:Qwen3-VL-4B-Thinking-FP8轻量化多模态革命
  • MATLAB图像导出专业指南:掌握export_fig的核心技术
  • AI浪潮下的新职业生态:技术角色的系统性演化
  • SQL优化实战:标量子查询改写外连接的真实案例
  • Claude Code 杀疯了!首创“后台实习生”模式,这才是真正的 AI 结对编程!
  • 多进程环境中解决 PHP 文件系统锁定问题指南
  • 浅谈InheritableThreadLocal---线程可继承的小书包
  • Jellyfin Android TV客户端音频播放异常问题深度解析
  • HFI高频方波注入方案stm32f405 无感FOC控制 直接闭环启动 永磁同步电机无感控制...
  • CTR预测系统构建实战:从FM到DeepFM的推荐算法演进之路
  • 从零玩转RT-Thread(22):定时器底层机制揭秘
  • B站缓存视频转换完整教程:m4s-converter高效管理本地视频
  • 解锁企业级后台管理:用Vue.js和Element-UI构建高效前端解决方案