怎样从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接口协议的更多相关文章
- 【转】hurry_liu 大神STM32移植contiki入门之一:系统介绍和开发环境搭建
前言: 由于项目的原因,需要在LPC1788(STM32 cortex-M3)上面跑contiki. 之前没有涉及到contiki,不知其为何物.不过这个不是难事,做IT的,每每遇到新事物,都不会处理 ...
- STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085和串口只发送数据不能接收数据问题
STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085的问题讨论:http://www.rt-thr ...
- Hello China操作系统STM32移植指南(一)
Hello China操作系统移植指南 首先说明一下,为了适应更多的文化背景,对Hello China操作系统的名字做了修改,修改为"Hello X",或者连接在一起,写为&quo ...
- STM32移植USB驱动总结
https://blog.csdn.net/stm32_newlearner/article/details/88095944 stm32 移植usb驱动开发 单片机 STM32单片机和51单片机 ...
- U8g2图形库与STM32移植(I2C,软件与硬件)
U8g2图形库 简介 U8g2 是一个用于嵌入式设备的简易图形库,可以在多种 OLED 和 LCD 屏幕上,支持包括 SSD1306 等多种类型的底层驱动,并可以很方便地移植到 Arduino .树莓 ...
- STM32 移植 RT-Thread 标准版的 FinSH 组件
一.移植准备 开发版STM32F10xC8T6 准备好移植RT-Thread的移植工程 没动手移植过RT-Thread的小伙伴,可以看RT-Thread移植到stm32 我这里是将控制台信息打印到串口 ...
- STM32学习笔记——SPI串行通讯(向原子哥学习)
一.SPI 简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在 EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...
- 【安富莱专题教程第1期】基于STM32的硬件RGB888接口实现emWin的快速刷新方案,32位色或24
说明:1. 首先感谢ST终于推出了ARGB格式的emWin库,可谓千呼万唤始出来,使用STM32的硬件RGB888接口刷新图片慢的问题终于得到解决.2. 这个问题由来已久,是之前为我们的STM32-V ...
- STM32移植UCGUI3.90笔记
在MDK环境下,终于将3.90版本的UCGUI移植到STM32下了,在网上看到的都是例程代码,很少看到有关于在STM32下移植UCGUI的教程方法,为了方便大家,特写此移植方法,大家可以借鉴(有错误之 ...
随机推荐
- Java web application——Listener
应用程序事件提供ServletContext和HttpSession以及ServletRequest对象状态更改的通知,用户编写响应状态更改的事件监听器类,并配置和部署他们.Servlet容器会调用事 ...
- 洛谷P1280 && caioj 1085 动态规划入门(非常规DP9:尼克的任务)
这道题我一直按照往常的思路想 f[i]为前i个任务的最大空暇时间 然后想不出来怎么做-- 后来看了题解 发现这里设的状态是时间,不是任务 自己思维还是太局限了,题做得太少. 很多网上题解都反着做,那么 ...
- Python学习笔记(2)--基本数据类型
在介绍基本数据类型之前,先说一个系统方法type():返回对象的数据类型,可以帮助我们查看系统的类型定义 python不同的版本,类型名称稍有不同,这里使用的是3.5.2版本 一.基本数据类型: 1. ...
- iOS日期转换之UTC/GMT时间格式
GMT只需要将代码中的UTC替换为GMT即可 //将本地日期字符串转为UTC日期字符串 //本地日期格式:2013-08-03 12:53:51 //可自行指定输入输出格式 -(NSString *) ...
- PKU 2528 Mayor's posters
题意: 一个公告板上面贴海报,宽度都是一样的,长度可能不一样.后面的海报可能把前面的覆盖掉.问最后能看见多少张不同的海报. 思路: 这题原来做过,是用线段树的区间染色写的.记录每个区间是纯色还是杂色. ...
- 【转】 基于C#.NET的高端智能化网络爬虫 2
[转] 基于C#.NET的高端智能化网络爬虫2 本篇故事的起因是携程旅游网的一位技术经理,豪言壮举的扬言要通过他的超高智商,完美碾压爬虫开发人员,作为一个业余的爬虫开发爱好者,这样的言论我当然不能置之 ...
- 八款常用的 Python GUI 开发框架推荐
作为Python开发者,你迟早都会用到图形用户界面来开发应用.本文将推荐一些 Python GUI 框架,希望对你有所帮助,如果你有其他更好的选择,欢迎在评论区留言. Python 的 UI 开发工具 ...
- android中文网站
Google Developers中国网站发布 用户评价: / 55 差好 最后更新于 2016年12月09日 点击数:15209 我们很高兴地宣布,Google Developers 中国网 ...
- (转载)http协议的Request Payload 和 Form Data 的区别
我正在开发的项目前端和后端是完全独立的,通过配置 webpack 的 proxy 将前端请求跨域代理到后台服务.昨天发现,我前端执行 post 请求,后台 springmvc 的 @RequestMa ...
- codeforces 140E.New Year Garland
传送门: 解题思路: 要求相邻两行小球颜色集合不同,并且限制行内小球相邻不同. 由此可得:每行小球排列都是独立与外界的, 所以答案应该是对于所有行的颜色集合分类,在将行内的答案乘到上面. 先考虑如何分 ...