ADS8345驱动程序设计文档
- 格式:doc
- 大小:1.15 MB
- 文档页数:33
嵌入式ADS实验指导书实验一嵌入式微处理器系统的开发环境一、实验环境PC机一台软件: ADS 1.2集成开发环境一套二、实验目的1.了解嵌入式系统及其特点;2.熟悉嵌入式系统的开发环境和基本配置并能编写简单的汇编程序三、实验内容1.嵌入式系统的开发环境、基本配置2.使用汇编指令完成简单的加法实验四、实验步骤(1)在D:\新建一个目录,目录名为experiment。
(2)点击 WINDOWS 操作系统的“开始|程序|ARM Developer Suite v1.2 |Code Warrior forARM Developer Suite”启动Metrowerks Code Warrior,或双击“ADS 1.2”快捷方式启动。
启动ADS 1.2 如图1-1所示:图1-1启动ADS1.2(3) 在CodeWarrior 中新建一个工程的方法有两种,能够在工具栏中单击“New”按钮,也能够在“File”菜单中选择“New…”菜单。
这样就会打开一个如图1-2 所示的对话框。
选择【File】->【New…】,使用ARM Executable Image工程模板建立一个工程,名称为ADS,目录为D:\experiment。
图1-2 新建文件在这个对话框中为用户提供了7 种可选择的工程类型:1)ARM Executabl Image:用于由ARM 指令的代码生成一个ELF 格式的可执行映像文件;2)ARM Object Library:用于由ARM 指令的代码生成一个armar 格式的目标文件库;3)Empty Project:用于创立一个不包含任何库或源文件的工程;4)Makefile Importer Wizard:用于将Visual C 的nmake 或GNUmake 文件转入到CodeWarrior IDE 工程文件;5)Thumb ARM Executable Image:用于由ARM 指令和Thumb 指令的混和代码生成一个可执行的ELF 格式的映像文件;6)Thumb Executable image:用于由Thumb 指令创立一个可执行的ELF 格式的映像文件;7)Thumb Object Library:用于由Thumb 指令的代码生成一个armar 格式的目标文件库。
基于ADS8341与ARM的数据采集模块接口设计作者:韩卫洁陈江锋董兴田军来源:《现代电子技术》2014年第24期摘 ;要:为了对冻土区土壤环境进行实时采集处理和检测,在此选取ADS8341作为A/D 转换芯片,STM32F103ZET6芯片作为微处理器,设计并实现了将ADS8341芯片和STM32F103ZET6芯片相结合用于采集土壤环境数据的硬件电路和A/D采集软件控制过程。
经过实际的检测与分析,该设计可以对冻土区土壤进行实时高效的采集、处理以及对数据的保存,以便后期数据的查询和土壤环境总体趋势的预测。
关键词: ADS8341; STM32F103ZET6; 接口电路; 采集控制中图分类号: TN964⁃34 ; ; ; ; ; ; ; ; ; 文献标识码: A ; ; ; ; ; ; ; ; ; ; ; ; ; ;文章编号:1004⁃373X(2014)24⁃0084⁃03Interface design of high⁃speed data acquisition module based on ADS8341 and ARMHAN Wei⁃jie1, CHEN Jiang⁃feng2, DONG Xing1, TIAN Jun1(1. School of Construction Machinery,Chang’an University,Xi’an 710064, China;2. School of Materials Science and Engineering ,Chang’an University,Xi’an 710064,China)Abstract: ;In order to conduct ;real⁃time acquisition, processing and detection of the frozen soil environment data, ADS8341 is chosen as A/D conversion chip and STM32F103ZET6 chip as MPU. The data acquisition circuit and A/D acquisition software control process based on ADS8341 and STM32F103ZET6 was designed. The actual tested and analyzed results show that the interface circuit can achieve real⁃time effective acquisition, processing and storage of the frozen soil environment data, which contribute to the future query of the relevant data and prediction of the trend of soil environment.Keywords: ADS8341; STM32F103ZET6; interface circuit ; acquisition control为实现某冻土区石油管道监测系统对管道周围土壤温度的实时监测和控制,在同一时间需要多路采集和处理温度信号,由于系统对温度信号的实时性和采集准确度有严格的要求,采用ADS8341作为专用的A/D转换芯片而不是使用ARM芯片自带的12位A/D转换芯片,微处理器选用STM32F103ZET6芯片,该芯片是由ST公司生产的STM32F103“增强型”系列处理器芯片。
《基于ADS的射频功率放大器设计与仿真》篇一一、引言随着无线通信技术的不断发展,射频功率放大器(RF Power Amplifier, RFPA)作为无线通信系统中的关键组件,其性能的优劣直接影响到整个系统的性能。
因此,设计一款高性能的射频功率放大器显得尤为重要。
本文将介绍基于ADS(Advanced Design System)软件的射频功率放大器设计与仿真过程,以期为相关领域的研究与应用提供参考。
二、设计目标与要求在设计射频功率放大器时,我们需要明确设计目标与要求。
主要包括以下几个方面:1. 工作频率范围:根据应用需求,确定射频功率放大器的工作频率范围。
2. 输出功率:根据系统需求,设定射频功率放大器的输出功率。
3. 效率:在保证输出功率的同时,尽量提高射频功率放大器的效率。
4. 线性度:确保在各种工作条件下,射频功率放大器的输出信号保持较好的线性度。
三、设计原理与方案根据设计目标与要求,我们采用合适的拓扑结构与器件,制定出具体的射频功率放大器设计方案。
设计方案主要包括以下几个方面:1. 拓扑结构选择:根据应用需求,选择合适的功率放大器拓扑结构,如AB类、BC类等。
2. 器件选择:选择具有较低噪声系数、高功率附加效率(PAE)和良好线性度的器件。
3. 电路设计:根据拓扑结构和器件特性,设计出合理的电路结构,包括输入匹配电路、输出匹配电路、偏置电路等。
四、ADS仿真与优化在确定了设计方案后,我们使用ADS软件进行仿真与优化。
ADS是一款功能强大的电子设计自动化软件,可以用于射频电路的设计、仿真与优化。
在ADS中,我们可以建立射频功率放大器的仿真模型,通过调整电路参数,优化性能指标。
仿真与优化的主要步骤包括:1. 建立仿真模型:根据设计方案,在ADS中建立射频功率放大器的仿真模型。
2. 参数设置:设置仿真参数,如工作频率范围、输出功率等。
3. 仿真分析:对仿真模型进行仿真分析,得到射频功率放大器的性能指标。
AD9854想必大家都在为AD9854没有电路图,没有资料而头疼吧。
我这里有一份AD9854ASQ的资料,里面有可以用的程序原理图PCB 码原希望对大家有帮助。
现在把我的设计法出来供大家使用参考。
原理图和PCB图为AD9854外围电路!以下是AD9854的控制程序!//#include <reg51f.h>#include "sst89x5xxrd2.h"#include <intrins.h>#define USE_KEY 0#define uchar unsigned char#define uint unsigned int#define schar signed char#define sint signed int#define ulong unsigned long int//须主程序定义的参数/sbit ADDR0 =P2^0; //sbit ADDR1 =P2^1; //sbit ADDR2 =P2^2; //sbit ADDR3 =P2^3; //sbit ADDR4 =P2^4; //sbit ADDR5 =P2^5; ///sbit AD_FUD =P3^7; //UP_DATA sbit RUN =P3^2;sbit WR_LOW =P3^5; // WRsbit MASTER_RESET=P3^3;bit bdata F_Flag,OneSec_Flag,Re_Flag,P_Flag;//uchar SecOne;uchar Time_count;uchar AD_Addr;uchar dats;uchar TAB_Data[40];////初始化串口。
配置定时器// voidinitial_system(){EA = 0;TMOD=0x21; //初始化定时器0PCON=0x00;SCON=0x50;TH0 = 0xdc; //10毫秒定时, 采用晶体11.0592 定时器0,方式1 TL0 = 0x00;TH1 = 0xfd; //波特率9600 采用晶体11.0592 定时器1,方式1 TL1 = 0xfd;TR0 =1; //开启定时器0TR1 =1; //开启定时器0ET0 =1; //时钟0ES =0; //开串口中断EA = 1 ; // 使能所有中断}void Timer0() interrupt 1 using 3{TH0 = 0xdc; //10毫秒采用晶体11.0592 定时器0,方式1TL0 = 0x00;SecOne++;if(SecOne>200) //计时1秒钟{SecOne=0x00;OneSec_Flag=1;RUN=~RUN;}}//void AD9854_delay(int time){int i;for(i = 0; i < time; i++){_nop_();_nop_();_nop_();_nop_();}}void TAB_DataWord(){TAB_Data[0]=0x00; //00H Phase Adjust Register #1 <13:8> (Bits 15, 14 don't care) Phase #1 相位为0TAB_Data[1]=0x00; //01H Phase Adjust Register #1 <7:0> 01HTAB_Data[2]=0x00; //02H Phase Adjust Register #2 <13:8> (Bits 15, 14 don't care) Phase #2 相位为0TAB_Data[3]=0x00; //03H Phase Adjust Register #1 <7:0> 03H//100MTAB_Data[4]=0X31; //Frequency Tuning Word 1 <47:40>//623795E0184ATAB_Data[5]=0X1B; //Frequency Tuning Word 1 <39:32>TAB_Data[6]=0xE6; //Frequency Tuning Word 1 <31:24>TAB_Data[7]=0xE6; //Frequency Tuning Word 1 <23:16>TAB_Data[8]=0x53; //Frequency Tuning Word 1 <15:8>TAB_Data[9]=0x86; //Frequency Tuning Word 1 <7:0>//FTW2TAB_Data[10]=0x31; //Frequency Tuning Word 2 <47:40TAB_Data[11]=0x1B; //Frequency Tuning Word 2 <39:32>TAB_Data[12]=0xE6; //Frequency Tuning Word 2 <31:24>TAB_Data[13]=0xE6; //Frequency Tuning Word 2 <23:16>TAB_Data[14]=0x53; //Frequency Tuning Word 2 <15:8>TAB_Data[15]=0x86; //Frequency Tuning Word 2 <7:0> //500KHZ//FTWTAB_Data[16]=0x01; //Delta Frequency Word <47:40>TAB_Data[17]=0x47; //Delta Frequency Word <39:32>TAB_Data[18]=0xAE; //Delta Frequency Word <31:24>TAB_Data[19]=0x14; //Delta Frequency Word <23:16>TAB_Data[20]=0x7A; //Delta Frequency Word <15:8>TAB_Data[21]=0xE1; //Delta Frequency Word <7:0> 三角波 //频率为0//UpclokTAB_Data[22]=0x00; //Update Clock <31:24>TAB_Data[23]=0x00; //Update Clock <23:16>TAB_Data[24]=0x00; //Update Clock <15:8>TAB_Data[25]=0xF0; //Update Clock <7:0> //系统出现寄存器更新信号reg. Int UpdateClk.=0;外部更新TAB_Data[26]=0x00; //Ramp Rate Clock <19:16> (Bits 23, 22, 21, 20 don't care)TAB_Data[27]=0x00; //Ramp Rate Clock <15:8>TAB_Data[28]=0x00; //Ramp Rate Clock <7:0>TAB_Data[29]=0x10; //Don't Care(0),Don't Care(0),Don't Care(0),Comp PD(1),Reserved_Always Low(0),QDAC PD(0),DAC PD(0),DIG PD(0).TAB_Data[30]=0x20; //Don't Care(0),PLL Range(1),Bypass PLL(1),Ref Mult 4(0),RefMult 3(0),Ref Mult 2(0),Ref Mult 1(0),Ref Mult 0(0).TAB_Data[31]=0x10; //CLR ACC1(0),CLR ACC2(0),Triangle(0)(三角波),SRC QDAC(0),Mode2(0),Mode 1(0),Mode 0(0),Int Update Clk(0). 注意TAB_Data[32]=0x50; //Don't Care(0),Bypass_Inv_Sinc(0),OSK EN(0),OSK INT(0),Don't Care(0),Don't Care(0),LSB First(0),SDO_Active(0).TAB_Data[33]=0x00; //Output Shape Key I Mult <11:8> (Bits 15, 14, 13, 12 don't care)TAB_Data[34]=0x0F; //Output Shape Key I Mult <7:0>TAB_Data[35]=0x00; //Output Shape Key Q Mult <11:8> (Bits 15, 14, 13, 12 don't care)TAB_Data[36]=0x0F; //Output Shape Key Q Mult <7:0>TAB_Data[37]=0xFF; //Output Shape Key Ramp Rate <7:0>TAB_Data[38]=0x00; //QDAC <11:8> (Bits 15, 14, 13, 12 don't care)TAB_Data[39]=0x0F; //QDAC <7:0> (Data is required to be in twos complement format) }void AD9854_ParallelSendByte(uchar addr,uchar data1){// WR_LOW=0; //lhyaddr WR_LOW=WRB_nop_();P2=addr&0x3F;_nop_();P1=data1;WR_LOW=0; //lhyaddr WR_LOW=WRB_nop_();WR_LOW=1;_nop_();_nop_();WR_LOW=0; //lhyaddr WR_LOW=WRB}data0=*(SWord+i);AD9854_ParallelSendByte(Special_addr,data0); AD9854_delay(5);}}void Init9854(void){WR_LOW=0;AD_FUD=0;MASTER_RESET=0;}//void main(void){ uchar i;MASTER_RESET=0;initial_system(); //系统初始化Init9854();TAB_DataWord();MASTER_RESET=0;_nop_();_nop_();_nop_();_nop_();MASTER_RESET=1;AD9854_delay(30);_nop_();_nop_();_nop_();_nop_();_nop_();MASTER_RESET=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();AD9854_delay(500);AD9854_delay(500);AD9854_delay(500);for (i=0;i<40;i++){dats=TAB_Data[i];AD_Addr=i;AD9854_ParallelSendByte(AD_Addr,dats); }_nop_();AD_FUD=0;_nop_();_nop_();_nop_();AD_FUD=1;AD9854_delay(80);_nop_();_nop_();AD_FUD=0;while(1){if(OneSec_Flag==1){_nop_();_nop_();_nop_();AD9854_delay(80);_nop_();_nop_();_nop_();AD9854_delay(80);_nop_();for (i=0;i<40;i++){dats=TAB_Data[i];AD_Addr=i;AD9854_ParallelSendByte(AD_Addr,dats); }_nop_();AD_FUD=0;_nop_();_nop_();AD9854_delay(80);AD_FUD=1;_nop_();AD9854_delay(80); _nop_();_nop_();AD_FUD=0;OneSec_Flag=0; }_nop_();_nop_();}}。
基于AD9854的雷达信号源设计与实现袁辉;李延香【摘要】使用AD9854芯片和FPGA,基于DDS理论设计并实现了多模式多波形雷达信号源.它可模拟LFM、NLFM、单频、相位编码等多种脉冲信号波形,能有效验证脉冲压缩与信号处理单元的工作性能.测试结果表明,该系统能满足设计要求.%A multi-mode and multi-waveform radar signal generator based on DDS was designed with AD9854 and FPGA, which can be used to simulate various pulse signal waveforms such as LFM, NLFM, single frequency and phase code with wide Doppler modulation and long time delay adjustment. The performance of pulse compression and signal processing unit can be verified effectively. The testing result shows that the system can satisfy the requirement.【期刊名称】《现代电子技术》【年(卷),期】2011(034)021【总页数】5页(P23-27)【关键词】直接数字合成;AD9854;FPGA;雷达信号【作者】袁辉;李延香【作者单位】陕西工业职业技术学院信息工程学院,陕西咸阳 712000;咸阳师范学院,陕西成阳 712000【正文语种】中文【中图分类】TN958.3-340 引言雷达信号源的设计在雷达测试中有着非常重要的作用。
本文设计的雷达信号源要求实现三个功能:(1) 要求该系统能产生多种波形信号,包括:线性调频信号,非线性调频信号等[1]。
adxl345的STM32驱动程序和硬件设计⼀、硬件电路接⼝图⽚1.ADXL345硬件接⼝图⽚使⽤的是SPI端⼝进⾏通信,这样读取数据⽐较快且后续也可以转化为IIC通信接⼝。
在⽹上找⼀些发现IIC接⼝的⽐较多,所以本⼈就DIY做SPI的通信。
2.STM32F103T系列单⽚机作为MCU 资源⽐较丰富、本⼈⽐较熟悉开发速度较快硬件电路⾸先是为了实现功能,所以设计⽐较简单。
后续⼩编想做⽆线蓝⽛的数据传输,所以硬件上也留了蓝⽛串⼝通信的硬件接⼝和3.3V电源管理。
⼆、单⽚机驱动代码1.ADXL345的端⼝配置函数#define ADXL345_FLAG_TIMEOUT ((uint32_t)0x1000)#define ADXL345_SPI SPI1#define ADXL345_SPI_CLK RCC_APB2Periph_SPI1#define ADXL345_SPI_SCK_PIN GPIO_Pin_5#define ADXL345_SPI_SCK_GPIO_PORT GPIOA#define ADXL345_SPI_SCK_GPIO_CLK RCC_APB2Periph_GPIOA#define ADXL345_SPI_SCK_SOURCE GPIO_PinSource5#define ADXL345_SPI_SCK_AF GPIO_AF_5#define ADXL345_SPI_MISO_PIN GPIO_Pin_6#define ADXL345_SPI_MISO_GPIO_PORT GPIOA#define ADXL345_SPI_MISO_GPIO_CLK RCC_APB2Periph_GPIOA#define ADXL345_SPI_MISO_SOURCE GPIO_PinSource6#define ADXL345_SPI_MISO_AF GPIO_AF_5#define ADXL345_SPI_MOSI_PIN GPIO_Pin_7#define ADXL345_SPI_MOSI_GPIO_PORT GPIOA#define ADXL345_SPI_MOSI_GPIO_CLK RCC_APB2Periph_GPIOA#define ADXL345_SPI_MOSI_SOURCE GPIO_PinSource7#define ADXL345_SPI_MOSI_AF GPIO_AF_5#define ADXL345_SPI_CS_PIN GPIO_Pin_2#define ADXL345_SPI_CS_GPIO_PORT GPIOB#define ADXL345_SPI_CS_GPIO_CLK RCC_APB2Periph_GPIOB#define ADXL345_SPI_INT1_PIN GPIO_Pin_0#define ADXL345_SPI_INT1_GPIO_PORT GPIOB#define ADXL345_SPI_INT1_GPIO_CLK RCC_APB2Periph_GPIOB#define ADXL345_SPI_INT1_EXTI_LINE EXTI_Line0#define ADXL345_SPI_INT1_EXTI_PORT_SOURCE EXTI_PortSourceGPIOB#define ADXL345_SPI_INT1_EXTI_PIN_SOURCE EXTI_PinSource0#define ADXL345_SPI_INT1_EXTI_IRQn EXTI0_IRQn#define ADXL345_SPI_INT2_PIN GPIO_Pin_1#define ADXL345_SPI_INT2_GPIO_PORT GPIOB#define ADXL345_SPI_INT2_GPIO_CLK RCC_APB2Periph_GPIOB#define ADXL345_SPI_INT2_EXTI_LINE EXTI_Line1#define ADXL345_SPI_INT2_EXTI_PORT_SOURCE EXTI_PortSourceGPIOB #define ADXL345_SPI_INT2_EXTI_PIN_SOURCE EXTI_PinSource1#define ADXL345_SPI_INT2_EXTI_IRQn EXTI1_IRQn#define ADXL345_WHO_AM_I_ADDR 0x0F#define ADXL345_CTRL_REG1_ADDR 0x20#define ADXL345_CTRL_REG2_ADDR 0x21#define ADXL345_CTRL_REG3_ADDR 0x22#define ADXL345_CTRL_REG4_ADDR 0x23#define ADXL345_CTRL_REG5_ADDR 0x24#define ADXL345_REFERENCE_REG_ADDR 0x25#define ADXL345_OUT_TEMP_ADDR 0x26#define ADXL345_STATUS_REG_ADDR 0x27#define ADXL345_OUT_X_L_ADDR 0x28#define ADXL345_OUT_X_H_ADDR 0x29#define ADXL345_OUT_Y_L_ADDR 0x2A#define ADXL345_OUT_Y_H_ADDR 0x2B#define ADXL345_OUT_Z_L_ADDR 0x2C#define ADXL345_OUT_Z_H_ADDR 0x2D#define ADXL345_FIFO_CTRL_REG_ADDR 0x2E#define ADXL345_FIFO_SRC_REG_ADDR 0x2F#define ADXL345_INT1_CFG_ADDR 0x30#define ADXL345_INT1_SRC_ADDR 0x31#define ADXL345_INT1_TSH_XH_ADDR 0x32#define ADXL345_INT1_TSH_XL_ADDR 0x33#define ADXL345_INT1_TSH_YH_ADDR 0x34#define ADXL345_INT1_TSH_YL_ADDR 0x35#define ADXL345_INT1_TSH_ZH_ADDR 0x36#define ADXL345_INT1_TSH_ZL_ADDR 0x37#define ADXL345_INT1_DURATION_ADDR 0x38#define I_AM_ADXL345 ((uint8_t)0xD4)#define ADXL345_MODE_POWERDOWN ((uint8_t)0x00)#define ADXL345_MODE_ACTIVE ((uint8_t)0x08)#define ADXL345_OUTPUT_DATARATE_1 ((uint8_t)0x00)#define ADXL345_OUTPUT_DATARATE_2 ((uint8_t)0x40)#define ADXL345_OUTPUT_DATARATE_3 ((uint8_t)0x80)#define ADXL345_OUTPUT_DATARATE_4 ((uint8_t)0xC0)#define ADXL345_X_ENABLE ((uint8_t)0x02)#define ADXL345_Y_ENABLE ((uint8_t)0x01)#define ADXL345_Z_ENABLE ((uint8_t)0x04)#define ADXL345_AXES_ENABLE ((uint8_t)0x07)#define ADXL345_AXES_DISABLE ((uint8_t)0x00)#define ADXL345_BANDWIDTH_1 ((uint8_t)0x00)#define ADXL345_BANDWIDTH_2 ((uint8_t)0x10)#define ADXL345_BANDWIDTH_3 ((uint8_t)0x20)#define ADXL345_BANDWIDTH_4 ((uint8_t)0x30)#define ADXL345_FULLSCALE_250 ((uint8_t)0x00)#define ADXL345_FULLSCALE_500 ((uint8_t)0x10)#define ADXL345_FULLSCALE_2000 ((uint8_t)0x20)#define ADXL345_BlockDataUpdate_Continous ((uint8_t)0x00) #define ADXL345_BlockDataUpdate_Single ((uint8_t)0x80)#define ADXL345_BLE_LSB ((uint8_t)0x00)#define ADXL345_BLE_MSB ((uint8_t)0x40)#define ADXL345_HIGHPASSFILTER_DISABLE ((uint8_t)0x00) #define ADXL345_HIGHPASSFILTER_ENABLE ((uint8_t)0x10)#define ADXL345_INT1INTERRUPT_DISABLE ((uint8_t)0x00) #define ADXL345_INT1INTERRUPT_ENABLE ((uint8_t)0x80)#define ADXL345_INT2INTERRUPT_DISABLE ((uint8_t)0x00) #define ADXL345_INT2INTERRUPT_ENABLE ((uint8_t)0x08)#define ADXL345_INT1INTERRUPT_LOW_EDGE ((uint8_t)0x20)#define ADXL345_INT1INTERRUPT_HIGH_EDGE ((uint8_t)0x00)#define ADXL345_BOOT_NORMALMODE ((uint8_t)0x00)#define ADXL345_BOOT_REBOOTMEMORY ((uint8_t)0x80)#define ADXL345_HPM_NORMAL_MODE_RES ((uint8_t)0x00)#define ADXL345_HPM_REF_SIGNAL ((uint8_t)0x10)#define ADXL345_HPM_NORMAL_MODE ((uint8_t)0x20)#define ADXL345_HPM_AUTORESET_INT ((uint8_t)0x30)#define ADXL345_HPFCF_0 0x00#define ADXL345_HPFCF_1 0x01#define ADXL345_HPFCF_2 0x02#define ADXL345_HPFCF_3 0x03#define ADXL345_HPFCF_4 0x04#define ADXL345_HPFCF_5 0x05#define ADXL345_HPFCF_6 0x06#define ADXL345_HPFCF_7 0x07#define ADXL345_HPFCF_8 0x08#define ADXL345_HPFCF_9 0x09#define ADXL345_CS_LOW() GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT, ADXL345_SPI_CS_PIN) #define ADXL345_CS_HIGH() GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT, ADXL345_SPI_CS_PIN)void ADXL345_Init(ADXL345_InitTypeDef *ADXL345_InitStruct);void ADXL345_RebootCmd(void);void ADXL345_INT1InterruptCmd(uint8_t InterruptState);void ADXL345_INT2InterruptCmd(uint8_t InterruptState);void ADXL345_INT1InterruptConfig(ADXL345_InterruptConfigTypeDef *ADXL345_IntConfigStruct);uint8_t ADXL345_GetDataStatus(void);void ADXL345_FilterConfig(ADXL345_FilterConfigTypeDef *ADXL345_FilterStruct);void ADXL345_FilterCmd(uint8_t HighPassFilterState);void ADXL345_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);void ADXL345_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead);2.ADXL345的SPI配置函数void SPI_init(void){GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(ADXL345_SPI_CLK ,ENABLE);GPIO_StructInit(&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =ADXL345_SPI_CS_PIN ;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADXL345_SPI_CS_GPIO_PORT, &GPIO_InitStructure);GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT,ADXL345_SPI_CS_PIN);GPIO_StructInit(&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =ADXL345_SPI_SCK_PIN|ADXL345_SPI_MISO_PIN|ADXL345_SPI_MOSI_PIN; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADXL345_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode=SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial=7;SPI_Init(ADXL345_SPI, &SPI_InitStructure);SPI_Cmd(ADXL345_SPI,ENABLE);}3.ADXL345初始化配置函数void ADXL345_init(void){SPI_init(); //ADXL345¶Ë¿Ú³õʼ»¯ÅäÖÃSPIͨÐÅADXL345_write_byte(0x1E,0x00); //X Æ«ÒÆÁ¿¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)ADXL345_write_byte(0x1F,0x00); //Y Æ«ÒÆÁ¿¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)ADXL345_write_byte(0x20,0x00); //Z Æ«ÒÆÁ¿¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)ADXL345_write_byte(0x21,0x00); //Çû÷ÑÓʱ0:½ûÓÃ; (1.25ms/LSB)ADXL345_write_byte(0x22,0x00); //¼ì²âµÚÒ»´ÎÇû÷ºóµÄÑÓʱ0:½ûÓÃ; (1.25ms/LSB)ADXL345_write_byte(0x23,0x00); //Çû÷´°¿Ú0:½ûÓÃ; (1.25ms/LSB)ADXL345_write_byte(0x24,0x01); //±£´æ¼ì²â»î¶¯·§Öµ; (62.5mg/LSB)ADXL345_write_byte(0x25,0x01); //±£´æ¼ì²â¾²Ö¹·§Öµ; (62.5mg/LSB)ADXL345_write_byte(0x26,0x2B); //¼ì²â»î¶¯Ê±¼ä·§Öµ; (1s/LSB)ADXL345_write_byte(0x27,0x00); //ADXL345_write_byte(0x28,0x09); //×ÔÓÉÂäÌå¼ì²âÍÆ¼ö·§Öµ; (62.5mg/LSB)ADXL345_write_byte(0x29,0xFF); //×ÔÓÉÂäÌå¼ì²âʱ¼ä·§Öµ,ÉèÖÃΪ×î´óʱ¼ä; (5ms/LSB)ADXL345_write_byte(0x2A,0x80); ////ADXL345_read_byte(0x2B); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡ADXL345_write_byte(0x2C,0x0F); //ËÙÂÊÉ趨Ϊ3200HZ²Î¿¼pdf13Ò³ 0X0A 1OO,0X0E 1600HZADXL345_write_byte(0x2D,0x08); //Ñ¡ÔñµçԴģʽ¹Ø±Õ×Ô¶¯ÐÝÃß,ÐÝÃß,»½Ðѹ¦Äܲο¼pdf24Ò³ADXL345_write_byte(0x2E,0x80); //ʹÄÜ DATA_READY ÖжÏADXL345_write_byte(0x2F,0x00);//ADXL345_read_byte(0x30); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡ADXL345_write_byte(0x31,0X0B);//Êý¾ÝͨПñʽ;ÉèÖÃΪ×Լ칦ÄܽûÓÃ,4ÏßÖÆSPI½Ó¿Ú,µÍµçƽÖжÏÊä³ö,13λȫ·Ö±æÂÊ,Êä³öÊý¾ÝÓÒ¶ÔÆë,16gÁ¿³Ì ADXL345_write_byte(0x38,0x00); //FIFOģʽÉ趨,Streamģʽ£¬´¥·¢Á¬½ÓINT1,31¼¶Ñù±¾»º³å//ADXL345_read_byte(0x39); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡}4.ADXL345的读写函数u8 ADXL345_read_byte(u8 add){GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);SPI_I2S_SendData(ADXL345_SPI,(add|0x80)<<8|0x00);while(SPI_I2S_GetFlagStatus(ADXL345_SPI,SPI_I2S_FLAG_TXE)==RESET);while(SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_RXNE)==RESET);GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);return SPI_I2S_ReceiveData(ADXL345_SPI)&0xff;}void ADXL345_write_byte(u8 add,u8 val){GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);SPI_I2S_SendData(ADXL345_SPI,add<<8|val);while(SPI_I2S_GetFlagStatus(ADXL345_SPI,SPI_I2S_FLAG_TXE)==RESET);while(SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_RXNE)==RESET);GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);SPI_I2S_ReceiveData(ADXL345_SPI)&0xff;}void ADXL345_ReadXYZ(float *g){uint8_t BUF[6]; // ´æ·ÅX,Y,ZÖáµÄÊý¾Ýint16_t temp;BUF[0] = ADXL345_read_byte(0x32);BUF[1] = ADXL345_read_byte(0x33);delay_ms(1);BUF[2] = ADXL345_read_byte(0x34);BUF[3] = ADXL345_read_byte(0x35);delay_ms(1);BUF[4] = ADXL345_read_byte(0x36);BUF[5] = ADXL345_read_byte(0x37);delay_ms(1);temp = (BUF[1] << 8) + BUF[0];if(temp < 0)temp = -temp;g[0] = (float)(temp * 3.9); //¼ÆËãÊý¾ÝºÍÏÔʾ,²é¿¼ADXL345¿ìËÙÈëÃŵÚ4Ò³temp = (BUF[3] << 8) + BUF[2];if(temp < 0)temp = -temp;g[1] = (float)(temp * 3.9); //¼ÆËãÊý¾ÝºÍÏÔʾ,²é¿¼ADXL345¿ìËÙÈëÃŵÚ4Ò³temp = (BUF[5] << 8) + BUF[4];if(temp < 0)temp = -temp;g[2] = (float)(temp * 3.9); //¼ÆËãÊý¾ÝºÍÏÔʾ,²é¿¼ADXL345¿ìËÙÈëÃŵÚ4Ò³}。
ADS8345驱动程序设计文档版本历史目录1引言 (4)1.1 编写目的 (4)1.2 实验环境 (4)1.4 术语和缩写词 (4)2 关于硬件的说明 (4)2.1 ADS8345的简介 (4)2 驱动程序的组织结构 (7)2.1 Linux的设备模型 (7)2.2 Tiny210 SPI移植 (9)2.3 mini2440 SPI驱动移植 (11)2.4 SPI移植驱动验证 (19)3 ADS8345驱动实现 (20)3.1 Linux设备模型 (20)3.2 驱动接口实现 (26)4总结说明 (33)1引言1.1 编写目的本文档编写目的是:方便实验室内部交流、相同工作只做一遍、在不同届学生之间项目的快速交接之目的。
1.2 实验环境1.2.1 内核版本:2.6.32.2(mini2440) 2.6.35.7(Tiny210)1.2.2硬件平台:mini2440开发板, Tiny210开发板1.2.3参考资料:华清远见SPI讲解资料,2010级师兄政越伟论文1.4 术语和缩写词2 关于硬件的说明2.1 ADS8345的简介ADS8345 是一款16 位逐次逼近型 8 通道串行输出的内部采样型模数转换器。
在100khz的转化速率,5v单电源供电的时候最大功耗为8mW。
参考电压可在500mv到1/2电源电源范围内变化。
输入电压范围根据参考电压而相适应。
本设备包括休眠模式,在这个模式下最低功耗可达15uw。
确保正常工作的最低电压是2.7v。
低功耗,高速率,自带多路转换器。
Ads8345是一款典型的逐次逼近型数模转换器。
内部自带采样保持器(SHA)典型应用电路:2.7-5V。
外部参考电源可以是500mV到+Vcc/2。
参考电源的电压直接决定转换器的模拟输入电压范围。
参考电源平均输入电流大小取决于AD的转换速率。
AD的模拟输入是差分的。
通过8通道的多路器获得。
输入电压可以根据COM端的电压设置。
或者使用8路中的4路来组成差分信号。
这些设置可以通过串口来选择。
模拟输入模拟输入是双极的差分的。
有两种方法来获得AD的模拟输入。
单端型和差分型。
当输入作为单端型的时候,COM端被保持在一个固定的电压。
CHX各个通道的输入电压在这个固定的电压值上下变化,峰峰值为2倍的Vref。
参考电压值决定COM端电压的变化范围。
当输入作为差分输入方式,各通道的输入电压的振幅为CHX端与COM端输入的差值。
每个通道的峰峰值为Vref。
在第一个八个时钟周期内。
可以通过Din端口向AD写入控制字符。
一旦AD获得了足够的控制信息之后就对内部的输入多路器进行设置。
AD就进入到采用模式。
四个或四个以上的时钟周期之后。
收到控制字符后,AD进入到转换模式。
在这个时候,输入采样保持器进入保持模式。
在之后的十六个时钟周期后完成实际的模拟数字转换。
控制字符:上图中显示出控制字符的每位控制字的写入顺序。
表中详细的给我这些控制字的说明。
第一位“S”为控制字的起始位,必须为逻辑高。
ADS8345会忽略所有的信息。
直到Din端口收到“S”这个开始位。
之后的三个位(A2-A0)可以用来选择模拟输入多路器的八个通道。
2 驱动程序的组织结构2.1 Linux的设备模型SPI接口是Motorola公司首先提出的全双工三线同步串行外围接口,采用主从模式(Master Slave)架构;一般仅支持单Master,但可以支持多slave模式。
时钟由Master控制,在时钟移位脉冲下,数据按位传输,高位在前(MSB first),低位在后(LSB);SPI接口有两根单向数据线,为全双工通信,目前应用中的数据速率可以达到Mbps级水平。
SPI接口主要应用在EEPROM、FLASH、RTC、ADC、DSP以及数字信号解码器之间。
它在芯片中只占用四根管脚用来控制以及进行数据传输,分别为SCK(时钟信号)、MOSI(主设备输出从设备输入)、MISO(主设备输入从设备输出),CS(片选信号,一般为低电平有效),节约了芯片的管脚数目,同时为PCB在布局上节省了空间。
正是由于这种简单易用的特性,现在越来越多的芯片上都集成了SPI技术。
其总线结构如图4.2所示:图4.2 SPI总线结构首先,主从设备之间进行的通信,要确保两个设备之间时钟的一致性,要匹配否则就没有办法进行正常的通信了。
对时钟(SCLK)来说,最重要的两个特性就是极性和相位了,只要保证两个设备的极性和相位保持一致,就可以保证两者正常通信。
时钟(SCLK)的空闲时刻,就是当时钟在发送八个比特数据之前和之后的状态,与此对应的就是在时钟发送数据的时候,也就是SPI正常工作的时候。
SPI 的极性就是指,当时钟空闲的时候,其电平是高电平还是低电平。
CPOL=0,表示时钟空闲的时候的电平是低电平;CPOL=1表示时钟空闲时候的电平是高电平。
其示时钟极性意图如图4.3:图4.3 时钟极性从图中可以看出,时钟的波形(CPOL=0)在有输出八个脉冲,而在脉冲输出前和完成后都保持在低电平状态。
此时的状态就是时钟空闲状态或无效状态,因为此时没有脉冲也就不会有数据传输。
同理可以得出CPOL=1的图形,无效状态为高电平。
时钟的相位就是表示当数据有效时刻,是在时钟的第几个条边沿进行采样,是在第一个或者第二个跳变沿进行采样。
CPHA=0表示在时钟的第一个跳变沿进行采样,即读取数据。
CPHA=1表示在时钟的第二个跳变沿进行数据采样。
SPI 接口的极性(CPOL)和相位(CPHA)分别可以是0或者是1,对应的组合可以实现SPI通信的四种模式:Mode0(CPOL=0,CPHA=0)、Mode1(CPOL=0,CPHA=1)、Mode2(CPOL=1,CPHA=0)、Mode3(CPOL=1,CPHA=1)。
其详细对比如表4.1:表4.1 时钟极性和相位组合其中Mode0和Mode3是最常用的模式,本系统采用的SPI接口协议即采用的Mode0,脉冲传输前和完成后都保持在低电平状态,所以CPOL=0即低电平是空闲时的电平。
在第一个跳变沿(上升沿)进行数据采样,第二个跳变沿(下降沿)输出数据,对应着CPHA=0。
其对应的时序图如4.4:图4.4 SPI时序图(MODE0)2.2 Tiny210 SPI移植Linux内核2.6.35.7的内核源码中已经给出了三星s5pv210的SPI驱动,但是Tiny210核心板并没有启用这个驱动,因此需要在开发板中配置这个驱动,使得Tiny210支持SPI接口。
通过对Linux内核相关的学习,得到在BSP包中添加添加SPI接口支持的方法:1)进入本开发板中的BSP相关的目录下,在Tiny210核心板中即是:/用户目录/Linux-2.6.35.7/arch/arm/mach-s5pv210,打开Tiny210的板级支持包Mach-mini210.c,加入相关头文件的支持,因为s5pv210的SPI寄存器相关定义和s3c64xx相同,故还是使用s3c64xx中SPI相关的寄存器,加入的头文件如下:#include <plat/s3c64xx-spi.h>#include <mach/spi-clocks.h>2)在平台相关设备中添加从设备相关结构体的定义,因为核心板有两个SPI 控制器,需要填充设备结构体数组struct spi_board_info s3c_spi_devs[],在本BSP 中的代码如下:static struct spi_board_info s3c_spi_devs[] __initdata = {[0] = {.modalias = "spidev",.mode = SPI_MODE_0,.max_speed_hz = 10000000,.bus_num = 0,.irq = IRQ_SPI0,.chip_select = 0,},[1] = {.modalias = "ads8345",.mode = SPI_MODE_0,.max_speed_hz = 1000000,.bus_num = 1,.irq = IRQ_SPI1,.chip_select = 0,},};本系统运用的是SPI1控制器,设备名字为ads8345,数据采集模式应用为Mode0即是CPOL=0, CPHA=0,采集速率为1MHz,SPI总线为一号总线,片选为低电平有效。
3)在struct platform_device *mini210_devices[] __initdata数组平台中添加SPI 控制器设备相关代码,用以在开发板初始化代码中注册进开发板,所添加的代码如下:&s5pv210_device_spi0,&s5pv210_device_spi1,设备结构体初始化代码,也就是SPI控制器设备结构体,包括设备名字,所用的资源等,s5pv210_device_spi0对应SPI第一个控制器,s5pv210_device_spi1对应第2个SPI控制器:struct platform_device s5pv210_device_spi0 = {.name = "s3c64xx-spi",.id = 0,.num_resources = ARRAY_SIZE(s5pv210_spi0_resource),.resource = s5pv210_spi0_resource,.dev = {.dma_mask = &spi_dmamask,.coherent_dma_mask = DMA_BIT_MASK(32),.platform_data = &s5pv210_spi0_pdata,},};struct platform_device s5pv210_device_spi1 = {.name = "s3c64xx-spi",.id = 1,.num_resources = ARRAY_SIZE(s5pv210_spi1_resource),.resource = s5pv210_spi1_resource,.dev = {.dma_mask = &spi_dmamask,.coherent_dma_mask = DMA_BIT_MASK(32),.platform_data = &s5pv210_spi1_pdata,},};4)在开发板的初始化代码中把上面步骤添加的相关代码,通过调用注册设备函数即在static void __init mini210_machine_init(void)中通过调用spi_register_board_info(s3c_spi_devs, ARRAY_SIZE(s3c_spi_devs))函数进行注册。