×
单片机 > 单片机程序设计 > 详情

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

发布时间:2024-07-16 发布时间:
|

芯片型号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被硬件拉低,选中该芯片。




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机与232串口通讯