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

📄 spi.c

📁 使用RC531读卡芯片读取二代身份证的模块软件设计部分
💻 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 + -