前言
本文是基于嵌入式开发板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);
}