主机程序spi.h
#ifndef _SPI_H
#define _SPI_H
#include "sys.h"
#define MOSI PHout(3) //主机输出,从机输入
#define SCLK PHout(4) //时钟引脚
#define MISO PBin(2) //主机输入,从机输出
#define CS1 PAout(4) //片选信号1
#define CS2 PAout(5) //片选信号2
void SPI_Init(void);
u8 SPI_ReadWrite(u8 dat, u8 choice);
#endif
spi.c
#include "spi.h"
#include "delay.h"
////////////////////////////////////////////////////////////////////////////////
//我们标定CPOL和CPHA都为0
//CPOL=0:时钟空闲时电平为低;
//CPHA=0;时钟周期的上升沿发送数据,时钟周期的下降沿接收数据;
////////////////////////////////////////////////////////////////////////////////
//SPI IO初始化
void SPI_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
__HAL_RCC_GPIOH_CLK_ENABLE(); //开启GPIOH时钟
GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_4; //PH3,4
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOH,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5; //PA4,5
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_2; //PB2
GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入
GPIO_Initure.Pull=GPIO_PULLUP; //下拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_3,GPIO_PIN_SET); //PH3置1
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_4,GPIO_PIN_SET); //PH4置1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET); //PA4置1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET); //PA5置1
}
//延时函数封装:可以进行改变延时的大小
void Delay()
{
delay_us(10); //延时1ms
}
//spi实现读写函数
//dat:要发送的数据
//choice: 选择的spi器件
u8 SPI_ReadWrite(u8 dat, u8 choice)
{
u8 temp;
SCLK = 0; //空闲时为低电平
Delay();
if (choice == 1)
{
CS1 = 0; //置低
}
else
{
CS2 = 0; //置低
}
Delay();
for (int i = 0; i < 8; i++)
{
MOSI = dat & 0x01; //低位在前
dat >>= 1;
SCLK = 1; //数据在上升沿时,主机发送数据,从机读取数据
Delay();
temp >>= 1; //下降沿时开始读取数据
if (MISO)temp++;
SCLK = 0;
Delay();
}
//片选关闭,不再选择
CS1 = 1;
CS2 = 1;
Delay();
return temp;
}
从机程序
spi.h
#ifndef _SPI_H
#define _SPI_H
#include "sys.h"
#define MOSI PHin(3) //主机输出,从机输入
#define SCLK PHin(4) //时钟引脚
#define MISO PBout(2) //主机输入,从机输出
#define CS1 PAin(4) //片选信号1
void SPI_Init(void);
u8 SPI_ReadWrite(u8 dat);
#endif
spi.c
#include "spi.h"
#include "delay.h"
////////////////////////////////////////////////////////////////////////////////
//我们标定CPOL和CPHA都为0
//CPOL=0:时钟空闲时电平为低;
//CPHA=0;时钟周期的上升沿采集数据,时钟周期的下降沿接收数据;
////////////////////////////////////////////////////////////////////////////////
//从机PB3输入,PB2,PH4输出
//SPI IO初始化
void SPI_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
__HAL_RCC_GPIOH_CLK_ENABLE(); //开启GPIOH时钟
GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_4; //PH3
GPIO_Initure.Mode=GPIO_MODE_INPUT; //推挽输入
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOH,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_4; //PA4
GPIO_Initure.Mode=GPIO_MODE_INPUT; //推挽输入
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_2; //PB2
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET); //PB3 HIGH
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);//PA4 LOW
}
//延时函数封装:可以进行改变延时的大小
void Delay()
{
delay_us(10); //延时1ms
}
//spi实现读写函数
//dat:要发送的数据
u8 SPI_ReadWrite(u8 dat)
{
u8 temp=0;
Delay();
for (int i = 0; i < 8; i++)
{
//数据在上升沿读取,在下降沿发送
if(SCLK==1)
{
Delay();
if (MOSI)temp++;
temp <<= 1;
}
else if(SCLK==0)
{
Delay();
if(dat&&0x80)MISO=1;
else MISO=0;
dat<<=1;
}
}
return temp;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
for (int i = 0; i < 8; i++)
{
MOSI = dat & 0x01; //低位在前
dat >>= 1;
SCLK = 1; //数据在上升沿时,主机发送数据,从机读取数据
Delay();
temp >>= 1; //下降沿时开始读取数据
if (MISO)temp++;
SCLK = 0;
Delay();
}
你这个temp应该是temp<<=1;否则只能返回0和1两个值,不会有其它值。这样先进的是高位。如果你想先读进的是低位,那程序得改一下了。
temp = 0;
for(int i = 0;i < 8;i++)
{
MOSI = dat & 0x01;
dat >> 1;
SCLK = 1;
Delay();
if(MISO)temp1 = 1 << i;else temp1 = 0;
temp |= temp1;
SCLK = 0;
Delay();
}
多谢老哥指点,初学stm32,我自己再改改
一周热门 更多>