stm32寄存器版學習筆記10 SPI


  SPI(Serial Peripheral Interface),串行外圍設備接口。SPI是一種高速的、全雙工、同步的通信總線。

SPI接口一般使用4條線通信:

  MISO 主設備數據輸入,從設備數據輸出

  MOSI 主設備數據輸出,從設備數據輸入

  SCLK 時鍾信號,有主設備產生

  CS 從設備片選信號,有主設備控制

  SPI模塊為了和外設進行數據交換,根據外設工作要求,其輸出串行同步時鍾極性和相位可以進行配置。SPI_CR寄存器的CPOL(時鍾極性)位,控制在沒有數據傳輸時時鍾的空閑狀態電平,此位對主模式和從模式下的設備都有效。CPOL=0,串行同步時鍾的空閑狀態為低電平;CPOL=1,串行同步時鍾的空閑狀態為高電平。SPI_CR寄存器的CPHA(時鍾相位)位,能配置用於選擇兩種不同的傳輸協議之一進行數據傳輸。CPHA=0,在串行同步時鍾的第一個跳變沿(上升或下降)數據被采樣;CPHA=1,在串行同步時鍾的第二個跳變沿(上升或下降)數據被采樣。

 

1.SPI主模式配置步驟

①使能SPI時鍾,配置PA口

  APB2外設時鍾使能寄存器(RCC_APB2ENR)

  APB1外設復位寄存器 (RCC_APB1RSTR)

  Eg:RCC->APB2ENR|=1<<2; //PORTA時鍾使能 

     RCC->APB2ENR|=1<<12; //SPI1時鍾使能
     //這里只針對SPI口初始化
       GPIOA->CRL&=0X000FFFFF;
     GPIOA->CRL|=0XBBB00000;//PA5.6.7復用
     GPIOA->ODR|=0X7<<5; //PA5.6.7上拉

 

②開全雙工模式並軟件管理NSS

  SPI控制寄存器1(SPI_CR1)(I2S模式下不使用)

 

  Eg:SPI1->CR1|=0<<10;//全雙工模式
     SPI1->CR1|=1<<9; //軟件nss管理
     SPI1->CR1|=1<<8;

 

 

設置SPI為主機並設置數據幀格式

  Eg:SPI1->CR1|=1<<2; //SPI主機
     SPI1->CR1|=0<<11;//8bit數據格式

 

 

④設置時鍾極性和相位極性

 

   Eg:SPI1->CR1|=1<<1; //空閑模式下SCK為1 CPOL=1
      SPI1->CR1|=1<<0; //數據采樣從第二個時間邊沿開始,CPHA=1

 

⑤傳輸速率和LSBFIRST幀格式設置

  Eg:SPI1->CR1|=7<<3; //Fsck=Fcpu/256
     SPI1->CR1|=0<<7; //MSBfirst

 

 

⑥使能SPI

 

  Eg:SPI1->CR1|=1<<6; //SPI設備使能

 

2.SPI

 1 //SPI口初始化
 2 //這里針是對SPI1的初始化
 3 void SPI1_Init(void)
 4 {     
 5     RCC->APB2ENR|=1<<2;       //PORTA時鍾使能      
 6     RCC->APB2ENR|=1<<12;      //SPI1時鍾使能 
 7            
 8     //這里只針對SPI口初始化
 9     GPIOA->CRL&=0X000FFFFF; 
10     GPIOA->CRL|=0XBBB00000;//PA5.6.7復用         
11     GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉
12         
13     SPI1->CR1|=0<<10;//全雙工模式    
14     SPI1->CR1|=1<<9; //軟件nss管理
15     SPI1->CR1|=1<<8;  
16 
17     SPI1->CR1|=1<<2; //SPI主機
18     SPI1->CR1|=0<<11;//8bit數據格式    
19     SPI1->CR1|=1<<1; //空閑模式下SCK為1 CPOL=1
20     SPI1->CR1|=1<<0; //數據采樣從第二個時間邊沿開始,CPHA=1  
21     SPI1->CR1|=7<<3; //Fsck=Fcpu/256
22     SPI1->CR1|=0<<7; //MSBfirst   
23     SPI1->CR1|=1<<6; //SPI設備使能
24     SPI1_ReadWriteByte(0xff);//啟動傳輸(主要作用:維持MOSI為高)         
25 }   
26 //SPI1 速度設置函數
27 //SpeedSet:0~7
28 //SPI速度=fAPB2/2^(SpeedSet+1)
29 //APB2時鍾一般為72Mhz
30 void SPI1_SetSpeed(u8 SpeedSet)
31 {
32     SpeedSet&=0X07;            //限制范圍
33     SPI1->CR1&=0XFFC7; 
34     SPI1->CR1|=SpeedSet<<3;    //設置SPI1速度  
35     SPI1->CR1|=1<<6;         //SPI設備使能 
36 } 
37 //SPI1 讀寫一個字節
38 //TxData:要寫入的字節
39 //返回值:讀取到的字節
40 u8 SPI1_ReadWriteByte(u8 TxData)
41 {        
42     u16 retry=0;                 
43     while((SPI1->SR&1<<1)==0)//等待發送區空    
44     {
45         retry++;
46         if(retry>0XFFFE)return 0;
47     }              
48     SPI1->DR=TxData;           //發送一個byte 
49     retry=0;
50     while((SPI1->SR&1<<0)==0) //等待接收完一個byte  
51     {
52         retry++;
53         if(retry>0XFFFE)return 0;
54     }                                  
55     return SPI1->DR;          //返回收到的數據                    
56 }
spi.c
 1 // SPI總線速度設置  
 2 #define SPI_SPEED_2           0
 3 #define SPI_SPEED_4           1
 4 #define SPI_SPEED_8           2
 5 #define SPI_SPEED_16          3
 6 #define SPI_SPEED_32         4
 7 #define SPI_SPEED_64         5
 8 #define SPI_SPEED_128         6
 9 #define SPI_SPEED_256         7
10                                                                                         
11 void SPI1_Init(void);             //初始化SPI口
12 void SPI1_SetSpeed(u8 SpeedSet); //設置SPI速度   
13 u8 SPI1_ReadWriteByte(u8 TxData);//SPI總線讀寫一個字節
14          
15 #endif
spi.h

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM