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