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

SPI通信协议

SPI通信协议

  • 软件SPI

全双工,一主多从,同步。
四根线:片选SS(CS),主发从收MOSI(DO),主收从收MISO(DI),时钟SCK。
一共四种模式:

CPOL01
CPHA
0空闲状态下,SCL-低;第0个边缘移出数据(SS的下降沿);第1个边沿移入数据;第二个边沿移出数据;…空闲状态下,SCL-高;第0个边缘移出数据(SS的下降沿);第1个边沿移入数据;第二个边沿移出数据;…
1空闲状态下,SCL-低;;第1个边沿移出数据;第二个边沿移入数据…空闲状态下,SCL-高;;第1个边沿移出数据;第二个边沿移入数据…

软件SPI

引脚初始化

// CS:
void MySPI_W_SS(u8 BitValue)
{//根据BitValue,设置SS引脚的电平GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);		
}
// SCK
void MySPI_W_SCK(uint8_t BitValue)
{//根据BitValue,设置SCK引脚的电平GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);		
}
//MOSI
void MySPI_W_MOSI(uint8_t BitValue)
{//根据BitValue,设置MOSI引脚的电平,BitValue要实现非0即1的特性GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)BitValue);		
}
//MISO
uint8_t MySPI_R_MISO(void)
{//读取MISO电平并返回return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);			
}
void MySPI_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA4、PA5和PA7引脚初始化为推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA6引脚初始化为上拉输入/*设置默认电平*///SS默认高电平MySPI_W_SS(1);	
#if mode == 0 || mode == 1//SCK默认低电平										MySPI_W_SCK(0);		
#elif mode == 2 || mode == 3//SCK默认高电平										MySPI_W_SCK(1);	
#endif}

协议层:

//开始
void MySPI_Start(void)
{MySPI_W_SS(0);				//拉低SS,开始时序
}
//停止
void MySPI_Stop(void)
{MySPI_W_SS(1);				//拉高SS,终止时序
}

交换一个字节
模式0:
SCK-空闲状态默认为零。
从第0个边沿开始移出,然后依次移入,移出

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{uint8_t i,ByteReceive = 0x00;//前面是开始信号,SS被拉低相当与第0个边沿for(i=0;i<8;i++)  //接收一个字节 8位{MySPI_W_MOSI(ByteSend & (0x80 >> i)); //移出MySPI_W_SCK(1);				//下一个边沿 开始移入//当MISO为1时,置变量指定位为1,当MISO为0时,不做处理,指定位为默认的初值0if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);} //移入MySPI_W_SCK(0);  //再来一个边沿,数据切换变成移出}//返回接收到的一个字节数据return ByteReceive;								
}

模式1:
SCK-空闲状态默认为零。
从第1个边沿开始移出,然后依次移入,移出.

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{uint8_t i,ByteReceive = 0x00;for(i=0;i<8;i++)  //接收一个字节 8位{	MySPI_W_SCK(1);				//第一个边沿 移出MySPI_W_MOSI(ByteSend & (0x80 >> i)); //移出MySPI_W_SCK(0);  //再来一个边沿,数据切换变成移入if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);} //移入}//返回接收到的一个字节数据return ByteReceive;								
}

模式2:
SCK-空闲状态默认为高。
从第0个边沿开始移除,然后依次移入,移出.

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{uint8_t i,ByteReceive = 0x00;//前面是开始信号,SS被拉低相当与第0个边沿for(i=0;i<8;i++)  //接收一个字节 8位{MySPI_W_MOSI(ByteSend & (0x80 >> i)); //移出MySPI_W_SCK(0);				//下一个边沿 开始移入//当MISO为1时,置变量指定位为1,当MISO为0时,不做处理,指定位为默认的初值0if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);} //移入MySPI_W_SCK(1);  //再来一个边沿,数据切换变成移出}//返回接收到的一个字节数据return ByteReceive;								
}

模式3:
SCK-空闲状态默认为零。
从第1个边沿开始移出,然后依次移入,移出.

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{uint8_t i,ByteReceive = 0x00;for(i=0;i<8;i++)  //接收一个字节 8位{	MySPI_W_SCK(0);				//第一个边沿 移出MySPI_W_MOSI(ByteSend & (0x80 >> i)); //移出MySPI_W_SCK(1);  //再来一个边沿,数据切换变成移入if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);} //移入}//返回接收到的一个字节数据return ByteReceive;								
}

http://www.mrgr.cn/news/57524.html

相关文章:

  • 认识ldconfig,不仅仅可以用于查看库的版本
  • Artistic Oil Paint 艺术油画着色器插件
  • “创新”何太急-03-系统用例是“深入到系统内部”?
  • Nacos相关问题
  • 排序算法 —— 快速排序(理论+代码)
  • ASP.NET Core8.0学习笔记(二十一)——EFCore关系配置API
  • 【正点原子K210连载】第四十八章 自学习分类实验 摘自【正点原子】DNK210使用指南-CanMV版指南
  • Dalvik汇编语言基础
  • 照片水印怎么去掉?这4种图片去水印方法简单好用!
  • 深入理解JWT(JSON Web Token):身份验证与信息安全
  • ArcGIS 10.8 安装教程
  • 【Ubuntu】Ubuntu22双网卡指定网关
  • 大模型技术学习过程梳理,零基础入门到精通,收藏这一篇就够了
  • nginx配置文件详解
  • tesseract-ocr 文本识别开发指南
  • Vue2中几个目录
  • 1024:只为遇见更好的自己
  • NumPy 与 Pandas 数据操作对比:从高效计算到灵活分析的转变
  • 基于大模型的Milvus向量数据库的背景与实战应用,计算与索引机制,Python代码实现
  • 如何在浏览器中打开预览pdf,而不是下载
  • 基于neo4j的疫情信息管理系统
  • C# 委托简述
  • 基于SSM健身国际俱乐部系统的设计
  • 好的代码——个人观点
  • 2024怎么保护企业办公文件?10款企业常用的文件加密软件排行榜!
  • docker部署SQL审核平台Archery