📄 spi.c
字号:
//[SPI.c]IO模拟SPI---------------------------------------------------------*
//本文件包含: *
// (1)SPI0Init : SPI0初始化 *
// (2)SPI0SLAVECOM : SPI0从机通信 *
// (3)SPI1Init : SPI1初始化 *
// (4)SPI1MASTERCOM : SPI1主机通信 *
//硬件连接: *
// (1)SPI0使用PTA口与外部控制芯片通信 *
// (2)SPI1使用PTD口与射频基站芯片MF RC531通信 *
//-------------------------------------------------------------------------*
//头文件
#include "SPI.h" //SPI函数头文件
//函数
//SPI0Init:----------------------------------------------------------------*
//功能:SPI0通信初始化函数,定义为SPI从机 *
//参数:无 *
//返回:无 *
//#define SPI0_SS 3 //从机选择引脚位 *
//#define SPI0_SCK 2 //时钟引脚 *
//#define SPI0_MOSI 1 //主出从入 *
//#define SPI0_MISO 0 //主入从出 *
//-------------------------------------------------------------------------*
void SPI0Init()
{
//定义接口数据方向
//设定SPI0_SS引脚为下降沿中断
DisableKBint(); //屏蔽键盘中断(IMASKK = 1)
KBIER |= (1 << SPI0_SS); //引脚中断使能
KBSCR |= (1 << 2); //清除键盘中断请求(ACKK = 1)
SPI0_D &= ~(1 << SPI0_SCK); //时钟信号
SPI0_D &= ~(1 << SPI0_MOSI); //主出从入
SPI0_D |= (1 << SPI0_MISO); //主入从出
SPI0_P |= (1 << SPI0_MISO); //初始化为高
}
//SPI0SLAVECOM:------------------------------------------------------------*
//功能:SPI0从机通信程序 *
//参数:snddata-发送数据 *
//返回:接收数据 *
//#define SPI0_SS 3 从机选择引脚位 *
//#define SPI0_SCK 2 时钟引脚 *
//#define SPI0_MOSI 1 主出从入 *
//#define SPI0_MISO 0 主入从出 *
//-------------------------------------------------------------------------*
INT8U SPI0SLAVECOM(INT8U snddata)
{
INT8U redata; //接收数据
INT8U datalen; //数据长度
datalen = 0x08; //每次发送8位
//发送数据字节最高位上线
if((snddata & (1 << 7 )) == 0x00)
{
SPI0_P &= ~(1 << SPI0_MISO); //置低电平
}
else
{
SPI0_P |= (1 << SPI0_MISO); //置高电平
}
//判断片选信号是否选中(低电平)
while(((SPI0_P & (1 << SPI0_SS)) == 0x00) && datalen)
{
//从机选中
//检测SCK时钟信号,空闲低电平,高电平为产生跳变
while ((SPI0_P & (1 << SPI0_SCK)) == 0x00); //为低电平则等待
//SCK时钟高电平时操作
//读MOSI
if((SPI0_P & (1 << SPI0_MOSI)) == 0x00)
{
redata &= ~(1 << (datalen - 1)); //低电平
}
else
{
redata |= 1 << (datalen - 1 ); //高电平
}
//写MISO
if(datalen > 1)
{
if((snddata & (1 << (datalen - 2 ))) == 0x00)
{
SPI0_P &= ~(1 << SPI0_MISO); //置低电平
}
else
{
SPI0_P |= (1 << SPI0_MISO); //置高电平
}
}
while ((SPI0_P & (1 << SPI0_SCK)) != 0x00); //等待恢复为空闲低电平
datalen--; //继续下一位操作
}//while
return redata; //返回
}
//SPI1Init:----------------------------------------------------------------*
//功能:SPI1通信初始化函数,定义为SPI主机 *
//参数:无 *
//返回:无 *
//#define SPI1_SS 7 //从机选择引脚位 *
//#define SPI1_SCK 6 //时钟引脚 *
//#define SPI1_MOSI 5 //主出从入 *
//#define SPI1_MISO 4 //主入从出 *
//-------------------------------------------------------------------------*
void SPI1Init()
{
//定义引脚功能
//1.从机选择
SPI1_D |= (1 << SPI1_SS); //输出引脚
SPI1_P |= (1 << SPI1_SS); //初始化为高
//2.时钟信号
SPI1_D |= (1 << SPI1_SCK); //输出引脚
SPI1_P &= ~(1 << SPI1_SCK); //初始化为低
//3.主出从入
SPI1_D |= (1 << SPI1_MOSI); //输出引脚
SPI1_P |= (1 << SPI1_MOSI); //初始化为高
//4.主入从出
SPI1_D &= ~(1 << SPI1_MISO); //输入引脚
//SPI1_P &= ~(1 << SPI1_MISO); //初始化为低
}
//SPI1MASTERCOM:-----------------------------------------------------------*
//功能:SPI1主机通信程序 *
//参数:snddata-发送数据 *
//返回:接收数据 *
//#define SPI1_SS 7 //从机选择引脚位 *
//#define SPI1_SCK 6 //时钟引脚 *
//#define SPI1_MOSI 5 //主出从入 *
//#define SPI1_MISO 4 //主入从出 *
//-------------------------------------------------------------------------*
INT8U SPI1MASTERCOM(INT8U snddata)
{
INT8U redata; //接收数据
INT8U datalen; //数据长度
INT8U i;
datalen = 0x08; //每次发送8位
//操作8位
for(i = 0; i < datalen; i++)
{
//先将MOSI数据上线,高位优先
if((snddata & (1 << (datalen - 1 - i ))) == 0x00)
{
SPI1_P &= ~(1 << SPI1_MOSI); //置低电平
}
else
{
SPI1_P |= (1 << SPI1_MOSI); //置高电平
}
//读MISO数据
if((SPI1_P & (1 << SPI1_MISO)) == 0x00)
{
redata &= ~(1 << (datalen - 1 - i)); //低电平
}
else
{
redata |= 1 << (datalen -1 - i); //高电平
}
//SPI1_SCK空闲时为低电平,通信时置高
SPI1_P |= (1 << SPI1_SCK);
asm("NOP");
SPI1_P &= ~(1 << SPI1_SCK);
}//for
return redata;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -