⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spidriv.c

📁 单片机开发列程
💻 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 + -