如何从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中写这个程序????

大家一起讨论

如何从Cortex-m向STM32移植使用SPI接口协议

时间: 2024-10-08 00:51:51

如何从Cortex-m向STM32移植使用SPI接口协议的相关文章

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

/***************************************************************************************************** * @brief: LDC1000应用程序 * _____________ _______________ * |PB4(SSI2CLK) ----> SCLK| * |PB5(SSI2FSS) ----> CSB | * |PB6(SSI2RX)    <----       SDO

STM32移植uC/OS-II记录

#STM32移植uC/OS-II 标签(空格分隔): ARM uC/OS-II --- ##移植前相关知识介绍 ###目标板与uC/OS-II的系统框架图 ![](http://images.cnitblog.com/blog/665192/201408/301617582511830.jpg) ###搭建文件结构 ![](http://images.cnitblog.com/blog/665192/201408/301619070633006.png) ###配置uC/OS-II - 修改os

FreeRTOS STM32移植笔记

FreeRTOS STM32移植笔记

STM32——SPI接口

STM32--SPI接口 宗旨:技术的学习是有限的,分享的精神的无限的. 一.SPI协议[SerialPeripheral Interface] 串行外围设备接口,是一种高速全双工的通信总线.在ADC/LCD等与MCU间通信. 1.SPI信号线 SPI 包含 4 条总线,SPI 总线包含 4 条总线,分别为SS .SCK.MOSI.MISO. (1)SS(SlaveSelect):片选信号线,当有多个 SPI 设备与 MCU 相连时,每个设备的这个片选信号线是与 MCU 单独的引脚相连的,而其他

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

一.SPI  简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在  EEPROM, FLASH,实时时钟,AD 转换器,还有数字信号处理器和数字信号解码器之间.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,STM32 有 SPI 接口.下面是 SPI 的内部简明图:

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

说明:1. 首先感谢ST终于推出了ARGB格式的emWin库,可谓千呼万唤始出来,使用STM32的硬件RGB888接口刷新图片慢的问题终于得到解决.2. 这个问题由来已久,是之前为我们的STM32-V6板子制作emWin模板时发现的.V6板子的硬件配置是STM32F429BIT6 + 32位带宽的SDRAM + 硬件RGB888接口.实际测试中发现,将F429配置为16位色的RGB565,刷新800*480分辨率的图片可以做到15ms左右一帧,而测试24位色的RGB888或者32位色的ARGB8

2.3 stm32移植lwip常见问题和解决方式

1.PHY初始化 一般来说,stm32外部驱动PHY芯片有两种连接方式,MII和RMII总线,这个与硬件设计有关,不过stm32芯片一般都支持这两种总线连接方式,因为RMII总线在传输效果不变的情况下占用接口更少,因此一般推荐RMII方式. 以DP83848芯片为例: 从上面可以看出RMII总线对应的输入时钟要设置为50MHZ, 当然这与你原理图的布线有,连接PHY芯片X1接口对应GPIO接口的外设区域时钟就要设定为该值,考虑到挂在同区域外设的时钟要求,为了方便设计,对于stm32f207vet

STM32移植uCGUI+触摸屏显示,没有加入uCOS Ⅱ

实验板子 ——李想STM32开发板 开发工具—— keil uVision5.0 for MDK 本次终极任务为显示示波器的GUI界面,此文章只是简单总结移植uCGUI+触摸屏,之后会加入视窗管理器及uCOSⅡ. 下面说说移植步骤,会穿插一些个人简单的理解,为像我一样的新手提供方便. 步骤分为三大步: 一.移植uCGUI 二.显示汉字 三.移植触摸屏 一.移植uCGUI 1.建立工程模版. 个人会先建立一个工程模板,里边只包含系统的一些文件,主函数是while(1);的循环.每次项目用到就直接复

为 STM32 移植 Berry 脚本语言

Berry 是我为单片机设计的一款脚本语言,该语言具有资源占用小.平台无关.执行速度快和易于掌握等优点.在单片机上使用脚本语言可以提高单片机的二次开发能力以及调试效率,同时也是一种比较新颖的玩法.本教程将简要介绍在 STM32F103RBT6 单片机上移植 Berry 脚本语言的方法.教程的末尾给出了移植完成的示例工程,读者可以根据本教程的内容和示例工程完成自己的移植工作. 我使用 ST 推出的 CubeMX 软件进行单片机固件库的配置,选择用 CubeMX 生成 HAL 库工程而不用标准库是考