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通讯
相关推荐
Blossom.1185 分钟前
把 AI 推理塞进「 8 位 MCU 」——0.5 KB RAM 跑通关键词唤醒的魔幻之旅
人工智能·笔记·单片机·嵌入式硬件·深度学习·机器学习·搜索引擎
桃源学社(接毕设)1 小时前
基于人工智能和物联网融合跌倒监控系统(LW+源码+讲解+部署)
人工智能·python·单片机·yolov8
玖別ԅ(¯﹃¯ԅ)2 小时前
PID学习笔记6-倒立摆的实现
笔记·stm32·单片机
清风6666667 小时前
基于51单片机的手机蓝牙控制8位LED灯亮灭设计
单片机·嵌入式硬件·智能手机·毕业设计·51单片机·课程设计
anghost15014 小时前
基于单片机的超市储物柜设计
单片机·嵌入式硬件·超市储物柜设计
qq_5260991318 小时前
工控机的用途与介绍:工业自动化的重要引擎
嵌入式硬件·自动化·电脑
尘似鹤18 小时前
旋钮键盘项目---foc讲解(开环)
单片机·嵌入式硬件
意法半导体STM3219 小时前
STM32N6引入NPU,为边缘AI插上“隐形的翅膀”
单片机·ai·npu·st·stm32n6·边缘人工智能
范纹杉想快点毕业1 天前
嵌入式 C 语言编程规范个人学习笔记,参考华为《C 语言编程规范》
linux·服务器·数据库·笔记·单片机·嵌入式硬件·fpga开发
Wallace Zhang1 天前
STM32 - Embedded IDE - GCC - 解决LWRB库在GCC编译器会编译失败,在ARMCC编译器时却正常编译
ide·stm32·嵌入式硬件