📄 spidriv.c
字号:
#define __SPIDRIV_H__
#include "Config.h"
#define WREN 0x06 //写使能
#define WRDI 0x04 //写禁止
#define RDSR 0x05 //读状态寄存器
#define WRSR 0x01 //写状态寄存器
#define READH 0x0B //读存储器的高半部分
#define READL 0x03 //读存储器的低半部分
#define WRITEH 0x0A //写存储器的高半部分
#define WRITEL 0x02 //写存储器的低半部分
/********************************************************************************************************
**函数名称: SPIInit
**函数功能: SPI接口初始化
**输 入: 无
**输 出: 无
********************************************************************************************************/
void SPIInit(void)
{
PERIPHEN1 |= (BIT7 | BIT6); //SPI接口使能;SPI CS禁止,作为通用IO口(CS0除外)
//--------------------------------------------------------------------
#ifdef DOWNLOAD
while((SPISTATUS & BIT3) == 0x00); //等待SPI准备好
#endif
//--------------------------------------------------------------------
SPICTRL = (0 | BIT6 | BIT5 | 0 | 0 | 0 | BIT1 | BIT0); //上升沿采样,休眠时停留为高电平
//通信速率sysclk/32;
//CS0使能
//SPI模式0(模式3也可以)
//SPI主模式
SPICONFIG = (BIT7 | 0 | 0 | 0 | 0 | 0 | 0 | 0); //CS手动控制
//片选自动控制
//CS3正常模式
//正常传输模式
//接收溢出中断禁止
//接收中断禁止
//发送缓冲空使能
SPISTATUS = 0x00; //正常模式
//至少一个片选有效
//中断标志清零
//SPISIZE = 0x07; //8位传输模式
}
/********************************************************************************************************
**函数名称: FMSPIWrite
**函数功能: 写数据到存储器
**输 入: Src: 要写入到存储器的数据的缓冲区指针
Dst: 要写入的存储器的地址
DataLen: 要写入的数据长度
**输 出: 无
********************************************************************************************************/
void FMSPIWrite(uchar * Src, uint Dst, uint DataLen)
{
uchar Temp;
//-----------------------------------------
//因为只发送一个字节,所以用自动模式即可
SPICONFIG &= ~BIT7;
//-----------------------------------------
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = WREN; //在写之前先发送写使能
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
//-----------------------------------------
//下面要发送多个字节故转为/CS手动控制方式
SPICONFIG |= BIT7; //转换为手动模式
//-----------------------------------------
if(Dst < 0x100) //如果是写低半部分
{
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = WRITEL; //低半部写
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = (uchar)(Dst & 0x00FF); //发送字节地址
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
}
else //写高半部分
{
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = WRITEH; //高半部写
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = (uchar)(Dst & 0x00FF); //发送字节地址
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
}
for(; DataLen --; DataLen > 0)
{
Temp = SPIRXTX0; //读清标志
SPIRXTX0 = *Src; //写数据
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待数据发送完成
#endif
Src ++; //指向下一个要发送的数据
}
//-----------------------------------------
//必须在一个操作完成之后再置高/CS
SPICONFIG &= ~BIT7; //拉高CS,(同时设为自动模式)
//-----------------------------------------
}
/********************************************************************************************************
**函数名称:FMSPIRead
**函数功能:读入数据数据到存储器
**输 入:DSt: 要存储读到的数据的缓冲区指针
Src: 要读数据的存储器的地址
DataLen: 要写入的数据长度
**输 出:读回的数据存储到DST指向的缓冲
********************************************************************************************************/
void FMSPIRead(uchar * Dst, uint Src, uint DataLen)
{
uchar Temp;
//-----------------------------------------
//由于要读写多字节,设为为手动模式,手动控制/CS
SPICONFIG |= BIT7;
//-----------------------------------------
Temp = SPIRXTX0; //DummyRead 清标志
if(Src < 0x100) //读低字节
{
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = READL;
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = (uchar)(Src & 0x00FF); //发送字节地址
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
}
else //读高字节
{
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = READH;
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
Temp = SPIRXTX0; //DummyRead to clear SPIRXAV flag 清接收标志
SPIRXTX0 = (uchar)(Src & 0x00FF); //发送字节地址
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0); //等待发送完成
#endif
}
for(; DataLen --; DataLen > 0)
{
Temp = SPIRXTX0;
SPIRXTX0 = 0x00; //产生接收数据时钟
#ifdef DOWNLOAD
while((SPISTATUS & BIT1) == 0);
#endif
*Dst = SPIRXTX0; //读回数据
Dst ++;
}
//-----------------------------------------
//必须在一个操作完成之后再置高/CS
SPICONFIG &= ~BIT7; //拉高CS
//-----------------------------------------
}
/********************************************************************************************************
**函数名称:FM25L04Test
**函数功能:25CL04数据存储器测试
**输 入: 无
**输 出: 无
********************************************************************************************************/
void FM25L04Test(void)
{
//-----------------------------------------------
//SPI接口存储器FM25L04测试时用到的变量
//-----------------------------------------------
uint xdata FM25L04ADDR;
uchar xdata FM25L04DatWR; //写入的数据
uchar xdata FM25L04WRStore[512]; //写入数据存储的数组
uchar xdata FM25L04RDStore[512]; //读取的数据存储殊组
//-----------------------------------------------
FM25L04ADDR = 0x0000; //25L04的地址计数器
//memset(FM25L04WRStore, 512, 0); //清空写RAM
//memset(FM25L04RDStore, 512, 0); //清空读RAM
UART0_Printf("\n ->FM25L04 test begin: \n");
//-----------------------------------------------
//先将待写的数据存储,方便用写多字节的方法一次写入
//-----------------------------------------------
for(FM25L04ADDR = 0x00; FM25L04ADDR < 512; FM25L04ADDR ++)
{
FM25L04DatWR = (int)rand();
FM25L04WRStore[FM25L04ADDR] = FM25L04DatWR;
}
FMSPIWrite(FM25L04WRStore, 0x00, 512); //写入512字节数据
#ifdef FM25L04DATASHOW
UART0_Printf("\n\n Write to 0x:%x \n",0x0000);
for(FM25L04ADDR = 0x00; FM25L04ADDR < 512; FM25L04ADDR ++)
{
UART0_Printf(" %d ",(int)FM25L04WRStore[FM25L04ADDR]);
}
#endif
//-------------------------------------------------
//读出所有的数据并存起来,下面将其写入的数据挨个比较
//-------------------------------------------------
FMSPIRead(FM25L04RDStore, 0x00, 512); //读取所有数据
#ifdef FM25L04DATASHOW
UART0_Printf("\n\n Read from 0x:%x \n",0x0000);
for(FM25L04ADDR = 0x00; FM25L04ADDR < 512; FM25L04ADDR ++)
{
UART0_Printf(" %d ",(int)FM25L04RDStore[FM25L04ADDR]);
}
#endif
for(FM25L04ADDR = 0x00; FM25L04ADDR < 512; FM25L04ADDR ++) //检查是否有错误
{
if(FM25L04RDStore[FM25L04ADDR] == FM25L04WRStore[FM25L04ADDR])
{;}
else
{
UART0_Printf("\n\n Data Err Occur at 0x:%x \n\n", FM25L04ADDR);
}
}
UART0_Printf("\n FM25L04 test OK! \n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -