资讯详情

嵌入式设计与开发项目-LIS302DL加速度传感器程序设计

嵌入式设计与开发项目-LIS302DL加速度传感器程序设计

  • 一、实现功能
  • 二、根据功能实现代码
    • 1、主文件main.c
    • 2、LIS302DL的头文件“lis302.h”
    • 3、LIS302DL的源文件“lis302.c”
  • 三、实现功能过程的注意力和学习点
    • 1、注意点
    • 2.学习知识点
LIS302DL是三轴±2g/±8g 提供智能数字输出加速度传感器 ,使用的是扩展板I2C接口, . 在这里插入图片描述

一、实现功能

二、根据功能实现代码

1、主文件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
        ++
        ; 
        } 
       

主函数分析:❤️ ❤️ ❤️

  1. 通过获取X轴的加速度数据;
  2. 通过获取X轴的加速度数据;
  3. 通过获取X轴的加速度数据;

2、LIS302DL的头文件“lis302.h”

#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

简要分析:❤️ ❤️

  1. 除了头文件不一样,其它的和AT24C02存储芯片的声明一样,可参考:嵌入式设计与开发项目-AT24C02存储器应用程序设计;
  2. 使用I2C协议进行通讯,可直接进行移植I2C驱动;

3、LIS302DL的源文件“lis302.c”

#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);
	}

简要分析:❤️ ❤️

  1. 每个I2C从设备都有唯一的器件地址,可直接修改,其它无需修改;
  2. 通过i2c_read()函数读取lis302加速度数据时,,选中传感器,然后,最后发送进行读取数据;
  3. 编写i2c_write(),发送0x38和寄存器地址,即可写入数据,暂不需要写入数据;

三、实现功能过程的注意与学习点

1、注意点

  1. 需要正确连线,断开没有使用到功能的引脚,
  2. 复制AT24C02的IIC驱动时,需要修改头文件的条件编译,并且
  3. 先往写入0x47数据,设置为正常模式;

2、学习的知识点

  1. 根据寄存器的地址获取到需要的三轴传感器数据;
  2. 加深对I2C在单片机开发应用的认识;
  3. 学会移植I2C驱动到其它芯片或传感器上,
  4. 实现LIS302DL三轴加速度传感器的X轴、Y轴、Z轴实时数据的获取;

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

标签: stm32三轴加速度传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司