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

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.lryc.cn/news/2400602.html

相关文章:

  • 安装 Nginx
  • Vue-1-前端框架Vue基础入门之一
  • OurBMC技术委员会2025年二季度例会顺利召开
  • postman自动化测试
  • 力扣热题100之二叉树的直径
  • 数字人技术的核心:AI与动作捕捉的双引擎驱动(210)
  • c++ 命名规则
  • GRU 参数梯度推导与梯度消失分析
  • 针对KG的神经符号集成综述 两篇
  • RabbitMQ和MQTT区别与应用
  • Vue跨层级通信
  • docker常见命令行用法
  • Axure设计案例:滑动拼图解锁
  • MySQL权限详解
  • 基于BP神经网络的语音特征信号分类
  • 解决fastadmin、uniapp打包上线H5项目路由冲突问题
  • web3-区块链的交互性以及编程的角度看待智能合约
  • 数据结构(7)—— 二叉树(1)
  • ROS1和ROS2的区别autoware.ai和autoware.universe的区别
  • 如何使用 Docker 部署grafana和loki收集vllm日志?
  • Kafka入门- 基础命令操作指南
  • 目标检测我来惹1 R-CNN
  • lua的笔记记录
  • 智能进化论:AI必须跨越的四大认知鸿沟
  • L2-056 被n整除的n位数 - java
  • 传统足浴行业数字化转型:线上预约平台的技术架构与商业逻辑
  • Java-IO流之字节输入流详解
  • 从OCR到Document Parsing,AI时代的非结构化数据处理发生了什么改变?
  • 【C/C++】入门grpc的idl
  • 【Java实用工具类】手撸SqlBuilder工具类,优雅拼接动态SQL,MyBatisPlus同款风格!