代码1:
#define MOSI_H GPIO_SetBits(GPIOB, GPIO_Pin_10)
#define MOSI_L GPIO_ResetBits(GPIOB, GPIO_Pin_10)
#define SCLK_H GPIO_SetBits(GPIOB, GPIO_Pin_13)
#define SCLK_L GPIO_ResetBits(GPIOB, GPIO_Pin_13)
#define MISO GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)
unsigned char SPI_ReadSendByte(unsigned char dt)//接受一个字节
{
u8 i;
u8 temp=0;
for(i=8;i>0;i--)
{
if(dt&0x80)MOSI_H;
else MOSI_L;
dt<<=1;
SCLK_H;
__NOP();//空白指令,用于延时//一个_NOP为1/sysclock,默认sysclock=72M,即——NOP=1/72us
__NOP();
__NOP();
temp<<=1;
if(MISO)temp++;
__NOP();
__NOP();
__NOP();
SCLK_L;
}
return temp;
}
2、代码2:
#ifndef __DRIVER_SPI_H
#define __DRIVER_SPI_H
#include "sys.h"
/************************* SPI 硬件相关定义 *************************/
#define SPI_GPIOx GPIOB
#define RCC_APB2Periph_GPIOx RCC_APB2Periph_GPIOB
#define SPI_GPIO_CSN GPIO_Pin_12 //片选
#define SPI_GPIO_SCK GPIO_Pin_13 //时钟
#define SPI_GPIO_MOSO GPIO_Pin_14 //输入
#define SPI_GPIO_MOSI GPIO_Pin_15 //输出
//SPI时钟
#define SCK_L GPIO_ResetBits(SPI_GPIOx , SPI_GPIO_SCK)
#define SCK_H GPIO_SetBits(SPI_GPIOx , SPI_GPIO_SCK)
//SPI输入
#define READ_MISO GPIO_ReadInputDataBit(SPI_GPIOx, SPI_GPIO_MOSO)
//SPI片选信号
#define CSN_L GPIO_ResetBits(SPI_GPIOx, SPI_GPIO_CSN)
#define CSN_H GPIO_SetBits(SPI_GPIOx, SPI_GPIO_CSN)
//SPI输出
#define MOSI_L GPIO_ResetBits(SPI_GPIOx , SPI_GPIO_MOSI)
#define MOSI_H GPIO_SetBits(SPI_GPIOx , SPI_GPIO_MOSI)
void mySPI_Init(void); //SPI 初始化
u8 mySPI_ReadWriteByte(u8 TxData); //模拟SPI读写数据函数
#endif
/************************* SPI 硬件相关定义结束 *************************/
#include "Driver_SPI.h"
/*
* 函数名:void Delay(vu32 nCount)
* 输入参数:nCount 延时计数
* 返回值:无
* 函数作用:阻塞式软件延时
*/
void Delay(vu32 nCount)
{
for(; nCount != 0; nCount--);
}
/*
* 函数名:void SPI_Init(void)
* 输入参数:
* 返回值:无
* 函数作用:初始化 SPI 的四根引脚
*/
void mySPI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx, ENABLE); //使能端口时钟
GPIO_InitStructure.GPIO_Pin = SPI_GPIO_CSN|SPI_GPIO_SCK|SPI_GPIO_MOSI; //端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(SPI_GPIOx, &GPIO_InitStructure); //根据设定参数初始化
CSN_H; //片选不选中
GPIO_InitStructure.GPIO_Pin = SPI_GPIO_MOSO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_GPIOx, &GPIO_InitStructure);
}
/*
* 函数名:u8 mySPI_ReadWriteByte(u8 TxData)
* 输入参数:TxData 待写入的数据
* 返回值:读取到的数据
* 函数作用:模拟SPI读写数据
*/
u8 mySPI_ReadWriteByte(u8 TxData)
{
u16 bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
if(TxData & 0x80) MOSI_H;
else MOSI_L;
TxData = (TxData << 1);
SCK_H;
Delay(0xff);
if(READ_MISO) TxData |= 0x01;
SCK_L;
Delay(0xff);
}
return(TxData);
}
本文介绍了如何在单片机上模拟SPI通信,通过代码1和代码2详细展示了实现过程,帮助读者理解并应用到自己的项目中。

4878

被折叠的 条评论
为什么被折叠?



