Embedded Design and Development Project-LIS302DL Acceleration Sensor Program Design


LIS302DL is a three-axis ±2g/±8g intelligent digital output acceleration sensor that provides I2C and SPI interfaces . The expansion board uses the I2C interface and the device address is 0x38 .
insert image description here

1. Implemented functions

  • ①pitch: The angle between the X axis and the horizontal plane, corresponding to the pitch angle of the human body forward and backward;
  • ②roll: the angle between the Y axis and the horizontal plane, corresponding to the side slip angle of the human body from left to right;
  • ③paw: The angle between the Z axis and the vertical direction, corresponding to the rotation angle of the human body around the Z axis;
  • ④ Real-time printing of X, Y, Z real-time data of the three-axis acceleration sensor;

2. Realize the code according to the function

1. The main file main.c

#include"key.h"
#include"led.h"
#include"lcd.h"
#include "stdio.h"
#include "lis302.h"

unsigned char ucSec,ucSec1;
unsigned char pucBuf[1];
unsigned char pucStr[21];
unsigned long ulTick_ms;

void LIS_Proc(void);
int main(void)
{
    
    
	SysTick_Config(72000);	//定时1ms(HCLK = 72MHz)
	KEY_Init();
	LED_Init();
	
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	i2c_init();
	pucBuf[0] = 0x47;
	i2c_write(pucBuf,0x20,1);
		
	while(1)
	{
    
    
		LED_Disp(ucSec);
		LIS_Proc();
	}
}

void LIS_Proc(void)
{
    
    
	if(ucSec != ucSec1)
	{
    
    
		ucSec1 = ucSec;
		
		i2c_read(pucBuf,0x29,1);
		sprintf((char*)pucStr,"  OutX:%02x",pucBuf[0]);
		LCD_DisplayStringLine(Line4,pucStr);
		
		i2c_read(pucBuf,0x2B,1);
		sprintf((char*)pucStr,"  OutY:%02x",pucBuf[0]);
		LCD_DisplayStringLine(Line5,pucStr);
		
		i2c_read(pucBuf,0x2D,1);
		sprintf((char*)pucStr,"  OutZ:%02x",pucBuf[0]);
		LCD_DisplayStringLine(Line6,pucStr);
	}
}
	
//SysTick 中断处理程序
	void SysTick_Handler(void)
	{
    
    
		ulTick_ms++;
		if(ulTick_ms % 1000 ==0)
		ucSec++;
		
	}
	
	

Main function analysis: ❤️ ❤️ ❤️

  1. Obtain the acceleration data of the X-axis through the X-axis output register 0x29 ;
  2. Obtain the acceleration data of the X-axis through the Y-axis output register 0x2B ;
  3. Obtain the acceleration data of the X-axis through the Z-axis output register 0x2D ;

2. The header file "lis302.h" of LIS302DL

#ifndef  __LIS302_H__
#define  __LIS302_H__

#include "stm32f10x.h"
void i2c_init(void);
void delay1(unsigned int n);

void I2CStart(void);
void I2CStop(void);
void I2CSendAck(void);
void I2CSendNotAck(void);
unsigned char I2CWaitAck(void);

void I2CSendByte(unsigned char cSendByte);
unsigned char I2CReceiveByte(void);
void i2c_write(unsigned char* pucBuf,unsigned char ucAddr,
	unsigned char ucNum);
void i2c_read(unsigned char* pucBuf,unsigned char ucAddr,
	unsigned char ucNum);

#endif

Brief analysis: ❤️ ❤️

  1. Except for the different header files, others are the same as the statement of the AT24C02 memory chip, please refer to: Embedded Design and Development Project - AT24C02 Memory Application Design ;
  2. Use the I2C protocol for communication, and can directly transplant the I2C driver;

3. The source file "lis302.c" of LIS302DL

#include "lis302.h"
/** I2C 总线接口 */
#define I2C_PORT GPIOA
#define SDA_Pin	GPIO_Pin_5
#define SCL_Pin GPIO_Pin_4

#define FAILURE 0
#define SUCCESS 1

//配置SDA信号线为输入模式
void SDA_Input_Mode()
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = SDA_Pin;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 

  	GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}

//配置SDA信号线为输出模式
void SDA_Output_Mode()
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = SDA_Pin;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  	GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}

//
void SDA_Output( uint16_t val )
{
    
    
	if ( val ) {
    
    
		GPIO_SetBits(I2C_PORT,SDA_Pin);
	} else {
    
    
		GPIO_ResetBits(I2C_PORT,SDA_Pin);
	}
}

//
void SCL_Output( uint16_t val )
{
    
    
	if ( val ) {
    
    
		GPIO_SetBits(I2C_PORT,SCL_Pin);
	} else {
    
    
		GPIO_ResetBits(I2C_PORT,SCL_Pin);
	}
}

//
uint8_t SDA_Input()
{
    
    
	return GPIO_ReadInputDataBit( I2C_PORT, SDA_Pin);
}

//延时程序
void delay1(unsigned int n)
{
    
    
	unsigned int i;
	for ( i=0;i<n;++i);
}

//I2C总线启动
void I2CStart(void)
{
    
    
	SDA_Output(1);delay1(500);
	SCL_Output(1);delay1(500);
	SDA_Output(0);delay1(500);
	SCL_Output(0);delay1(500);
}

//I2C总线停止
void I2CStop(void)
{
    
    
	SCL_Output(0); delay1(500);
	SDA_Output(0); delay1(500);
	SCL_Output(1); delay1(500);
	SDA_Output(1); delay1(500);

}

//等待应答
unsigned char I2CWaitAck(void)
{
    
    
	unsigned short cErrTime = 5;
	SDA_Input_Mode(); 
	delay1(500);
	SCL_Output(1);delay1(500);
	while(SDA_Input())
	{
    
    
		cErrTime--;
		delay1(500);
		if (0 == cErrTime)
		{
    
    
			SDA_Output_Mode();
			I2CStop();
			return FAILURE;
		}
	}
	//修改顺序
	SCL_Output(0);delay1(500); 
	SDA_Output_Mode();
	return SUCCESS;
}

//发送应答位
void I2CSendAck(void)
{
    
    
	SDA_Output(0);delay1(500);
	delay1(500);
	SCL_Output(1); delay1(500);
	SCL_Output(0); delay1(500);

}

//
void I2CSendNotAck(void)
{
    
    
	SDA_Output(1);
	delay1(500);
	SCL_Output(1); delay1(500);
	SCL_Output(0); delay1(500);

}

//通过I2C总线发送一个字节数据
void I2CSendByte(unsigned char cSendByte)
{
    
    
	unsigned char  i = 8;
	while (i--)
	{
    
    
		SCL_Output(0);delay1(500); 
		SDA_Output(cSendByte & 0x80); delay1(500);
		cSendByte += cSendByte;			//左移一位
		delay1(500); 
		SCL_Output(1);delay1(500); 
	}
	SCL_Output(0);delay1(500); 
}

//从I2C总线接收一个字节数据
unsigned char I2CReceiveByte(void)
{
    
    
	unsigned char i = 8;
	unsigned char cR_Byte = 0;
	SDA_Input_Mode(); 
	while (i--)
	{
    
    
		cR_Byte += cR_Byte;			//左移一位
		SCL_Output(0);delay1(500); 
		delay1(500); 
		SCL_Output(1);delay1(500); 
		cR_Byte |=  SDA_Input(); 
	}
	SCL_Output(0);delay1(500); 
	SDA_Output_Mode();
	return cR_Byte;
}

//I2C总线初始化
void i2c_init()
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitStructure.GPIO_Pin = SDA_Pin | SCL_Pin;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 // **

  	GPIO_Init(I2C_PORT, &GPIO_InitStructure);

}

//lis302dl加速度传感器 读
void i2c_read(unsigned char* pucBuf,unsigned char ucAddr,
	unsigned char ucNum)
	{
    
    
		I2CStart();
		I2CSendByte(0x38);
		I2CWaitAck();
		
		I2CSendByte(ucAddr);
		I2CWaitAck();
		
		I2CStart();
		I2CSendByte(0x39);
		I2CWaitAck();
		
		while(ucNum--)
		{
    
    
			*pucBuf++ = I2CReceiveByte();
			if(ucNum)
				I2CSendAck();
			else
			I2CSendNotAck();
		}
		I2CStop();
	}
	
	//lis302dl加速度传感器 写
	void i2c_write(unsigned char* pucBuf,unsigned char ucAddr,
	unsigned char ucNum)
	{
    
    
		I2CStart();
		I2CSendByte(0x38);
		I2CWaitAck();
		
		I2CSendByte(ucAddr);
		I2CWaitAck();
		
		while(ucNum--)
		{
    
    
			I2CSendByte(*pucBuf++);
			I2CWaitAck();
		}
		I2CStop();
		delay1(500);
	}

Brief analysis: ❤️ ❤️

  1. Each I2C slave device has a unique device address, which can be directly modified to 0x38 , and others do not need to be modified;
  2. When reading the lis302 acceleration data through the i2c_read() function, first send 0x38 , select the sensor, then send the address of the register , and finally send the read command 0x39 to read the data;
  3. Write i2c_write(), send 0x38 and register address, you can write data, no need to write data for now;

3. Attention and learning points in the process of realizing functions

1. Precautions

  1. It is necessary to connect correctly and disconnect the pins that are not used to prevent conflicts ;
  2. When copying the IIC driver of AT24C02, it is necessary to modify the conditional compilation of the header file and modify the address of the current device ;
  3. Write 0x47 data to the 0x20 control register first , and set it to normal mode;

2. Knowledge points learned

  1. Obtain the required three-axis sensor data according to the address of the register;
  2. Deepen the understanding of the development and application of I2C in single-chip microcomputer;
  3. ③Learn to transplant the I2C driver to other chips or sensors, only need to modify the device address and header file ;
  4. Realize the acquisition of real-time data of the X-axis, Y-axis, and Z-axis of the LIS302DL three-axis acceleration sensor;

❤️ ❤️ ❤️ ❤️ ❤️ ❤️

Guess you like

Origin blog.csdn.net/a6662580/article/details/124676431