stm32使用hal库模拟spi模式3

因为网上模拟spi模拟的都是模式0,很少有模式3的。

模式3的时序图,在clk的下降沿切换电平状态,在上升沿采样, SCK空闲为高电平

初始化cs,clk,miso,mosi四个io。miso配置为输入,cs、clk、mosi配置为推挽输出。

c 复制代码
  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

c 复制代码
#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

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;
        else
            MOSI_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);     //返回数据
}
*/

使用示例:

c 复制代码
 	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通讯
相关推荐
智购科技自动贩卖机9 小时前
自动售货机嵌入式状态机设计实战:从45个事件源到层次型状态机的工程重构
大数据·人工智能·stm32·物联网·重构·硬件架构
长江后浪博客10 小时前
ESP32-SOLO-1 在 ESP-IDF v5.5 下启动不断重启问题分析与解决
单片机·嵌入式硬件·嵌入式·esp32·freertos·esp-idf
单片机仿真设计11 小时前
【proteus仿真】基于 STM32 单片机智能仓库设计(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus·毕设
星游路11 小时前
单片机·电子时钟
单片机·嵌入式硬件
AOI小白新手上路14 小时前
江科协51单片机 7-2 LCD1602显示时钟实验
单片机·嵌入式硬件·51单片机
思麟呀15 小时前
嵌入式入门(一)宏观生态到首次烧录
c语言·嵌入式硬件
runningshark15 小时前
SC32L14GR8PJR
单片机·嵌入式硬件
智购科技无人售货机厂家15 小时前
2026自动售货机备用电池管理系统设计:从充放电保护到健康监测的工程实践~YH
大数据·linux·单片机·嵌入式硬件·微信
智购无人售货机厂家15 小时前
2026自动售货机软硬件版本管理策略:从版本号规范到兼容性矩阵的工程实践~YH
运维·服务器·人工智能·单片机·嵌入式硬件·线性代数·矩阵
花 满 楼15 小时前
RISC-V APLIC 中断模块总结——第二篇
单片机·嵌入式硬件·mcu·risc-v