SPI多从机

#include "GLOBAL_VAR.H"

uint8_t  SPI1TxBuf[SPI1_TXBUF_SIZE];     //-----------------SPI1发送缓冲区
//uint16_t SPI1TxReadPtr, SPI1TxWritePtr; //---------------SPI1发送缓冲区读写指针
uint8_t  SPI1RxBuf[SPI1_RXBUF_SIZE];     //-----------------SPI1接收缓冲区
//-------------------------------------------

uint8_t Stream_Spi1;   //SPI1 通道
//无论来自哪个管道的消息均通过消息处理程序来处理,每条消息包含以下内容:

#define SPI_BUFFER_NUMBERS 10 //消息队列存储器内可存储消息数量
#define SPI_BUFFER_STEP 100   //消息队列存储器内单条消息长度 流ID+40字节消息
#define SPI_BUFFER_LEN 1000

#define VOLTAGE_CHANEL 0
#define CURRENT_CHANEL 1

uint8_t *PC_Voltage;
static uint8_t SpiBuffer [AUXPLATE_CHANEL][SPI_BUFFER_LEN]; //消息队列存储器,每条存入队列的消息长度为41个字节
static uint8_t SpiWritePtr [AUXPLATE_CHANEL];               //存入消息队列的指针
static uint8_t SpiReadPtr [AUXPLATE_CHANEL];                //处理消息的指针
static uint8_t              AuxPlate_TYPE [AUXPLATE_CHANEL];   //辅板类型
static uint8_t              AuxPlate_LEN [AUXPLATE_CHANEL]; //辅板数据长度

void  AuxPlate_CS_H(uint8_t CS)
{
        switch(CS)
        case 0:
                 HAL_GPIO_WritePin(SPI1_CS1_GPIO_Port,SPI1_CS1_Pin,GPIO_PIN_RESET);
                                break;
            case 1:
                 HAL_GPIO_WritePin(SPI1_CS2_GPIO_Port,SPI1_CS2_Pin,GPIO_PIN_RESET);
                                    break;
            case 2:
                 HAL_GPIO_WritePin(SPI1_CS3_GPIO_Port,SPI1_CS3_Pin,GPIO_PIN_RESET);
                                break;
                         case 3:
                 HAL_GPIO_WritePin(SPI1_CS4_GPIO_Port,SPI1_CS4_Pin,GPIO_PIN_RESET);
                         break;
            case 4:
                  HAL_GPIO_WritePin(SPI1_CS5_GPIO_Port,SPI1_CS5_Pin,GPIO_PIN_RESET);
                        break;
            case 5:
                HAL_GPIO_WritePin(SPI1_CS6_GPIO_Port,SPI1_CS6_Pin,GPIO_PIN_RESET);
                        break;
        }
}
uint8_t SPI1_AuxPlate_ReadWriteByte(uint8_t TxData)//发送一个字节,并从寄存器返回一个字节
{
    uint8_t Rxdata;
    HAL_SPI_TransmitReceive_DMA(&hspi1, &TxData, &Rxdata, 1);       
     return Rxdata;                      
}//读取辅板类别
//返回值如下:
//0X01,电压采集;
//0X02,电流采集;
//0X03,频率信号采集;
//0X04,标准工业信号采集;
//0X05, IO输入信号采集;
//0X06,IO输出/继电器输出;
//0X07,辅源输出;
//0X08,信号输出;
//0X09,语音输出;
//0X0A,通讯模块;
//0X00,无板卡;
    
uint8_t SPI1_AuxPlate_ReadType(uint8_t Chanel)
{
      

 uint8_t Temp = 0;
         AuxPlate_CS_L(Chanel);     
         SPI1_AuxPlate_ReadWriteByte(0XFF);
         AuxPlate_CS_H(Chanel);
    
        AuxPlate_CS_L(Chanel);
    SPI1_AuxPlate_ReadWriteByte(AuxPlate_DeviceIDChk);                            //发送读取ID命令
    SPI1_AuxPlate_ReadWriteByte(0x00);
    SPI1_AuxPlate_ReadWriteByte(0x00);
    SPI1_AuxPlate_ReadWriteByte(0x84);
    Temp = SPI1_AuxPlate_ReadWriteByte(0xFF);
        AuxPlate_CS_H(Chanel);
    return Temp;
}

uint8_t SPI1_AuxPlate_Length(uint8_t Chanel)

{

    uint8_t arr;
         AuxPlate_CS_L(Chanel);     
    SPI1_AuxPlate_ReadWriteByte(AuxPlate_LengthChk);
    SPI1_AuxPlate_ReadWriteByte(0x00);
    SPI1_AuxPlate_ReadWriteByte(0x00);
    SPI1_AuxPlate_ReadWriteByte(0x84);
        arr = SPI1_AuxPlate_ReadWriteByte(0xFF);
        AuxPlate_CS_H(Chanel);     
    return arr;
}


//初始化辅板
void  SPI1_AuxPlate_Init(void)
{     
     int i;
   for(i=0;i<AUXPLATE_CHANEL;i++)
    {
                AuxPlate_TYPE[i] = SPI1_AuxPlate_ReadType(i);          // 读取辅板类型.
                        
    


        }
}


//读取SPI FLASH
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535)
void SPI1_Read(uint16_t Chanel,uint8_t *pBuffer, uint16_t NumByteToRead)
{
      uint16_t i;
      AuxPlate_CS_L(Chanel); //使能器件
    
    SPI1_AuxPlate_ReadWriteByte(AuxPlate_ReadData);             //发送读取命令

    for (i = 0; i < NumByteToRead; i++)
    {
        pBuffer[i] = SPI1_AuxPlate_ReadWriteByte(0XFF);       //循环读数
    }
        
    AuxPlate_CS_H(Chanel);

}

//读取W25QXX的状态寄存器
//BIT7  6   5   4   3   2   1   0
//SPR   RV  TB BP2 BP1 BP0 WEL BUSY
//SPR:默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:FLASH区域写保护设置
//WEL:写使能锁定
//BUSY:忙标记位(1,忙;0,空闲)
//默认:0x00
uint8_t AuxPlate_ReadSR(uint8_t Chanel)
{
    uint8_t byte = 0;
     AuxPlate_CS_L(Chanel);  //使能器件
    SPI1_AuxPlate_ReadWriteByte(AuxPlate_ReadStatusReg); //发送读取状态寄存器命令
    byte = SPI1_AuxPlate_ReadWriteByte(0Xff);          //读取一个字节
    AuxPlate_CS_H(Chanel);  //取消片选
    return byte;
}

//等待空闲
void AuxPlate_Wait_Busy(uint8_t Chanel)
{
    while ((AuxPlate_ReadSR(Chanel) & 0x01) == 0x01);          // 等待BUSY位清空
}
//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!
void AuxPlate_Write(uint16_t Chanel,uint8_t *pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
{
    uint16_t i;

    AuxPlate_CS_L(Chanel); //使能器件 

SPI1_AuxPlate_ReadWriteByte(AuxPlate_WriteEnable);          //发送写页命令
    SPI1_AuxPlate_ReadWriteByte((uint8_t)WriteAddr);
    for (i = 0; i < NumByteToWrite; i++)
        SPI1_AuxPlate_ReadWriteByte(pBuffer[i]); //循环写数
    AuxPlate_CS_H(Chanel);  //取消片选
    AuxPlate_Wait_Busy(Chanel);                               //等待写入结束
}

void Put_SPI_Msg(uint8_t Type,uint8_t Chanel, uint8_t *msg) //将收到的消息插入消息队列,等候处理
{

    uint8_t *buf;
        
    SpiBuffer[Chanel][SpiWritePtr[Chanel] * SPI_BUFFER_STEP] = Type; //每条消息的第一个子节为流ID
    
    buf = (uint8_t *)(SpiBuffer[Chanel] + SpiWritePtr[Chanel] * SPI_BUFFER_STEP + 1);
    
    memcpy(buf, msg, SPI_BUFFER_STEP); //
    
    SpiWritePtr[Chanel] = (SpiWritePtr[Chanel] + 1) % SPI_BUFFER_NUMBERS;
    //    EchoUART1(buf,MSG_BUFFER_STEP);
}

void SPI1_Channel_Read (uint8_t Chanel)  //SPI1 通道1 数据读取
{
     SPI1_Read(Chanel,SPI1RxBuf,SPI_BUFFER_STEP);
    
    if(SPI1RxBuf[0]==0xf9 && SPI1RxBuf[1] == 0xf8 && SPI1RxBuf[2] == AuxPlate_TYPE[Chanel] && SPI1RxBuf[3] == 0x64  && SPI1RxBuf[SPI_BUFFER_STEP-1]== 0XA8)

        {
            Put_SPI_Msg(AuxPlate_TYPE[Chanel],Chanel, (uint8_t *)(SPI1RxBuf+3)); //将受到的消息存入消息处理队列
            
            EchoUART1(SPI1RxBuf,AuxPlate_LEN[Chanel]);
        }
}

void Basal_SPI1_Read(void)

     uint8_t i;
    for(i=0;i<AUXPLATE_CHANEL;i++)
        if(ChkBit(Stream_Spi1,i))
        {
                 SPI1_Channel_Read(i);
        }
    }

void Basal_Read_Data(void)
    { 
        uint8_t i, Type;
    uint8_t *msg;


for(i=0;i<AUXPLATE_CHANEL;i++)
        {
            if (SpiWritePtr[i] == SpiReadPtr[i])
        return; //没有未处理的消息
            Type = SpiBuffer[i][SpiReadPtr[i] * SPI_BUFFER_STEP];
                if(Type==0x01)
                {
                    msg =  (uint8_t *)(SpiBuffer[i] + SpiReadPtr[i] * SPI_BUFFER_STEP+ 1);
                    
                        memcpy(PC_Voltage, msg + AuxPlate_LEN[i]*i, AuxPlate_LEN[i]); //
                }
        }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值