微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > msp430单片机模拟IIC总线读取MMA7660三轴加速度传感器

msp430单片机模拟IIC总线读取MMA7660三轴加速度传感器

时间:11-27 来源:互联网 点击:
搞了几天的msp430单片机,发现它的硬件IIC并不是很好用(没调出来,嘿嘿),所以就弃之不用了,改用模拟IIC总线的协议。用来读取MMA7660三轴加速度按传感器的X,Y,Z的值,并通过串口显示出来,串口也是通过定时器TimerA模拟来的,只是为了练习一下单片机的编程所以都用了模拟。测试结果如下:

代码如下:

file1 : main.c

#include "msp430G2452.h"

#include "g2452uart.h"

#include "MMA7660FC.h"

#define SDA_DirOut P2DIR |= BIT0

#define SDA_DirIn P2DIR &=~ BIT0

#define SDA_0 P2OUT &=~ BIT0

#define SDA_1 P2OUT |= BIT0

#define SCL_1 P2OUT |= BIT1

#define SCL_0 P2OUT &=~ BIT1

#define Get_Bit( x,y) ((x&(1

#define SDA_in Get_Bit(P2IN,0)

char X_value=0 ;

char Y_value=0 ;

char Z_value=0 ;

signed char X_value_final,Y_value_final,Z_value_final; //三轴加速度的最终值,有正负

void OSC_Init()

{

WDTCTL=WDTPW+WDTHOLD;//close whatchdog

if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)

{

while(1); // If calibration constants erased

// do not load, trap CPU!!

}

//1Mhz

BCSCTL1 = CALBC1_1MHZ; // Set range

DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation */

}

void Port_Init()

{

P2DIR |= BIT0+BIT1;

SDA_1;

SCL_1;

}

void delay_us( unsigned int k )

{

while(k--)

_nop();

}

void IIC_Start()

{

SDA_1;

SCL_1;

delay_us(5);

SDA_0; //产生下降沿

delay_us(5);

SCL_0; //拉低时钟线,准备发送或者接收数据

}

void IIC_Stop()

{

SCL_1;

SDA_0;

delay_us(5);

SDA_1; //产生一个上升沿

delay_us(5);

}

void IIC_SendAck()

{

SDA_0;

SCL_1;

delay_us(5);

SCL_0;

delay_us(5);

}

void IIC_SendNAck()

{

SDA_1;

SCL_1;

delay_us(5);

SCL_0;

delay_us(5);

}

unsigned char IIC_RecAck()

{

unsigned char CY ;

SDA_DirIn; //在接收模式下,设置SDA的方向为输入

SCL_1; //拉高时钟线

delay_us(5); //延时

CY = SDA_in; //读应答信号

SCL_0 ; //拉低时钟线

delay_us(5); //延时

SDA_DirOut; //接收结束的时候还要吧SDA的方向切换过来

return CY;

}

void IIC_WriteByte(unsigned int data)

{

unsigned char i ;

for (i=0;i<8;i++)

{

if((data&0x80)?1:0) //分别发送每一位二进制数据

SDA_1;

else

SDA_0 ;

SCL_1;

data<=1; //移位传送下一位

delay_us(5);

SCL_0; //在SCL上升沿的时候加载一位的数据

delay_us (5);

}

SDA_1; //8位数据位发送完释放数据总线,同时SDA拉高

// IIC_Recevie(); //接收答信号

}

unsigned char IIC_Read(void )

{

unsigned char i ,data=0;

SDA_DirIn; //在接收模式下,设置SDA的方向为输入

for (i=0;i<8;i++)

{

SCL_0;

delay_us(5);

SCL_1 ; //SCL下降沿期间有数据,当SCL为高时数据线上的数据才有效

data<=1;

data|=SDA_in;

delay_us(3);

}

SDA_DirOut; //接收结束的时候还要吧SDA的方向切换过来

return data;

}

void WriteToAddr(unsigned char REG_addr, unsigned char REG_data )

{

IIC_Start();

IIC_WriteByte(SlaveAddress+0); //发送从机地址+写入操作0

IIC_RecAck(); //应答

IIC_WriteByte(REG_addr); //写入内部寄存器地址

IIC_WriteByte(REG_data); //写入内部寄存器数据

IIC_RecAck();

IIC_Stop();

delay_us(5);

}

unsigned char ReadFromAddr(unsigned char REG_addr)

{

unsigned char RecData ;

IIC_Start(); //启动IIC总线

IIC_WriteByte(SlaveAddress+0); //写入从机地址+写命令0

IIC_WriteByte(REG_addr); //写入要读的内部寄存器地址

IIC_Start();

IIC_WriteByte(SlaveAddress+1); //写入从机地址+读命令1

RecData=IIC_Read();

IIC_SendNAck();

IIC_Stop();

return RecData;

}

void MMA7660_Init()

{

WriteToAddr(MMA7660_MODE,0x01);

}

void Read3axle(void)

{

X_value=ReadFromAddr(X_outAddr);

Y_value=ReadFromAddr(Y_outAddr);

Z_value=ReadFromAddr(X_outAddr);

//将采集到的数据转换到-32~31之间

X_value_final=(char)(X_value<2);

X_value_final =(char)(X_value_final /4);

Y_value_final= (char)(Y_value<2);

Y_value_final = (char)(Y_value_final /4);

Z_value_final= (char)(Z_value<2);

Z_value_final = (char)(Z_value_final /4);

}

//-----------主函数-----------------------------------------------------------

void main(void)

{

OSC_Init();

Port_Init();

TimerA_UART_init();

MMA7660_Init();

__enable_interrupt();

TimerA_UART_print("All Initialization is OK!rn");

for (;;)

{

//__bis_SR_register(LPM0_bits);

Read3axle();

if (X_value_final>0)

P1OUT|= BIT0;

else

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top