本帖最后由 ltbytyn 于 2014-11-17 23:18 编辑
硬件部分:MSP430FR5969 Launchpad+430BOOST-SHARP96+ADXL345
ADXL345数字三轴重力加速度芯片,支持I2C\SPI两种接口,本设计中采用I2C接口。
MSP430FR5969事实上是有硬件I2C接口,但是与430BOOST-SHARP96连接后,I2C接口(P1.6/P1.7)被占用。只有P2.5\P2.6\P3.0可做他用,这三个脚均不支持硬件I2C,故使用IO模拟I2C。
I2C硬件连接
P2.6 <——————> SDA
P2.5 <——————> SCL
P3.0预留
- #define I2C_DIR P2DIR
- #define I2C_OUT P2OUT
- #define I2C_IN P2IN
- #define I2C_SCL 0x20 //SCL P2.5
- #define I2C_SDA 0x40 //SDA P2.6
- #define SDA_HIGH I2C_OUT |= I2C_SDA//SDA_HIGH
- #define SDA_LOW I2C_OUT &= ~I2C_SDA//SDA_LOW
- #define SCL_HIGH I2C_OUT |= I2C_SCL//SCL_HIGH
- #define SCL_LOW I2C_OUT &= ~I2C_SCL//SCL_LOW
- #define SET_SDA_IN I2C_DIR &= ~I2C_SDA //SET SDA IN
- #define SET_SDA_OUT I2C_DIR |= I2C_SDA //SET SDA OUT
- #define SDA_IN ( I2C_IN & I2C_SDA) //READ SDA DATA
- #define SlaveAddress 0xA6 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改
- //ALT ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
复制代码- /**************************************
- 起始信号
- **************************************/
- void ADXL345_Start(void)
- {
- SET_SDA_OUT;
- SDA_HIGH; //拉高数据线
- SCL_HIGH; //拉高时钟线
- Delay5us(); //延时
- SDA_LOW; //产生下降沿
- Delay5us(); //延时
- SCL_LOW; //拉低时钟线
- }
- /**************************************
- 停止信号
- **************************************/
- void ADXL345_Stop(void)
- {
- SET_SDA_OUT;
- SDA_LOW; //拉低数据线
- SCL_HIGH; //拉高时钟线
- Delay5us(); //延时
- SDA_HIGH; //产生上升沿
- Delay5us(); //延时
- }
- /**************************************
- 发送应答信号
- 入口参数:ack (0:ACK 1:NAK)
- **************************************/
- void ADXL345_SendACK(uchar ack)
- {
- SET_SDA_OUT;
- if(ack)
- SDA_HIGH; //写NACK应答信号
- else
- SDA_LOW; //写ACK应答信号
- SCL_HIGH; //拉高时钟线
- Delay5us(); //延时
- SCL_LOW; //拉低时钟线
- Delay5us(); //延时
- }
- /**************************************
- 接收应答信号
- **************************************/
- uchar ADXL345_RecvACK(void)
- {
- unsigned char ack;
- SCL_HIGH; //拉高时钟线
- SET_SDA_IN;
- Delay5us(); //延时
- ack = SDA_IN; //读应答信号
- SCL_LOW; //拉低时钟线
- Delay5us(); //延时
- return ack;
- }
- /**************************************
- 向IIC总线发送一个字节数据
- **************************************/
- void ADXL345_Senduchar(uchar dat)
- {
- uchar i,m;
- SET_SDA_OUT;
- for (i=8; i!=0; i--) //8位计数器
- {
- m=dat&0x80; //移出数据的最高位
- if(m==0x80)
- SDA_HIGH;
- else
- SDA_LOW;
- SCL_HIGH; //拉高时钟线
- Delay5us(); //延时
- SCL_LOW; //拉低时钟线
- dat=dat<<1;
- Delay5us(); //延时
- }
- ADXL345_RecvACK();
- }
- /**************************************
- 从IIC总线接收一个字节数据
- **************************************/
- uchar ADXL345_Recvuchar(void)
- {
- uchar i;
- uchar dat = 0;
- uchar m;
- SDA_HIGH; //使能内部上拉,准备读取数据,
- SET_SDA_IN;
- for (i=8; i!=0; i--) //8位计数器
- {
- dat <<= 1;
- SCL_HIGH; //拉高时钟线
- SET_SDA_IN;
- m = SDA_IN;
- if(m == I2C_SDA)
- dat = dat|0x01;
- Delay5us(); //延时
- SCL_LOW; //拉低时钟线
- Delay5us(); //延时
- }
- return dat;
- }
- //******单字节写入*******************************************
- void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
- {
- ADXL345_Start(); //起始信号
- ADXL345_Senduchar(SlaveAddress); //发送设备地址+写信号
- ADXL345_Senduchar(REG_Address); //内部寄存器地址,请参考中文pdf22页
- ADXL345_Senduchar(REG_data); //内部寄存器数据,请参考中文pdf22页
- ADXL345_Stop(); //发送停止信号
- }
- //********单字节读取*****************************************
- uchar Single_Read_ADXL345(uchar REG_Address)
- { uchar REG_data;
- ADXL345_Start(); //起始信号
- ADXL345_Senduchar(SlaveAddress); //发送设备地址+写信号
- ADXL345_Senduchar(REG_Address); //发送存储单元地址,从0开始
- ADXL345_Start(); //起始信号
- ADXL345_Senduchar(SlaveAddress+1); //发送设备地址+读信号
- REG_data=ADXL345_Recvuchar(); //读出寄存器数据
- ADXL345_SendACK(1);
- ADXL345_Stop(); //停止信号
- return REG_data;
- }
- //*********************************************************
- //
- //连续读出ADXL345内部加速度数据,地址范围0x32~0x37
- //
- //*********************************************************
- void Multiple_Read_ADXL345(void)
- {
- uchar i;
- ADXL345_Start(); //起始信号
- ADXL345_Senduchar(SlaveAddress); //发送设备地址+写信号
- ADXL345_Senduchar(0x32); //发送存储单元地址,从0x32开始
- ADXL345_Start(); //起始信号
- ADXL345_Senduchar(SlaveAddress+1); //发送设备地址+读信号
- for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF
- {
- BUF[i] = ADXL345_Recvuchar(); //BUF[0]存储0x32地址中的数据
- if (i == 5)
- {
- ADXL345_SendACK(1); //最后一个数据需要回NOACK
- }
- else
- {
- ADXL345_SendACK(0); //回应ACK
- }
- }
- ADXL345_Stop(); //停止信号
- for(i=0;i<3;i++)
- {
- Result = ((BUF[i*2+1]<<8) + BUF[i*2]);
- //if(Result<0)
- // Result = -Result;
- buffer[cnt][i] = (float)Result*3.9;
- }
- cnt++;
- if(cnt>99)
- cnt = 0;
- // read_i2c_flag = 0;
- Delay5ms();
- }
- //*****************************************************************
- //初始化ADXL345,根据需要请参考pdf进行修改************************
- void Init_ADXL345(void)
- {
- Single_Write_ADXL345(0x31,0x0B); //测量范围,正负16g,13位模式
- Single_Write_ADXL345(0x2C,0x08); //速率设定为12.5 参考pdf13页
- Single_Write_ADXL345(0x2D,0x08); //选择电源模式 参考pdf24页
- Single_Write_ADXL345(0x2E,0x80); //使能 DATA_READY 中断
- Single_Write_ADXL345(0x1E,0x00); //X 偏移量 根据测试传感器的状态写入pdf29页
- Single_Write_ADXL345(0x1F,0x00); //Y 偏移量 根据测试传感器的状态写入pdf29页
- Single_Write_ADXL345(0x20,0x05); //Z 偏移量 根据测试传感器的状态写入pdf29页
- }
复制代码
演示视频(先沿X轴方向改变,随后沿Y轴方向改变,最后改变Z轴):
ADXL345快速入门AN-1077_cn.pdf
(347.33 KB, 下载次数: 27)
ADXL345中文PDF.pdf
(874.7 KB, 下载次数: 31)
本例实现读取三轴加速度数据及显示,未考虑低功耗的应用。
430玩的就是低功耗。一切与低功耗无关的430设计都是失败的设计。所以针对目前的程序,后续会对其进行低功耗优化。