SPI通信(SPI1主机与SPI2从机)

芯片型号stm32f103

主机采用spi1,从机spi2,中断接收测试

主机配置函数:

#include "spi.h"
void SPI1_Init(void)
{    
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;
    
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);     //ʹÄÜPA¶Ë¿ÚʱÖÓ
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,   ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //ÍÆÍìÊä³ö
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;                
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
      
    //SPI_SSOutputCmd(SPI1,ENABLE);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//SPI_Mode_Master    SPI_Mode_Slave                             
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                               
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                                       
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                                     
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;    //SPI_NSS_Hard        SPI_NSS_Soft                               
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;    
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                           
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);
    
    SPI_Cmd(SPI1, ENABLE);
    SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
    
    NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);    
     SPI1_ReadWriteByte(0xff);//Æô¶¯´«Êä                         
}   
void SPI1_SetSpeed(u8 SpeedSet)
{
    SPI1->CR1&=0XFFC7;//Fsck=Fcpu/256
    if(SpeedSet==SPI_SPEED_2)//¶þ·ÖƵ
    {
        SPI1->CR1|=0<<3;//Fsck=Fpclk/2=36Mhz    
    }else if(SpeedSet==SPI_SPEED_8)//°Ë·ÖƵ
    {
        SPI1->CR1|=2<<3;//Fsck=Fpclk/8=9Mhz    
    }else if(SpeedSet==SPI_SPEED_16)//Ê®Áù·ÖƵ
    {
        SPI1->CR1|=3<<3;//Fsck=Fpclk/16=4.5Mhz
    }else                  //256·ÖƵ
    {
        SPI1->CR1|=7<<3; //Fsck=Fpclk/256=281.25Khz µÍË
    }
    SPI1->CR1|=1<<6; //
}
u8 SPI1_ReadWriteByte(u8 TxData)
{        
    u8 retry=0;                
    while((SPI1->SR&1<<1)==0)//µÈ´ý·¢ËÍÇø¿Õ    
    {
        retry++;
        if(retry>200)return 0;
    }              
    SPI1->DR=TxData;           //·¢ËÍÒ»¸öbyte
    retry=0;
    while((SPI1->SR&1<<0)==0) //µÈ´ý½ÓÊÕÍêÒ»¸öbyte  
    {
        retry++;
        if(retry>200)return 0;
    }                                  
    return SPI1->DR;          //·µ»ØÊÕµ½µÄÊý¾Ý                    
}

u8 SPI1_ReadByte(u8 TxData)
{        
    u8 retry=0;                
    while((SPI1->SR&1<<0)==0) //µÈ´ý½ÓÊÕÍêÒ»¸öbyte  
    {
        retry++;
        if(retry>200)return 0;
    }                                  
    return SPI1->DR;          //·µ»ØÊÕµ½µÄÊý¾Ý                    
}

#include "spi.h"
#include "sys.h" //ϵͳ×Óº¯Êý        
#include "delay.h" //ÑÓʱ×Óº¯Êý

//PA4 SPI1_NSS
//PA5 SPI1_SCK
//PA6 SPI1_MISO
//PA7 SPI1_MOSI

u8 Master_Temp =0;
int main(void)
{
         SystemInit();
         delay_init(72);         //ÑÓʱ³õʼ»¯
         NVIC_Configuration();    
        SPI1_Init(); //SPI1³õʼ»¯
        SPI1_SetSpeed(SPI_SPEED_256);
      GPIO_ResetBits(GPIOA,GPIO_Pin_4);
        while(1)
        {    
            SPI1_ReadWriteByte(0x22);        
            delay_ms(100);    
        }
}


void SPI1_IRQHandler(void)
{    
    if((SPI1->SR&1<<0)==1)
    {    
        Master_Temp = SPI1_ReadByte(0x00);
    }     
}

从机SPI2配置函数:

#include "spi.h"

void SPI2_Init(void)
{    
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,   ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
    
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15;                  
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
              
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IPD;         
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    GPIO_SetBits(GPIOB,GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
    
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;//SPI_Mode_Master    SPI_Mode_Slave                             
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                               
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                                       
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                                     
    SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;    //SPI_NSS_Hard        SPI_NSS_Soft                               
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;    
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                           
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI2, &SPI_InitStructure);
    SPI_I2S_ITConfig(SPI2,SPI_I2S_IT_RXNE,ENABLE);
        
    NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    SPI_Cmd(SPI2, ENABLE); //ʹÄÜSPIÍâÉè
}


//SpeedSet:
//SPI_SPEED_2   2·ÖƵ   (SPI 12M    --sys 24M)
//SPI_SPEED_8   8·ÖƵ   (SPI 3M     --sys 24M)
//SPI_SPEED_16  16·ÖƵ  (SPI 1.5M    --sys 24M)
//SPI_SPEED_256 256·ÖƵ (SPI  905.6K --sys 24M)

void SPI2_SetSpeed(u8 SpeedSet)
{
    SPI2->CR1&=0XFFC7;//Fsck=Fcpu/256
    if(SpeedSet==SPI_SPEED_2)//¶þ·ÖƵ
    {
        SPI2->CR1|=0<<3;//Fsck=Fpclk/2=36Mhz    
    }
    else if(SpeedSet==SPI_SPEED_8)//°Ë·ÖƵ
    {
        SPI2->CR1|=2<<3;//Fsck=Fpclk/8=9Mhz    
    }
    else if(SpeedSet==SPI_SPEED_16)//Ê®Áù·ÖƵ
    {
        SPI2->CR1|=3<<3;//Fsck=Fpclk/16=4.5Mhz
    }
    else                  //256·ÖƵ
    {
        SPI2->CR1|=7<<3; //Fsck=Fpclk/256=281.25Khz µÍËÙģʽ
    }
    SPI2->CR1|=1<<6; //SPIÉ豸ʹÄÜ      
}
u8 SPI2_ReadWriteByte(u8 TxData)
{        
    u8 retry=0;                
    while((SPI2->SR&1<<1)==0)//µÈ´ý·¢ËÍÇø¿Õ    
    {
        retry++;
        if(retry>200)return 0;
    }              
    SPI2->DR=TxData;           //·¢ËÍÒ»¸öbyte
    retry=0;
    while((SPI2->SR&1<<0)==0) //µÈ´ý½ÓÊÕÍêÒ»¸öbyte  
    {
        retry++;
        if(retry>200)return 0;
    }                                  
    return SPI2->DR;          //·µ»ØÊÕµ½µÄÊý¾Ý                    
}

u8 SPI2_ReadByte(u8 TxData)
{        
    u8 retry=0;                
    while((SPI2->SR&1<<0)==0) //µÈ´ý½ÓÊÕÍêÒ»¸öbyte  
    {
        retry++;
        if(retry>200)return 0;
    }                                  
    return SPI2->DR;          //·µ»ØÊÕµ½µÄÊý¾Ý                    
}

#include "sys.h" //ϵͳ×Óº¯Êý    
#include "delay.h" //ÑÓʱ×Óº¯Êý
#include "spi.h"


u8 Slave_Temp=0;

void SPI2_Init(void);             //³õʼ»¯SPI¿Ú
void SPI2_SetSpeed(u8 SpeedSet); //ÉèÖÃSPIËٶȠ  
u8 SPI2_ReadWriteByte(u8 TxData);

//PB13 SPI2_SCK
//PB14 SPI2_MISO
//PB15 SPI2_MOSI

int main(void)
{
         SystemInit();
         delay_init(72);         //ÑÓʱ³õʼ»¯
         NVIC_Configuration();    
        SPI2_Init(); //SPI2³õʼ»¯
        SPI2_SetSpeed(SPI_SPEED_256);//SPI2ËÙ¶ÈÁ½·ÖƵ
        while(1)
        {    
                delay_ms(100);    
        }
}


void SPI2_IRQHandler(void)
{
    if((SPI2->SR&1<<0)==1)
    {                    
        Slave_Temp = SPI2_ReadByte(0x00);    
    }     
}

/*************************************************************/

注意事项:主机片选引脚模式为推完输出,配置为复用无法控制输出电平,从机为硬件模式,上拉输入,主机初始化SPI时候,拉高nss引脚,发数据前拉低nss,从而从机nss被硬件拉低,选中该芯片。

你可能感兴趣的:(stm32)