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

stm32使用hal库模拟spi模式3

因为网上模拟spi模拟的都是模式0,很少有模式3的。
模式3的时序图,在clk的下降沿切换电平状态,在上升沿采样, SCK空闲为高电平
在这里插入图片描述
初始化cs,clk,miso,mosi四个io。miso配置为输入,cs、clk、mosi配置为推挽输出。

  HAL_GPIO_WritePin(GPIOD, spi_sck_Pin|spi_cs_Pin, GPIO_PIN_SET);	//sck,cs空闲时为高GPIO_InitStruct.Pin = spi_miso_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(spi_sdo_GPIO_Port, &GPIO_InitStruct);GPIO_InitStruct.Pin = spi_mosi_Pin|spi_sck_Pin|spi_cs_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

my_spi.h

#ifndef __MY_SPI_H
#define __MY_SPI_H
#include "main.h"
#include "gpio.h"#define		SCK_H		HAL_GPIO_WritePin(GPIOD, spi_sck_Pin, GPIO_PIN_SET)
#define		SCK_L		HAL_GPIO_WritePin(GPIOD, spi_sck_Pin, GPIO_PIN_RESET)
#define		MOSI_H		HAL_GPIO_WritePin(GPIOD, spi_sdi_Pin, GPIO_PIN_SET)
#define		MOSI_L		HAL_GPIO_WritePin(GPIOD, spi_sdi_Pin, GPIO_PIN_RESET)
#define		MISO		HAL_GPIO_ReadPin(spi_sdo_GPIO_Port,spi_sdo_Pin)
#define		CS_H		HAL_GPIO_WritePin(GPIOD, spi_cs_Pin, GPIO_PIN_SET)
#define		CS_L		HAL_GPIO_WritePin(GPIOD, spi_cs_Pin, GPIO_PIN_RESET)uint8_t SOFT_SPI_RW_MODE3( uint8_t write_dat );void Delay5us(U8 delaycnt);#endif

my_spi.c

#include "my_spi.h"
#include "stdint.h"void delay_us(uint16_t i){uint8_t a;while(i--){for(a=6;a>0;a--);	//64mhz,6大概1us}
}void Delay5us(U8 delaycnt)
{U8 i;for(i=0; i<delaycnt; i++){delay_us(5);}
}//模式3测试通过
uint8_t SOFT_SPI_RW_MODE3( uint8_t write_dat )
{uint8_t i=0, read_dat=0;for( i = 0; i < 8; i++ ){SCK_L;if( write_dat & 0x80 )MOSI_H;elseMOSI_L;write_dat <<= 1;delay_us(2);SCK_H;read_dat <<= 1;if( MISO )read_dat++;delay_us(2);__nop();}return read_dat;
}/*
// CPOL = 0, CPHA = 0, MSB first
uint8_t SOFT_SPI_RW_MODE0( uint8_t write_dat )
{uint8_t i, read_dat;for( i = 0; i < 8; i++ ){if( write_dat & 0x80 )MOSI_H;  else                    MOSI_L;  write_dat <<= 1;delay_us(1);  SCK_H; read_dat <<= 1;  if( MISO ) read_dat++; delay_us(1);SCK_L; __nop();}return read_dat;
}// CPOL=0,CPHA=1, MSB first 
uint8_t SOFT_SPI_RW_MODE1(uint8_t byte) 
{uint8_t i,Temp=0;for(i=0;i<8;i++)     // 循环8次{SCK_H;     //拉高时钟if(byte&0x80){MOSI_H;  //若最到位为高,则输出高}else      {MOSI_L;   //若最到位为低,则输出低}byte <<= 1;     // 低一位移位到最高位delay_us(1);SCK_L;     //拉低时钟Temp <<= 1;     //数据左移if(MISO)Temp++;     //若从从机接收到高电平,数据自加一delay_us(1);}return (Temp);     //返回数据
}// CPOL=1,CPHA=0, MSB first 
uint8_t SOFT_SPI_RW_MODE2(uint8_t byte) 
{uint8_t i,Temp=0;for(i=0;i<8;i++)     // 循环8次{if(byte&0x80){MOSI_H;  //若最到位为高,则输出高}else      {MOSI_L;   //若最到位为低,则输出低}byte <<= 1;     // 低一位移位到最高位delay_us(1);SCK_L;     //拉低时钟Temp <<= 1;     //数据左移if(MISO)Temp++;     //若从从机接收到高电平,数据自加一delay_us(1);SCK_H;     //拉高时钟}return (Temp);     //返回数据
}
*/

使用示例:

 	CS_L;		// SPI_CS脚拉低,开始SPI通讯Delay5us(1);for (i=0; i<5; i++) {AFERxBuf[i]=SOFT_SPI_RW_MODE3(AFETxBuf[i]);}Delay5us(1);CS_H;		// SPI_CS脚拉高,结束SPI通讯
http://www.xdnf.cn/news/864631.html

相关文章:

  • git cherry-pick (28)
  • Redis初识
  • 华为ICT和AI智能应用
  • 深入理解系统:UML类图
  • YOLO12 改进|融入 Mamba 架构:插入视觉状态空间模块 VSS Block 的硬核升级
  • OpenCV C++ 学习笔记(六):绘制文本、几何绘图、查找/绘制轮廓
  • [蓝桥杯]取球博弈
  • 【发布实录】云原生+AI,助力企业全球化业务创新
  • Odoo17 技巧 | 如何获取Selection字段的显示值五种方法
  • Cisco IOS XE WLC 任意文件上传漏洞复现(CVE-2025-20188)
  • powershell 安装 .netframework3.5
  • CentOS7 + JDK8 虚拟机安装与 Hadoop + Spark 集群搭建实践
  • .Net Framework 4/C# 集合和索引器
  • C++ 使用 ffmpeg 解码本地视频并获取每帧的YUV数据
  • .NET 9中的异常处理性能提升分析:为什么过去慢,未来快
  • .net jwt实现
  • 12.RSA
  • 使用 React Native 开发鸿蒙运动健康类应用的​​高频易错点总结​​
  • 基于BP神经网络的语音特征信号分类
  • THUNDER:用“听回去”的方式让数字人说话更像真人
  • 内网穿透之Linux版客户端安装(神卓互联)
  • 【学习笔记】TCP 与 UDP
  • 化学方程式配平免费API接口教程
  • 图像处理、图像分析和图像理解的定义、联系与区别
  • vue 多端适配之pxtorem
  • 论文阅读笔记——Large Language Models Are Zero-Shot Fuzzers
  • 如何安全高效的文件管理?文件管理方法
  • MySQL补充知识点学习
  • 【触想智能】工业一体机在工厂智能化升级改造中的作用和应用分析
  • AI数字人在说话时怎样模拟呼吸?