zoukankan      html  css  js  c++  java
  • 怎样从Cortex-m向STM32移植使用SPI接口协议

    /*****************************************************************************************************
     * @brief: LDC1000应用程序
     * _____________ _______________
     * |PB4(SSI2CLK) ----> SCLK|
     * |PB5(SSI2FSS) ----> CSB |
     * |PB6(SSI2RX)    <----       SDO |
     *  Tiva M4 |PB7(SSI2TX) ----> SDI | LDC1000
     * |PA4(INT/GPIO) <---- INTB|
     * |PB0(Timer CLK) ---->   TBCLK|
     * _____________| |______________
     *****************************************************************************************************/
    #include <stdint.h>
    #include <stdbool.h>
    #include "driverlib/rom.h"
    #include "driverlib/adc.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/pwm.h"
    #include "driverlib/timer.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/ssi.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_gpio.h"
    #include "LDC1000_cmd.h"
    #include "inc/hw_timer.h"
    #include "inc/hw_types.h"
    #include "inc/hw_ssi.h"


    #ifndef TARGET_IS_BLIZZARD_RA1
    #define TARGET_IS_BLIZZARD_RA1
    #endif


    #ifndef  PART_TM4C123GH6PM
    #define  PART_TM4C123GH6PM
    #endif




    #define SPI_RWBIT 0x80                           //LDC1000,SPI时序读写位,1=读,0=写


    unsigned long ProximityData;                                           //LDC上Proximity Data
    unsigned long FrequencyData;                                           //LDC1000上的Frequency Data
    volatile unsigned char DataRdy ;                                       //LDC1000中断标志


    uint32_t DataRcv[5] ;                                                  //存储SPI读取的数据




    /********************************************************************
     * @brief: SPI写数据
     * @param: unsigned int,SPIdata:待写的数据
     * @return: none
     *********************************************************************/
    void SPIDataSend(unsigned int SPIdata)
    {
         SSIDataPut(SSI2_BASE,SPIdata);   //SPI发送(写)数据
    while(SSIBusy(SSI2_BASE)) ;             //等待SPI发送(写)完毕
    }


    /********************************************************************
     * @brief: LDC1000初始化配置,ps:在SPI中配置了数据位16个数据长度。故
     * 在发送数据时能够将地址和值进行或运算一起发送出去
     * @param: none
     * @return: none
     *********************************************************************/
    void LDC1000_init()
    {


    SPIDataSend(LDC1000_CMD_RPMAX<<8|TEST_RPMAX_INIT); //配置Rp_MAX(0x01)寄存器
    SPIDataSend(LDC1000_CMD_RPMIN<<8|TEST_RPMIN_INIT); //配置Rp_MIN(0x02)寄存器
    SPIDataSend(LDC1000_CMD_SENSORFREQ<<8|0x94); //配置Sensor Frequency(0x03)寄存器
    SPIDataSend(LDC1000_CMD_LDCCONFIG<<8|0x17); //配置LDC Configuration(0x04)寄存器
    SPIDataSend(LDC1000_CMD_CLKCONFIG<<8|0x00); //配置Clock Configuration(0x05)寄存器,
    //使用TBCLK作为时钟源


    SPIDataSend(LDC1000_CMD_INTCONFIG<<8|0x02); //配置INTB Pin Configuration(0x0A),
    //配置INTB为比較输出标志位(status of Comparator output)


    SPIDataSend(LDC1000_CMD_THRESHILSB<<8|0x50); //配置Comparator Threshold High(0x06)寄存器低8位
    SPIDataSend(LDC1000_CMD_THRESHIMSB<<8|0x14); //配置Comparator Threshold High(0x07)寄存器高8位
    SPIDataSend(LDC1000_CMD_THRESLOLSB<<8|0xC0); //配置Comparator Threshold Low(0x08)寄存器低8位
    SPIDataSend(LDC1000_CMD_THRESLOMSB<<8|0x12); //配置Comparator Threshold Low(0x09)寄存器高8位
    SPIDataSend(LDC1000_CMD_PWRCONFIG<<8|0x01); //配置Power Configuration(0x0B)寄存器,
    //为Active Mode,使能转化
    }




    /********************************************************************
     * @brief: 使用SPI读取LDC1000中的数据
     * @param: none
     * @return: none
     *********************************************************************/
    void LDCRead()
    {


    SPIDataSend((LDC1000_CMD_PROXLSB|SPI_RWBIT)<<8);           //写入将要读取的Proximity Data LSB寄存器地址(0x21)
    SSIDataGet(SSI2_BASE,&DataRcv[0]);                       //读取上述寄存器中的值,并存入DataRcv[0]
    ProximityData|= DataRcv[0] ;


    SPIDataSend((LDC1000_CMD_PROXMSB|SPI_RWBIT)<<8); //写入将要读取的Proximity Data MSB寄存器地址(0x22)
    SSIDataGet(SSI2_BASE,&DataRcv[1]); //读取上述寄存器中的值,并存入DataRcv[1]
    ProximityData|= (DataRcv[1]<<8) ; //组合成ProximityData


    SPIDataSend((LDC1000_CMD_FREQCTRLSB|SPI_RWBIT)<<8); //写入将要读取的Frequency Counter Data LSB寄存器地址(0x23)
    SSIDataGet(SSI2_BASE,&DataRcv[2]); //读取上述寄存器中的值。并存入DataRcv[2]
    FrequencyData|= DataRcv[2] ;


    SPIDataSend((LDC1000_CMD_FREQCTRMID|SPI_RWBIT)<<8); //写入将要读取的Frequency Counter Data Mid-Byte寄存器地址(0x24)
    SSIDataGet(SSI2_BASE,&DataRcv[3]); //读取上述寄存器中的值,并存入DataRcv[3]
    FrequencyData|= (DataRcv[3]<<8) ;


    SPIDataSend((LDC1000_CMD_FREQCTRMSB|SPI_RWBIT)<<8); //写入将要读取的Frequency Counter Data MSB寄存器地址(0x25)
    SSIDataGet(SSI2_BASE,&DataRcv[4]); //读取上述寄存器中的值,并存入DataRcv[4]
    FrequencyData|= (DataRcv[4]<<16) ; //组合成FrequencyData


    GPIOIntEnable(GPIO_PORTA_BASE,GPIO_INT_PIN_4); //使能PA4中断
    }


    /********************************************************************
     *  @brief: Timer初始化
     *  @param: none
     *  @return: none
     * _____________ _______________
     * | |
     *  Tiva M4 |PB0(Timer CLK) ---->   TBCLK| LDC1000
     * _____________| |______________
     *********************************************************************/


    void TimerInit()
    {
    TimerDisable(TIMER2_BASE,TIMER_A);
    GPIOPinTypeTimer(GPIO_PORTB_BASE,GPIO_PIN_0);
    GPIOPinConfigure(GPIO_PB0_T2CCP0); //配置PB0为CCP模式
    HWREG(TIMER2_BASE + TIMER_O_CFG) = 0x04; //选择16-bit timer


    //配置TimerA周期计数(Periodic Timer mode)
    HWREG(TIMER2_BASE + TIMER_O_TAMR)|=(TIMER_TAMR_TAAMS|TIMER_TAMR_TAMR_PERIOD) ;


    //载入Timer计数值:40。而且设置Match值:20(Timer默觉得减计数)
    HWREG(TIMER2_BASE + TIMER_O_TAMATCHR) = 20;
    TimerLoadSet(TIMER2_BASE,TIMER_A,40);


    TimerEnable(TIMER2_BASE,TIMER_A); //使能Timer
    }


    /********************************************************************
     * @brief: PA4初始化
     * @param: none
     * @return: none
     * _________ ___________
     * | |
     * | |
     * Tiva M4 | PA4  <--- INTB|  LDC1000
     * | |
     * —————————| |__________
     *********************************************************************/


    void GPIOInit()
    {
    HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= 1<<4 ;
    GPIOIntTypeSet(GPIO_PORTA_BASE,GPIO_PIN_4,GPIO_RISING_EDGE);     //配置为上升沿中断
    GPIOIntEnable(GPIO_PORTA_BASE,GPIO_INT_PIN_4);  //使能PA4中断
    IntEnable(INT_GPIOA);  //使能GPIOA中断
    }


    /********************************************************************
     * @brief: SPI通信初始化
     * @param: none
     * @return: none
     * _____________ _______________
     * |PB4(SSI2CLK) ----> SCLK|
     * |PB5(SSI2FSS) ----> CSB |
     * |PB6(SSI2RX)    <----       SDO |
     *  Tiva M4 |PB7(SSI2TX) ----> SDI | LDC1000
     * |PB0(Timer CLK) ---->   TBCLK|
     * _____________| |______________
     *********************************************************************/


    void SPIInit()
    {
    //配置PB6为SSI2RX,即对Tiva M4而言的SPI数据接收线
    GPIOPinTypeSSI(GPIO_PORTB_BASE,GPIO_PIN_6) ;
    GPIOPinConfigure(GPIO_PB6_SSI2RX);


    //配置PB6为SSI2TX。即对Tiva M4而言的SPI数据发送线
    GPIOPinTypeSSI(GPIO_PORTB_BASE,GPIO_PIN_7) ;
    GPIOPinConfigure(GPIO_PB7_SSI2TX);


    //配置PB4为SSI2CLK线。作为时钟线
    GPIOPinTypeSSI(GPIO_PORTB_BASE,GPIO_PIN_4) ;
    GPIOPinConfigure(GPIO_PB4_SSI2CLK);


    //配置PB5为SSI2FFS线,作为片选线
    GPIOPinTypeSSI(GPIO_PORTB_BASE,GPIO_PIN_5) ;
    GPIOPinConfigure(GPIO_PB5_SSI2FSS);


    SSIDisable(SSI2_BASE);                                           //禁能SSI2


    //配置SSI2为SSI_FRF_MOTO_MODE_0协议格式。SPI主模式。时钟源为5K,16位数据长度
    SSIConfigSetExpClk(SSI2_BASE,SysCtlClockGet(),SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER,5000,16);


    SSIEnable(SSI2_BASE) ; //使能SSI2
    }


    /********************************************************************
     * @brief: PA4中断服务函数,该函数在startup_ccs.c的中断向量表中进行
     * 了注冊
     * @param: none
     * @return: none
     * _________ ___________
     * | |
     * | |
     * Tiva M4 | PA4  <--- INTB|  LDC1000
     * | |
     * —————————| |__________
     *********************************************************************/
    void GPIOAIntHandler()
    {
    GPIOIntClear(GPIO_PORTA_BASE,GPIO_INT_PIN_4) ; //清除PA4中断标志
    DataRdy = 1 ; //LDC1000中断标志置位
    GPIOIntDisable(GPIO_PORTA_BASE,GPIO_INT_PIN_4) ; //禁能PA4中断。将在SPI数据读取完毕后又一次使能PA4中断
    }


    //---------------------------------------main函数----------------------------------------------
    int main(void)
    {

    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | //配置主时钟为50MHz
                          SYSCTL_OSC_MAIN);


    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA) ; //使能GPIOA外设模块
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB) ; //使能GPIOB外设模块
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2); //使能Timer2外设模块
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2); //使能SSI2外设模块
        DataRdy = 0 ; //LDC1000中断标志清零
        TimerInit() ; //TBCLK所在时钟初始化
        GPIOInit() ; //GPIO初始化(PA4)
        SPIInit() ; //SPI初始化
        LDC1000_init(); //LDC1000初始配置
        ROM_IntMasterEnable();                                         //使能总中断
        while(HWREG(SSI2_BASE + SSI_O_SR)& SSI_SR_RNE)                 //首先清除SPI上的接收缓存,排除干扰
        {
        DataRcv[0] = HWREG(SSI2_BASE + SSI_O_DR) ;
        }
          while(1)
        {


          //转化结束后读取ProximityData和FrequencyData
         if(DataRdy)
         {
         DataRdy = 0 ; //LDC1000中断标志清零(在PA4中断服务程序中置位)
         LDCRead() ; //SPI读取数据操作
          }


        }


    }

    如何在stm32中写这个程序????

    大家一起讨论

  • 相关阅读:
    JDBC在getConnection之前为什么要调用Class.forName(转)
    ThreadPoolExecutor的一点理解 专题
    java.lang.NoSuchMethodError
    POJ 3380 最大流
    Spring3.0 AOP 具体解释
    深入浅出 RPC
    JUnit入门
    Linux makefile 教程 很具体,且易懂
    怎样修复“Windows/System32/Config/System中文件丢失或损坏”故障
    MessageDigest简单介绍
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6971575.html
Copyright © 2011-2022 走看看