SPI通信协议

devtools/2024/10/25 8:31:32/

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.ppmy.cn/devtools/128634.html

相关文章

【Android】JNI报错 non-zero capacity for nullptr pointer分析

【Android】JNI报错 non-zero capacity for nullptr pointer分析 背景 某天&#xff0c;运行Android App时程序报错。 Abort message: JNI DETECTED ERROR IN APPLICATION: non-zero capacity for nullptr pointer: 1in call to NewDirectByteBufferfrom *****出错部分&#…

《YOLO目标检测》—— YOLOv1 详细介绍

文章目录 一、算法特点二、网络结构三、检测过程四、损失函数五、性能表现六、优缺点 YOLO v1&#xff08;You Only Look Once version 1&#xff09;是一种快速的目标检测算法&#xff0c;以下是对YOLO v1的详细介绍&#xff1a; 一、算法特点 端到端的网络结构&#xff1a;Y…

axios退休了吗?现代Web开发的新请求策略

表单草稿功能的实用价值 在软件开发中&#xff0c;表单是用户与系统交互的重要界面。用户通过填写表单来提交数据&#xff0c;而系统则需要确保这些数据的准确性和完整性。然而&#xff0c;在实际使用中&#xff0c;用户可能会因为各种原因中断填写过程&#xff0c;比如网络问…

内网穿透工具——Cpolar

什么是内网穿透 内网穿透是一种网络技术&#xff0c;它允许从公共网络&#xff08;例如互联网&#xff09;访问位于私有网络&#xff08;内网&#xff09;中的设备或服务。在传统的网络环境中&#xff0c;私有网络通常由路由器、防火墙和网络地址转换&#xff08;NAT&#xff…

Ubuntu 通过Supervisor 或者 systemd 管理 .Net应用

在 Ubuntu 上安装 .NET 8.0&#xff0c;通过 supervisor 或 systemd 管理 .NET 应用服务&#xff0c;确保应用能够自动启动、运行以及在崩溃时重启。 1. 安装 .NET 8.0 最新的Ubuntu版本已经不需要注册 Microsoft 包存储库了&#xff0c;具体的可以参考微软官方文档安装&…

百度翻译以及另外三款翻译工具推荐!!!

在这个全球化的时代&#xff0c;翻译工具已经成为我们生活中不可或缺的一部分。我们需要使用翻译工具来克服语言障碍&#xff0c;无论是出国旅行、商务谈判还是学术研究。那么&#xff0c;市场上有各种各样的翻译工具。有哪些好用的在线翻译软件呢&#xff1f;别担心&#xff0…

MySQL 9从入门到性能优化-权限表

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

AMD平台,5600X+6650XT,虚拟机安装macOS 15 Sequoia 15.0.1 (2024.10)

macOS 15 Sequoia终于出正式版了&#xff0c;没有Mac&#xff0c;所以还是虚拟机玩玩&#xff0c;还是属于折腾&#xff0c;安装过程和之前差不多&#xff0c;这次我从外网获得了8核和16核openCore&#xff0c;分享一下。 提前发一下ISO镜像地址和openCore引导磁盘地址 ISO镜…