嵌入式设计与开发项目-LIS302DL加速度传感器程序设计
- 一、实现功能
- 二、根据功能实现代码
-
- 1、主文件main.c
- 2、LIS302DL的头文件“lis302.h”
- 3、LIS302DL的源文件“lis302.c”
- 三、实现功能过程的注意力和学习点
-
- 1、注意点
- 2.学习知识点
一、实现功能
二、根据功能实现代码
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
++
;
}
主函数分析:❤️ ❤️ ❤️
- 通过获取X轴的加速度数据;
- 通过获取X轴的加速度数据;
- 通过获取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
简要分析:❤️ ❤️
- 除了头文件不一样,其它的和AT24C02存储芯片的声明一样,可参考:嵌入式设计与开发项目-AT24C02存储器应用程序设计;
- 使用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);
}
简要分析:❤️ ❤️
- 每个I2C从设备都有唯一的器件地址,可直接修改,其它无需修改;
- 通过i2c_read()函数读取lis302加速度数据时,,选中传感器,然后,最后发送进行读取数据;
- 编写i2c_write(),发送0x38和寄存器地址,即可写入数据,暂不需要写入数据;
三、实现功能过程的注意与学习点
1、注意点
- 需要正确连线,断开没有使用到功能的引脚,;
- 复制AT24C02的IIC驱动时,需要修改头文件的条件编译,并且;
- 先往写入0x47数据,设置为正常模式;
2、学习的知识点
- ①根据寄存器的地址获取到需要的三轴传感器数据;
- ②加深对I2C在单片机开发应用的认识;
- ③学会移植I2C驱动到其它芯片或传感器上,;
- ④实现LIS302DL三轴加速度传感器的X轴、Y轴、Z轴实时数据的获取;
❤️ ❤️ ❤️ ❤️ ❤️ ❤️