蓝桥杯嵌入式国赛 ---- LIS302DL加速度传感器


前言

本文是基于嵌入式开发板CT117E,stm32f103RBT6。

一、原理图

在这里插入图片描述

二、由原理图得到的信息

  • SCL,SDL用I2C协议进行通信。
  • INT1,INT2,两个中断控制引脚。
  • SCL,SDA,INT1,INT2分别是PA4,PA5,PA6,PA7。

三、LIS302DL初始化

i2c.c

#include "stm32f10x.h"
#include "i2c.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;
		}
	}
	SDA_Output_Mode();
	SCL_Output(0);delay1(500); 
	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_GPIOA, 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.c

#include "lis302dl.h"
#include "i2c.h"
u8 t[3];
void lis302dl_write(u8 addr,u8 data)
{
	I2CStart();
	I2CSendByte(0x38);
	I2CWaitAck();

	I2CSendByte(addr);
	I2CWaitAck();

	I2CSendByte(data);
	I2CWaitAck();

	I2CStop();

}

u8 lis302dl_read(u8 addr)
{
	u8 t;
	I2CStart();
	I2CSendByte(0x38);
	I2CWaitAck();

	I2CSendByte(addr);
	I2CWaitAck();

	I2CStart();
	I2CSendByte(0x39);
	I2CWaitAck();

	t=I2CReceiveByte();
	I2CWaitAck();
	I2CStop();

	return t;
}

void lis302dl_init(void)
{
	lis302dl_write(0x20,0x47);	   //不用中断只需要初始化这个就行了  0x20一个寄存器的地址
	//DR=0,加速度的采集频率为 200Hz;
	//PD=1,LIS302DL工作在普通功耗模式;
	//FS=0,最大测量范围为 2g(2.3g),灵敏度为 18mg/LSB(16.2),受温度影响为 0.01%, 在0加速度时.飘移为 40mg;
	//STP=0,STM=0,表示 LIS302DL 工作在普通模式,即非自检模式;
	//Zen=1,表示使能 Z 轴方向加速度采集; 
	//Yen=1,表示使能 Y 轴方向加速度采集; 
	//Xen=1,表示使能 X 轴方向加速度采集; 

//下面是一些中断相关的初始化
//	lis302dl_write(0x21,0x00);
//	lis302dl_write(0x22,0xC0);
//	lis302dl_write(0x32,0x28);
//	lis302dl_write(0x33,0x28);
//	lis302dl_write(0x30,0x00);
}

u8* read_xyz(void)
{

	if((lis302dl_read(0x27)& 0x08)!=0)		  //判断数据xyz是不是可用
	{
		t[0]= lis302dl_read(0x29);			   //读取x轴数据
		t[1]= lis302dl_read(0x2B);			   //读取y轴数据
		t[2]= lis302dl_read(0x2D);			   //读取z轴数据
	}

	return t;
}
u8 LIS302DL_Check(void)
{
	if(lis302dl_read(0x0f)){	  //判断芯片是否正常
		return 1;
	}else{
		return 0;
	}
}


lis302dl.h

#ifndef LIS302DL_H
#define LIS302DL_H
#include "stm32f10x.h"

u8* read_xyz(void);
u8 LIS302DL_Check(void);
void lis302dl_init(void);

#endif


五、LIS302DL在主函数的应用方法

while(1)
{
		   val=read_xyz();
		   sprintf((char *)buff,"  x: %2.2f    ",val[0]/18.0);
		   LCD_DisplayStringLine(Line4,buff);
		   sprintf((char *)buff,"  y: %2.2f     ",val[1]/18.0);
		   LCD_DisplayStringLine(Line5,buff);
		   sprintf((char *)buff,"  z: %2.2f     ",val[2]/18.0);
		   LCD_DisplayStringLine(Line6,buff);
		  // Delay_Ms(200);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值