硬件准备

ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器

软件准备

Visual DSP++软件

硬件链接


MEMS三轴加速度传感器

我做了一个三轴加速度传感器的子卡,插在这个板子上,然后写了一些有意思的应用程序。

硬件实现原理

MEMS 子卡板连接在 ADSP-EDU-BF53x 开发板的扩展端口 PORT3 和 PORT4 上,板卡插入时,应将扩展子卡板上标注的“圆圈”符号与板卡上的“圆圈”对准插入,避免子卡板反向接入板卡。

MEMS 传感器芯片有两个外部中断管脚,该中断管脚连接在扩展接口的外部中断管脚上,由于 MEMS 传感器默认的中断触发为高电平触发,上电后,中断管脚会将板卡上的中断触发管脚拉到 0,导致板卡中断异常。这时若
不使用扩展板外部中断资源,可执行 CPLD 配置函数ExtIO_Interrupt_Disable (),将外部中断接入关掉。或者通过配置 MEMS 传感器的 DATA_FORMAT 寄存器中的 INT_INVERT 位,将其设置为低电平触发中断。

MEMS 子卡板采用了 ADI 公司的数字加速度传感器 ADXL345。采用 SPI 接口方式接入。通过配置 CPLD 将 SPI的片选切换至外部的子卡板 ExtSPI0 管脚。

DEVICE_OE 寄存器(读/写):
DEVICE_OE 寄存器地址:0x20320000
DEVICE_OE 寄存器设置硬件设备上一些控制管脚的电平状态。

DEVICE_OE 寄存器位功能:

SPI_SEL1~0:SPI 片选选择位
00:SPI_SEL 选通触摸屏模块
01:SPI_SEL 选通 SD 卡模块
10:SPI_SEL 选通外部 SPI0 模块
11:SPI_SEL 选通外部 SPI1 模块

选通 MEMS 子卡板上 SPI 接口,需将 SPI_SEL0 位设置为 0,SPI_SEL1 位设置为 1。

MEMS 芯片坐标判定:

硬件连接示意图

代码实现功能

代码实现了通过 SPI 接口读取 MEMS 芯片 ADXL345 的三轴坐标数据,并将坐标打印出。

测试步骤

1. 将仿真器(ICE)与 ADSP-EDU-BF53x 开发板和计算机连接好,将 MEMS 子卡板插入扩展板接口 PORT3 和PORT4。
2. 先给 ADSP-EDU-BF53x 开发板上电,再为仿真器(ICE)上电。
3. 运行 VisualDSP++ 5.0 软件,选择合适的 BF53x 的 session 将仿真器与软件连接。
4. 加载 VisualDSP++ 5.0 工程文件 BF53x_MEMS.dpj 文件,编译并全速运行。

测试结果

在 VDSP 软件输出窗口连续打印出读到的当前 MEMS 的坐标数据,当将板卡倾斜后,打印的坐标数据会随倾斜改变。

程序源码

adxl345.c

#include <cdefBF533.h>
#include"adxl345.h"

#define DELAY_DATA 500

void SPIinit(void)
{
*pSPI_BAUD = 50;
*pSPI_FLG |=FLS2;
*pSPI_CTL = 0x1001|CPHA| CPOL|EMISO ;
*pSPI_CTL = (*pSPI_CTL | SPE);
}

unsigned char spi_byte_rw(unsigned char value)
{
unsigned char incoming=0;
while(!(*pSPI_STAT & SPIF));
*pSPI_TDBR = value;
while(*pSPI_STAT & RXS)
incoming = *pSPI_RDBR;
return(incoming);
}
adxl345_write(unsigned char data,unsigned char address)
{
*pSPI_FLG &= ~FLG2;
delay(DELAY_DATA);
spi_byte_rw(address|0x40);
spi_byte_rw(data);
delay(DELAY_DATA);
*pSPI_FLG |= FLG2;
delay(DELAY_DATA);
}
unsigned char adxl345_read(unsigned char address)
{
unsigned char read_data;
*pSPI_FLG &= ~FLG2;
delay(DELAY_DATA);
spi_byte_rw(address|0xc0);
delay(DELAY_DATA);
read_data = spi_byte_rw(0xff);
delay(DELAY_DATA);
read_data = spi_byte_rw(0xff);
delay(DELAY_DATA);
*pSPI_FLG |= FLG2;
delay(DELAY_DATA);
return read_data;
}

unsigned char adxl345_read_id(void)
{
unsigned char id = 0;
id = adxl345_read(DEVID);
return id;
}

void adxl345_init(void) //ADXL345初始化设置
{
adxl345_write(0xfe,OFSX); //X\Y\Z轴校正偏移
adxl345_write(0xff,OFSY);
adxl345_write(0x05,OFSZ);
adxl345_write(0x77,ACT_INACT_CTL); //X\Y\Z轴使能
adxl345_write(0x01,BW_RATE); //功率选择及输出数据速率
adxl345_write(0x38,POWER_CTL); //测量、待机及测量模式控制
adxl345_write(0x0b,DATA_FORMAT); //数据及通信形式控制
adxl345_write(0x03,THRESH_ACT);
adxl345_write(0x03,THRESH_INACT);
adxl345_write(0x0f,TIME_INACT); //加速度时间阈值
adxl345_write(0x77,ACT_INACT_CTL); //使能控制
adxl345_write(0xa0,THRESH_FF); //自由落体加速度阈值
adxl345_write(0xff,TIME_FF); //自由落体时间阈值
adxl345_write(0x00,TAP_AXES);
adxl345_write(0x77,ACT_TAP_STATUS);
adxl345_write(0x0a,BW_RATE);
adxl345_write(0x38,POWER_CTL);
}

unsigned short adxl345_read_xyzdat(short *buffer)
{
short tem_x = 0,tem_y = 0,tem_z = 0;
int i;
signed short dlXDiff0,dlXDiff1,dlXDiff2;
signed short dlYDiff0,dlYDiff1,dlYDiff2;
signed short dlZDiff0,dlZDiff1,dlZDiff2;
short ptx[9];
short pty[9];
short ptz[9];
short pax[3];
short pay[3];
short paz[3];
for(i=0;i<9;i++)
{
ptx[i] =adxl345_read(DATAX1)<<8|adxl345_read(DATAX0);
pty[i] =adxl345_read(DATAY1)<<8|adxl345_read(DATAY0);
ptz[i] =adxl345_read(DATAZ1)<<8|adxl345_read(DATAZ0);
}
///
pax[0]=(ptx[0]+ptx[1]+ptx[2])/3;
pax[1]=(ptx[3]+ptx[4]+ptx[5])/3;
pax[2]=(ptx[6]+ptx[7]+ptx[8])/3;

dlXDiff0 = pax[ 0 ] - pax[ 1 ];
dlXDiff1 = pax[ 1 ] - pax[ 2 ];
dlXDiff2 = pax[ 2 ] - pax[ 0 ];dlXDiff0 = dlXDiff0 > 0 ? dlXDiff0 : -dlXDiff0;
dlXDiff1 = dlXDiff1 > 0 ? dlXDiff1 : -dlXDiff1;
dlXDiff2 = dlXDiff2 > 0 ? dlXDiff2 : -dlXDiff2;if ( dlXDiff0 < dlXDiff1 )
{if ( dlXDiff2 < dlXDiff0 ){tem_x = ( ( pax[ 0 ] + pax[ 2 ] ) >> 1 ) ;}else{tem_x = ( ( pax[ 0 ] + pax[ 1 ] ) >> 1 );}
}
else if ( dlXDiff2 < dlXDiff1 )
{tem_x = ( ( pax[ 0 ] + pax[ 2 ] ) >> 1 ) ;
}
else
{tem_x= ( ( pax[ 1 ] + pax[ 2 ] ) >> 1 ) ;
}

///
pay[0]=(pty[0]+pty[1]+pty[2])/3;
pay[1]=(pty[3]+pty[4]+pty[5])/3;
pay[2]=(pty[6]+pty[7]+pty[8])/3;

dlYDiff0 = pay[ 0 ] - pay[ 1 ];
dlYDiff1 = pay[ 1 ] - pay[ 2 ];
dlYDiff2 = pay[ 2 ] - pay[ 0 ];dlYDiff0 = dlYDiff0 > 0 ? dlYDiff0 : -dlYDiff0;
dlYDiff1 = dlYDiff1 > 0 ? dlYDiff1 : -dlYDiff1;
dlYDiff2 = dlYDiff2 > 0 ? dlYDiff2 : -dlYDiff2;if ( dlYDiff0 < dlYDiff1 )
{if ( dlYDiff2 < dlYDiff0 ){tem_y = ( ( pay[ 0 ] + pay[ 2 ] ) >> 1 ) ;}else{tem_y = ( ( pay[ 0 ] + pay[ 1 ] ) >> 1 );}
}
else if ( dlYDiff2 < dlYDiff1 )
{tem_y = ( ( pay[ 0 ] + pay[ 2 ] ) >> 1 ) ;
}
else
{tem_y= ( ( pay[ 1 ] + pay[ 2 ] ) >> 1 ) ;}

//
paz[0]=(ptz[0]+ptz[1]+ptz[2])/3;
paz[1]=(ptz[3]+ptz[4]+ptz[5])/3;
paz[2]=(ptz[6]+ptz[7]+ptz[8])/3;

dlZDiff0 = paz[ 0 ] - paz[ 1 ];
dlZDiff1 = paz[ 1 ] - paz[ 2 ];
dlZDiff2 = paz[ 2 ] - paz[ 0 ];dlZDiff0 = dlZDiff0 > 0 ? dlZDiff0 : -dlZDiff0;
dlZDiff1 = dlZDiff1 > 0 ? dlZDiff1 : -dlZDiff1;
dlZDiff2 = dlZDiff2 > 0 ? dlZDiff2 : -dlZDiff2;if ( dlZDiff0 < dlZDiff1 )
{if ( dlZDiff2 < dlZDiff0 ){tem_z = ( ( paz[ 0 ] + paz[ 2 ] ) >> 1 ) ;}else{tem_z = ( ( paz[ 0 ] + paz[ 1 ] ) >> 1 );}
}
else if ( dlZDiff2 < dlZDiff1 )
{tem_z = ( ( paz[ 0 ] + paz[ 2 ] ) >> 1 ) ;
}
else
{tem_z= ( ( paz[ 1 ] + paz[ 2 ] ) >> 1 ) ;}
*buffer++ = tem_x;
*buffer++ = tem_y;
*buffer = tem_z;

}

cpu.c

#include <cdefBF533.h>
#include <sys/exception.h>
#include “ccblkfn.h”
#include “sysreg.h”

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

  • 名称 : Init_PLL
  • 功能 : 配置处理器的内核与系统时钟
  • 入口参数 :无
  • 返回值 :无
    ****************************************************************************/
    void Set_PLL(int pmsel,int pssel)
    {
    int new_PLL_CTL;
    *pPLL_DIV = pssel;
    asm(“ssync;”);
    new_PLL_CTL = (pmsel & 0x3f) << 9;
    *pSIC_IWR |= 0xffffffff;
    if (new_PLL_CTL != *pPLL_CTL)
    {
    *pPLL_CTL = new_PLL_CTL;
    asm(“ssync;”);
    asm(“idle;”);
    }
    }

void Init_Flags(void)
{
*pFIO_INEN = 0x0001;
*pFIO_DIR = 0x0000;
*pFIO_EDGE = 0x0001;
*pFIO_POLAR = 0x0001;
*pFIO_MASKA_D = 0x0001;
}

void Init_SDRAM(void)
{
*pEBIU_SDRRC = 0x00000817;
*pEBIU_SDBCTL = 0x00000013;
*pEBIU_SDGCTL = 0x0091998d;
ssync();
}

void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0xffc07bb0;
*pEBIU_AMGCTL = 0x000f;
}

void delay(volatile int tem)
{
volatile int i;
while(tem–)
for(i=6; i>0; i–);
}

main.c

#include <stdio.h>
#include <cdefBF533.h>

void main(void)
{
unsigned char adxl345_id;
unsigned char buf[3];
short buf_data[3];
float XDat,YDat,ZDat;
Set_PLL(16,4);
Init_EBIU();

ExtSPI0_Enable();SPIinit();
adxl345_init();
adxl345_id = adxl345_read_id();
printf("adxl345 id is :%x\r\n",adxl345_id);
while(1)
{       adxl345_read_xyzdat(buf_data);if(buf_data[0]&0xe000)  //判断正负{buf_data[0] = ~buf_data[0]+1;buf[0] = '-';XDat = (float)buf_data[0]*0.0039;} else{buf_data[0] = buf_data[0];XDat =(float) buf_data[0]*0.0039;buf[0] = '+'; }if(buf_data[1]&0xe000)  //判断正负{buf_data[1] = ~buf_data[1]+1;buf[1] = '-';YDat = (float)buf_data[1]*0.0039;}  else{buf_data[1] = buf_data[1];YDat =(float) buf_data[1]*0.0039;buf[1] = '+'; }if(buf_data[2]&0xe000)  //判断正负{buf_data[2] = ~buf_data[2]+1;buf[2] = '-';ZDat =(float) buf_data[2]*0.0039;}  else{buf_data[2] = buf_data[2];buf[2] = '+';ZDat =(float) buf_data[2]*0.0039;}printf("mems x y z is %c%1.1fg,%c%1.1fg,%c%1.1fg\r\n",buf[0],XDat,buf[1],YDat,buf[2],ZDat);
}

}

ADI Blackfin DSP处理器-BF533的开发详解58:DSP控制ADXL345三轴加速度传感器的应用(含源码)相关推荐

  1. ADI Blackfin DSP处理器-BF533的开发详解60:DSP控制ADXL345三轴加速度传感器-电子水平仪(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 MEMS三轴加速度传感器 我做了一个三轴加速度 ...

  2. ADI Blackfin DSP处理器-BF533的开发详解61:DSP控制ADXL345三轴加速度传感器-LCD(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 MEMS三轴加速度传感器 我做了一个三轴加速度 ...

  3. ADI Blackfin DSP处理器-BF533的开发详解21:RTC实时时钟的原理及应用(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 硬件设计原理图 功能介绍 ADSP-BF53x ...

  4. ADI Blackfin DSP处理器-BF533的开发详解18:用触摸屏的例程来理解中断(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 硬件设计原理图 硬件实现原理 ADSP-EDU ...

  5. ADI Blackfin DSP处理器-BF533的开发详解49:图像处理专题-Bright (图像亮暗处理)(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 功能介绍 代码实现了图像亮暗处理,代码运行时, ...

  6. ADI Blackfin DSP处理器-BF533的开发详解11:PPI视频接口的驱动和应用(含源代码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 接口功能介绍 PPI(Parallel Per ...

  7. ADI Blackfin DSP处理器-BF533的开发详解1:软件和硬件的准备

    BF533是ADI Blackfin系列DSP处理器里的最经典型号,这个DSP我用了20年,单就这一颗DSP来讲,我相信国内应该没有比我更资深的了,下面就来说一说这颗DSP. 这颗IC是Blackfi ...

  8. ADI Blackfin DSP处理器-BF533的开发详解59:DSP控制ADXL345三轴加速度传感器的应用2(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 MEMS三轴加速度传感器 我做了一个三轴加速度 ...

  9. ADI Blackfin DSP处理器-BF533的开发详解62:DSP控制ADXL345三轴加速度传感器-贪食蛇游戏(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 MEMS三轴加速度传感器 我做了一个三轴加速度 ...

最新文章

  1. python使用imbalanced-learn的SMOTEENN方法同时进行上采样和下采样处理数据不平衡问题
  2. linux bash输入输出重定向
  3. java linux urlencode_java字符编码转换研究(转)
  4. LYNC 和 Exchange 整合手记之R2 如何下如何安装补丁
  5. Service Broker实现发布-订阅(Publish-Subscribe)框架(3)
  6. 无限复活服务器,绝地求生无限复活模式怎么玩 无限复活新手教程
  7. JS与APP原生控件交互
  8. 多媒体分析与理解_如何设计一个出色的数字多媒体展厅?
  9. 浅谈java对象的equals方法
  10. MySQL 半同步复制+MMM架构
  11. C语言与汇编“硬在哪里”——什么是面向硬件?
  12. 3.TCP/IP 详解卷1 --- IP:网际协议
  13. web如何加入视频?video
  14. 写在19年初的后端社招面试经历(两年经验): 蚂蚁 头条 PingCAP
  15. 多台计算机虚拟化方案,虚拟化建设解决方案
  16. 系统架构设计师教程学习笔记
  17. 你不得不了解的人工智能基础知识
  18. 常用的一句话反弹shell总结
  19. 缓解环境噪声对音频质量干扰
  20. 慢啃《编程珠玑》【持续更新ing……】

热门文章

  1. (转)IST:Iterative Shrinkage/Thresholding和Iterative Soft Thresholding
  2. hibernate 二级缓存 @cache注解
  3. 北大软微学院计算机金融方向考研,北大软微金服方向2016年考研经验贴---初试410分...
  4. strcpy()、strncpy()、strlcpy()、strncpy_s()函数
  5. 设计模式中的工厂类图
  6. 嵌入式RTOS的 任务栈 和 系统栈
  7. 设计模式 模版方法模式 展现程序员的一天
  8. Kafka Streams开发单词计数应用
  9. 未加载coreavcdecoder.ax所用的符号
  10. idc机房建设费用_成立一个IDC机房要多少钱