TI BLE CC2541的SPI主模式


SPI就是用4條線來串行傳輸數據, 2541只能用模擬的方式用GPIO來做.

 

//******************************************************************************
//                      INCLUDES
//******************************************************************************
#include <ioCC2541.h>               
#include "hal_spi_master.h"   
#include "OSAL.h"
#include "hal_mcu.h"

#include <string.h>

#define SPI_CS                          P1_4   
#define SPI_CLK                         P1_5
#define SPI_MOSI                        P1_6
#define SPI_MISO                        P1_7
//4個GPIO引腳

#define SPI_MAX_PACKET_LEN              39
#define SPI_MAX_DATA_LEN                35

const uint8 W25X_ReadData=0x03;

void startSending(void);
void _nop_(void){

}

//下面的delay 1ms在紅外遙控器里面改寫過, 因為需要更精確的delay.
void SPI_DLY_ms(unsigned int ms)
{                         
    unsigned int a;
    while(ms)
    {
        a=1800;
        while(a--);
        ms--;
    }
    return;
}

void SPI_DLY_us(unsigned int us)
{                         
    unsigned int a;
    while(us)
    {
        a=2;
        while(a--);
        us--;
    }
    return;
}

void SPI_Init(void)
{  
    P1SEL &= 0x0F; //將 P1.4 P1.5 P1.6 P1.7 設置為GPIO引腳          00001111
    P1DIR |= 0x70; //設置 P1.4 P1.5, p1.6 引腳為輸出, P1.7 為輸入   01110000
    SPI_SendByte(0xff);
}

void SPI_GetFlashID(void){
    uint16 Temp = 0;
    //startSending();
    SPI_CS=0;
    SPI_SendByte(0x90);
    SPI_SendByte(0x00);
    SPI_SendByte(0x00);
    SPI_SendByte(0x00);
    Temp|=SPI_ReadByte()<<8;  
    Temp|=SPI_ReadByte();
    SPI_CLK=1;
    _nop_();
    SPI_CS=1;
}

void W25Q64_Read(uint8* pBuffer,uint8* readAddr,uint16 NumByteToRead){
    int i;
    SPI_CS=0;
    SPI_SendByte(0x03);
    //SPI_SendByte((uint8)((ReadAddr)>>16));
    //SPI_SendByte((uint8)((ReadAddr)>>8));
    SPI_SendByte(readAddr[0]);
    SPI_SendByte(readAddr[1]);
    SPI_SendByte(readAddr[2]);

    //SPI讀W25Q時, 先發頁地址.


    //SPI_SendByte((uint8)ReadAddr);
    for(i=0;i<NumByteToRead;i++){
        pBuffer[i]=SPI_ReadByte();      //循環讀
    }
 
    SPI_CLK=1;
    _nop_();
    SPI_CS=1;
}

//發送一個字節, 基本上先拉低使能CS腳, 然后不斷的時鍾高低, 在時鍾的后變化沿, 就是所謂clock tailing edge, 讀MISO值.
uint8 SPI_ReadByte(void){
    unsigned char i=0, in=0, temp=0;
    //SPI_CS=0;

    //先拉低, 然后拉高的時候, 讀取MISO
    SPI_CLK = 0;
    for(i=0;i<8;i++){
        in = (in << 1);
        SPI_CLK = 1;
        //SPI_DLY_us(1);
        temp = SPI_MISO;
        if (temp == 1){
            in = in | 0x01;
        }
        SPI_CLK = 0;
        //SPI_DLY_us(1);   
    }
    //SPI_CS=1;
    return in;
}

//發送字節也是一樣, 先拉低時鍾, 然后發送, 然后拉高.
void SPI_SendByte(uint8 cmd){
 
    unsigned char i=8, temp=0;

    //SPI_CS=0;
  
    for(i=0;i<8;i++){
        SPI_CLK=0;
        
        temp = cmd&0x80;
        if (temp == 0)
        {
            SPI_MOSI = 0;
        }
        else
        {
            SPI_MOSI = 1;
        }
        cmd<<=1;;             
        SPI_CLK=1;
        //SPI_DLY_us(1);
    }
    
    SPI_MOSI=1;
}

重點是配合邏輯分析儀使用, 用STM32的板子硬件SPI的波形做參考, 慢慢調就行.


免責聲明!

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



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