• 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的波形做参考, 慢慢调就行.

  • 相关阅读:
    ksoap2 android 调用WebService
    Android App自动更新解决方案(DownloadManager)
    Android 网络加载通用Loading
    工具类ToastUtil 避免在子线程中使用抛异常 "Can't create handler inside thread that has not called Looper.prepare()"
    Material 风格的搜索框MaterialSearchView的使用
    Android集成极光推送
    第三十天
    第二十九天
    第二十八天
    第二十七天
  • 原文地址:https://www.cnblogs.com/Montauk/p/5801949.html
Copyright © 2020-2023  润新知