怎样从Cortex-m向STM32移植使用SPI接口协议

时间:2022-10-29 11:09:48

/*****************************************************************************************************

 * @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中写这个程序????

大家一起讨论

怎样从Cortex-m向STM32移植使用SPI接口协议的更多相关文章

  1. 【转】hurry&lowbar;liu 大神STM32移植contiki入门之一:系统介绍和开发环境搭建

    前言: 由于项目的原因,需要在LPC1788(STM32 cortex-M3)上面跑contiki. 之前没有涉及到contiki,不知其为何物.不过这个不是难事,做IT的,每每遇到新事物,都不会处理 ...

  2. STM32移植RT-Thread后的串口在调试助手上出现:&lpar;mq &excl;&equals; RT&lowbar;NULL&rpar; assert failed at rt&lowbar;mq&lowbar;recv&colon;2085和串口只发送数据不能接收数据问题

    STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085的问题讨论:http://www.rt-thr ...

  3. Hello China操作系统STM32移植指南(一)

    Hello China操作系统移植指南 首先说明一下,为了适应更多的文化背景,对Hello China操作系统的名字做了修改,修改为"Hello X",或者连接在一起,写为&quo ...

  4. STM32移植USB驱动总结

    https://blog.csdn.net/stm32_newlearner/article/details/88095944 stm32   移植usb驱动开发 单片机 STM32单片机和51单片机 ...

  5. STM32学习笔记——SPI串行通讯(向原子哥学习)

    一.SPI  简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在  EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...

  6. 【安富莱专题教程第1期】基于STM32的硬件RGB888接口实现emWin的快速刷新方案,32位色或24

    说明:1. 首先感谢ST终于推出了ARGB格式的emWin库,可谓千呼万唤始出来,使用STM32的硬件RGB888接口刷新图片慢的问题终于得到解决.2. 这个问题由来已久,是之前为我们的STM32-V ...

  7. STM32移植UCGUI3&period;90笔记

    在MDK环境下,终于将3.90版本的UCGUI移植到STM32下了,在网上看到的都是例程代码,很少看到有关于在STM32下移植UCGUI的教程方法,为了方便大家,特写此移植方法,大家可以借鉴(有错误之 ...

  8. Hello China操作系统STM32移植指南(三)

    移植到STM32的源代码,可从下列链接下载: http://download.csdn.net/detail/hellochina15/7049909 包含两个包:一个是移植前的Hello China ...

  9. Hello China操作系统STM32移植指南(二)

    移植步骤详解 下面就以MDK 4.72为开发环境,详细说明Hello China内核向STM32的移植过程.MDK 4.72评估版只支持32K代码的编译,这对Hello China的内核来说,裁剪掉一 ...

随机推荐

  1. jquery 插件开发

    一.$.extend()  这种方式用来定义一些辅助方法是比较方便的 $.extend({ sayHello:function(name){ console.log('Hello:'+name); } ...

  2. javascript高级编程运用

    一//各种尺寸 (size) s += “\r\n网页可见区域宽:“+ document.body.clientWidth; s += “\r\n网页可见区域高:“+ document.body.cl ...

  3. paramiko SSH 模块简单应用。

    目的:需要ssh链接到Linux主机,执行telnet 命令,抓回显匹配制定内容. ssh --->执行telnet到本地端口--->执行类似 ls 的命令.匹配命令执行后的特定回显字段. ...

  4. c&plus;&plus;针对数据库,文件的操作总结&lpar;原始&rpar;

    1.将文件保存到sqlserver数据库的相关操作: Update t1 .txt’, SINGLE_BLOB ) Select convert( varchar(), data ) 注:fileTy ...

  5. 使用 nodeJs 开发微信公众号(上传图片)

    在给用户发送消息中涉及到的素材(图片.视频.音频.文章等)需要事先传到微信服务器,然后获得媒体id(media_id),然后把 media_id 传递给用户 上传分上传临时素材(只保存三天)和上传永久 ...

  6. BOS物流项目第十一天(补充)

    上节课我们在添加权限时,把选择父功能点做成这种效果,不太好,我们进行升级优化. 1.我们对jsp页面进行修改,主要是改了样式. 2.重新编写我们dao层的代码 3.在我们查看父项的时候自动查找子项,我 ...

  7. 使用tensorflow的lstm网络进行时间序列预测

    https://blog.csdn.net/flying_sfeng/article/details/78852816 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog. ...

  8. 20145302张薇 《网络对抗技术》 web基础

    20145302张薇 <网络对抗> web基础 实验问题回答 1.什么是表单 表单在网页中主要负责数据采集功能:一般网页上需要用户输入.选择的地方都会用到表单 表单标签:即,用于确定表单所 ...

  9. java保留小数点两位的4种方法

    import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; public c ...

  10. MySQL实现排名并查询指定用户排名功能,并列排名功能

    MySQL实现排名并查询指定用户排名功能,并列排名功能 表结构: CREATE TABLE test.testsort ( id int(11) NOT NULL AUTO_INCREMENT, ui ...