//<br />// SPI_Lis3lv02dl : TMS320F2812 Teaching CD ROM<br />// (C) chenwei email chenwei_0218@qq.com<br />//<br />//###########################################################################<br />//<br />// FILE: Lis3lv02dl.c<br />//<br />// TITLE: SPI - Lis3lv02dl <br />// CPU Timer0 ISR every 50 ms<br />// Watchdog active , served in ISR and main-loop <br />//<br />//###########################################################################<br />//<br />// Ver | dd mmm yyyy | Who | Description of changes<br />// =====|=============|======|===============================================<br />// 2.0 | 11 Nov 2008 | C.W. | adapted to header-files Version 1.00 <br />//###########################################################################<br /><br />#include "DSP281x_Device.h"<br />#define WHO_AM_I 0x0f <br />#define OFFSET_X 0x16 <br />#define OFFSET_Y 0x17 <br />#define OFFSET_Z 0x18 <br />#define GAIN_X 0x19 <br />#define GAIN_Y 0x1a <br />#define GAIN_Z 0x1b <br />#define CTRL_REG1 0x20 <br />#define CTRL_REG2 0x21 <br />#define CTRL_REG3 0x22 <br />#define HP_FILTER_RESET 0x23 <br />#define STATUS_REG 0x27 <br />#define OUTX_L 0x28 <br />#define OUTX_H 0x29 <br />#define OUTY_L 0x2a <br />#define OUTY_H 0x2b <br />#define OUTZ_L 0x2c <br />#define OUTZ_H 0x2d <br />#define FF_WU_CFG 0x30 <br />#define FF_WU_SRC 0x31 <br />#define FF_WU_ACK 0x32 <br />#define FF_WU_THS_L 0x34 <br />#define FF_WU_THS_H 0x35 <br />#define FF_WU_DURATION 0x36 <br />#define DD_CFG 0x38 <br />#define DD_SRC 0x39 <br />#define DD_ACK 0x3a <br />#define DD_THSI_L 0x3c <br />#define DD_THSI_H 0x3d <br />#define DD_THSE_L 0x3e <br />#define DD_THSE_H 0x3f <br />#define LED0_ON GpioDataRegs.GPFDAT.bit.GPIOF6=1<br />#define LED0_OFF GpioDataRegs.GPFDAT.bit.GPIOF6=0<br />#define LED1_ON GpioDataRegs.GPFDAT.bit.GPIOF7=1<br />#define LED1_OFF GpioDataRegs.GPFDAT.bit.GPIOF7=0<br /><br />void delay_loop(void);<br />void spi_xmit(Uint16 a);<br />Uint16 spi_rev();<br />void Lis3lv02dq_init(void);<br />Uint16 read_LIS_register( Uint16 register_name);<br />void write_LIS_register(Uint16 register_name, Uint16 register_value);<br />void Lis3lv02dq_init(void);<br />Uint16 LIS_read_x(void); <br />Uint16 LIS_read_y(void); <br />Uint16 LIS_read_z(void);<br /> <br />Uint16 var1;<br />Uint16 var2;<br />Uint16 var3;<br />Uint16 ID_Lis3lv02dl;<br />Uint16 Led_Flag;<br />Uint16 Flag0;<br />Uint16 Flag1;<br />Uint16 CTRL_REG1_staus;<br />Uint16 Vulae_OFFSET_X,Vulae_OFFSET_Y,Vulae_OFFSET_Z;<br />Uint16 Vulae_GAIN_X,Vulae_GAIN_Y,Vulae_GAIN_Z;<br />Uint16 Vulae_CTRL_REG1,Vulae_CTRL_REG2;<br />Uint16 w_Rev_data,accel_x,accel_y,accel_z;<br /><br />// Prototype statements for functions found within this file.<br /><br />void Gpio_select(void);<br />void InitSystem(void);<br />void spi_init();<br />void spi_fifo_init();<br />interrupt void cpu_timer0_isr(void); // 定时器中断循环程序<br /><br />// Global Variables<br />Uint16 dummy;<br /><br />void main(void)<br />{<br /><br /> InitSystem(); // Initialize the DSP's core Registers<br /> <br /> Gpio_select(); // Setup the GPIO Multiplex Registers<br /> <br /> InitPieCtrl(); // Function Call to init PIE-unit ( code : DSP281x_PieCtrl.c)<br /> <br /> InitPieVectTable(); // Function call to init PIE vector table ( code : DSP281x_PieVect.c )<br /> <br /> // re-map PIE - entry for Timer 0 Interrupt <br /> EALLOW; // This is needed to write to EALLOW protected registers<br /> PieVectTable.TINT0 = &cpu_timer0_isr;<br /> EDIS; // This is needed to disable write to EALLOW protected registers<br /> <br /> InitCpuTimers();<br /> <br /> // Configure CPU-Timer 0 to interrupt every 50 ms:<br /> // 150MHz CPU Freq, 50000 祍econds interrupt period<br /> ConfigCpuTimer(&CpuTimer0, 150, 50000);<br /><br /> <br /> // Enable TINT0 in the PIE: Group 1 interrupt 7<br /> PieCtrlRegs.PIEIER1.bit.INTx7 = 1;<br /><br /> // Enable CPU INT1 which is connected to CPU-Timer 0:<br />// IER = 1;<br />// IER |= M_INT1; //使能连接到CPU-TIMER0的CPU中断<br /><br /> EINT; // 使能全局中断<br /> ERTM; // 使能全局实时中断DBGM<br /> spi_init();<br /> spi_fifo_init();<br /> Lis3lv02dq_init();<br /> StartCpuTimer0(); //定时器开始 <br /><br /> while(1)<br /> { <br /> while(CpuTimer0.InterruptCount < 4); // wait for Timer 0<br /> CpuTimer0.InterruptCount = 0;<br /> EALLOW;<br /> SysCtrlRegs.WDKEY = 0xAA; // and serve watchdog #2 <br /> EDIS; <br /> }<br />} <br /><br />void Gpio_select(void)<br />{<br /> EALLOW;<br /> GpioMuxRegs.GPAMUX.all = 0x0; // all GPIO port Pin's to I/O<br /> GpioMuxRegs.GPBMUX.all = 0x0; <br /> GpioMuxRegs.GPDMUX.all = 0x0;<br /> GpioMuxRegs.GPFMUX.all = 0xF; // SPI pins enabled <br /> GpioMuxRegs.GPEMUX.all = 0x0; <br /> GpioMuxRegs.GPGMUX.all = 0x0;<br /> <br /> GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6=0; //配置GPIOF6为输出<br /> GpioMuxRegs.GPFDIR.bit.GPIOF6=1;<br /> <br /> GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7=0; //配置GPIOF7为输出<br /> GpioMuxRegs.GPFDIR.bit.GPIOF7=1; <br /> <br /> EDIS;<br />} <br /><br /><br />void InitSystem(void)<br />{<br /> EALLOW;<br /> SysCtrlRegs.WDCR= 0x00AF; // Setup the watchdog <br /> // 0x00E8 to disable the Watchdog , Prescaler = 1<br /> // 0x00AF to NOT disable the Watchdog, Prescaler = 64<br /> SysCtrlRegs.SCSR = 0; // Watchdog generates a RESET <br /> SysCtrlRegs.PLLCR.bit.DIV = 10; // Setup the Clock PLL to multiply by 5<br /> <br /> SysCtrlRegs.HISPCP.all = 0x1; // Setup Highspeed Clock Prescaler to divide by 2<br /> SysCtrlRegs.LOSPCP.all = 0x2; // Setup Lowspeed CLock Prescaler to divide by 4<br /> <br /> // Peripheral clock enables set for the selected peripherals. <br /> SysCtrlRegs.PCLKCR.bit.EVAENCLK=0;<br /> SysCtrlRegs.PCLKCR.bit.EVBENCLK=0;<br /> SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0;<br /> SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0;<br /> SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0;<br /> SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;<br /> SysCtrlRegs.PCLKCR.bit.ECANENCLK=0;<br /> SysCtrlRegs.PCLKCR.bit.ADCENCLK=0;<br /> EDIS;<br />}<br /> <br />//Step5,所有中断服务程序和函数<br /><br />//发送一个读指令到加速度传感器<br />Uint16 read_LIS_register( Uint16 register_name)<br /> {<br /> Uint16 Tx_data; // 发送的数据<br /> Uint16 Rev_data; // 接收到的数据<br /> Tx_data =(register_name|0x0080)<<8; <br /> <br /> spi_xmit(Tx_data); //发送<br /> <br /> while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } //等待直到FIFO接收到数据 <br /> <br /> Rev_data = (SpiaRegs.SPIRXBUF) & 0x00FF; // 读取接收到的数据<br /><br /> return(Rev_data); //返回读取到数据<br />}<br /><br />//发送一个写指令到加速度传感器<br /> void write_LIS_register(Uint16 register_name, Uint16 register_value)<br />{<br /> Uint16 w_Tx_data; <br /><br /> w_Tx_data = (register_name<<8)+register_value ; <br /> <br /> spi_xmit(w_Tx_data); //发送数据 <br /><br /> while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } //等待直到FIFO接收到数据 <br /><br /> w_Rev_data = (SpiaRegs.SPIRXBUF) & 0x00FF; //接收数据并且屏蔽无效位<br /><br />}<br /><br />//SPI发送<br /> void spi_xmit(Uint16 a)<br /> {<br /> SpiaRegs.SPITXBUF=a; //向SPI发送缓冲写数据<br /> }<br /><br /> <br />//加速度计Lis3lv02dq初始化<br /> void Lis3lv02dq_init(void) <br />{ <br /><br /> ID_Lis3lv02dl = read_LIS_register(WHO_AM_I); //读取器件ID<br /><br /> write_LIS_register(CTRL_REG1, 0xD7); //设置采样率,160khz。正常工作模式 <br /> write_LIS_register(CTRL_REG2, 0x14); //从内flash校准参数,如X/Y/Z轴的偏移量和增益,<br /> //调整到出厂设置,调往boot位置o<br /> delay_loop(); <br /><br /> write_LIS_register(CTRL_REG1, 0xD7); //设置采样率,160khz。正常工作模式<br /> write_LIS_register(CTRL_REG2, 0x44); //读取完高字节后数据更新,确保数据传输正确, <br /> //使能数据更新信号<br /><br /><br /> Vulae_OFFSET_X = read_LIS_register(OFFSET_X); //读取X轴加速度偏移量<br /><br /> Vulae_OFFSET_Y = read_LIS_register(OFFSET_Y); //读取Y轴加速度偏移量<br /> <br /> Vulae_OFFSET_Z = read_LIS_register(OFFSET_Z); //读取Z轴加速度偏移量<br /><br /> Vulae_GAIN_X = read_LIS_register(GAIN_X); //读取X轴加速度增益<br /><br /> Vulae_GAIN_Y = read_LIS_register(GAIN_Y); //读取Y轴加速度增益<br /><br /> Vulae_GAIN_Z = read_LIS_register(GAIN_Z); //读取Z轴加速度增益<br /><br /> write_LIS_register(CTRL_REG1, 0xD7); //写CTRL_REG1工作状态,正常工作<br /> <br /> Vulae_CTRL_REG1 = read_LIS_register(CTRL_REG1); //读取CTRL_REG1<br /><br /> Vulae_CTRL_REG2 = read_LIS_register(CTRL_REG2); //读取CTRL_REG2<br /><br /><br />} <br />//读取X轴加速度<br />Uint16 LIS_read_x(void) <br />{ <br /> Uint16 low, high; <br /><br /> low = read_LIS_register(0x28); <br /> high = read_LIS_register(0x29); <br /> accel_x = (((Uint16)high)<<8) | low;<br /> <br /> return(accel_x); <br />} <br /><br />//读取Y轴加速度<br />Uint16 LIS_read_y(void) <br />{ <br /> Uint16 low, high; <br /><br /> low = read_LIS_register(0x2A); <br /> high = read_LIS_register(0x2B); <br /> accel_y = (((Uint16)high)<<8) | low;<br /><br /> return(accel_y); <br />} <br /><br />//读取Z轴加速度<br />Uint16 LIS_read_z(void) <br />{ <br /> Uint16 low, high; <br /><br /> low = read_LIS_register(0x2C); <br /> high = read_LIS_register(0x2D); <br /> accel_z = (((Uint16)high)<<8) | low; <br /><br /> return(accel_z); <br />} <br /><br />//定时器中断程序<br />interrupt void cpu_timer0_isr(void)<br />{<br /> CpuTimer0.InterruptCount++;<br /> <br /> LIS_read_x(); //读取X轴加速度<br /> LIS_read_y(); //读取Y轴加速度<br /> LIS_read_z(); //读取Z轴加速度<br /><br /> if(Led_Flag == 1) //驱动LED灯<br /> {<br /> LED0_OFF;<br /> LED1_ON;<br /><br /> Led_Flag = 0;<br /> }<br /> else<br /> {<br /> LED0_ON;<br /> LED1_OFF;<br /><br /> Led_Flag = 1;<br /> }<br /> // 每次中断复位看门狗 <br /> EALLOW;<br /> SysCtrlRegs.WDKEY = 0x55; // 组合复位看门狗<br /> EDIS;<br /><br /> PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //申明已经接收到中断并且允许接收更多的中断<br />}<br /><br />void delay_loop()<br />{<br /> long i;<br /> for (i = 0; i < 1000000; i++) {}<br />}<br /><br /><br />void error(void)<br />{<br /> asm(" ESTOP0"); // 测试错误停止<br /> for (;;);<br />}<br /><br />void spi_init()<br />{ <br /> SpiaRegs.SPICCR.all =0x000F; // 复位,数据在上升沿输出 , 字符长度为16位 <br /> SpiaRegs.SPICTL.all =0x0006; // 使能主模式,正常相位<br /> // 使能发送,SPI中断禁止<br /> SpiaRegs.SPIBRR =0x007C; //300KHZ设置波特率 <br /> SpiaRegs.SPICCR.all =0x008F; // 退出复位,数据在上升沿输出 , 字符长度为16位 <br /> SpiaRegs.SPIPRI.bit.FREE = 1; // SPI操作,自由运行<br />}<br /><br /><br />void spi_fifo_init() <br />{<br />// 初始化 SPI FIFO 寄存器<br /> SpiaRegs.SPIFFTX.all=0xE040;<br /> SpiaRegs.SPIFFRX.all=0x204f;<br /> SpiaRegs.SPIFFCT.all=0x0;<br />} <br /><br />//===========================================================================<br />// 代码结束<br />//===========================================================================<br /><br /> |
|