当前位置: 首页 > 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.lqws.cn/news/124111.html

相关文章:

  • IEC 61347-1:2015 灯控制装置安全标准详解
  • RFID | 第一章:RFID系统概述
  • AtCoder-abc407_e解析
  • 在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
  • 第五期书生大模型实战营-《L1G1-玩转书生大模型 API 之 Browser-Use 实践》
  • 【多线程初阶】wait() notify()
  • 那些Java 线程中断的实现方式
  • 如果安装并使用RustDesk
  • window 显示驱动开发-提供视频解码功能(三)
  • GO语言---函数命名返回值
  • React从基础入门到高级实战:React 高级主题 - 测试进阶:从单元测试到端到端测试的全面指南
  • 深入详解开源工具DCMTK:C++开发的DICOM工具包
  • 更新 Docker 容器中的某一个文件
  • Java Stream 高级实战:并行流、自定义收集器与性能优化
  • 机器学习监督学习sklearn实战三:八种算法对印第安人糖尿病预测数据进行分类和比较
  • 基于对比学习的带钢表面缺陷分类研究,整合SimCLR自监督预训练与YOLOv8目标检测框架的技术解析及Python实现方案
  • 每天总结一个html标签——Audio音频标签
  • SOC-ESP32S3部分:30-I2S音频-麦克风扬声器驱动
  • 图像处理、图像分析和图像理解的定义、联系与区别
  • 【Pandas】pandas DataFrame reset_index
  • Delphi用if else实现 select case、switch语句功能,实现case 以字符串为分类条件。
  • AI IDE 正式上线!通义灵码开箱即用
  • (T/SAIAS 020-2024)《医疗大模型语料一体机应用指南》深度解读与实施分析
  • echarts使用graph、lines实现拓扑,可以拖动增加effect效果
  • Duix.HeyGem:以“离线+开源”重构数字人创作生态
  • 【运维实战】使用Nvm配置多Node.js环境!
  • Git安装与常用命令全攻略
  • C#编程过程中变量用中文有啥影响?
  • Zookeeper 集群部署与故障转移
  • C#和C++在编译过程中的文件区分