新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > msp430單片機(jī)模擬IIC總線讀取MMA7660三軸加速度傳感器

msp430單片機(jī)模擬IIC總線讀取MMA7660三軸加速度傳感器

作者: 時(shí)間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
搞了幾天的msp430單片機(jī),發(fā)現(xiàn)它的硬件IIC并不是很好用(沒調(diào)出來,嘿嘿),所以就棄之不用了,改用模擬IIC總線的協(xié)議。用來讀取MMA7660三軸加速度按傳感器的X,Y,Z的值,并通過串口顯示出來,串口也是通過定時(shí)器TimerA模擬來的,只是為了練習(xí)一下單片機(jī)的編程所以都用了模擬。測試結(jié)果如下:
代碼如下:
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; //三軸加速度的最終值,有正負(fù)
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; //產(chǎn)生下降沿
delay_us(5);
SCL_0; //拉低時(shí)鐘線,準(zhǔn)備發(fā)送或者接收數(shù)據(jù)
}
void IIC_Stop()
{
SCL_1;
SDA_0;
delay_us(5);
SDA_1; //產(chǎn)生一個(gè)上升沿
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; //在接收模式下,設(shè)置SDA的方向?yàn)檩斎?/div>
SCL_1; //拉高時(shí)鐘線
delay_us(5); //延時(shí)
CY = SDA_in; //讀應(yīng)答信號
SCL_0 ; //拉低時(shí)鐘線
delay_us(5); //延時(shí)
SDA_DirOut; //接收結(jié)束的時(shí)候還要吧SDA的方向切換過來
return CY;
}
void IIC_WriteByte(unsigned int data)
{
unsigned char i ;
for (i=0;i<8;i++)
{
if((data&0x80)?1:0) //分別發(fā)送每一位二進(jìn)制數(shù)據(jù)
SDA_1;
else
SDA_0 ;
SCL_1;
data<<=1; //移位傳送下一位
delay_us(5);
SCL_0; //在SCL上升沿的時(shí)候加載一位的數(shù)據(jù)
delay_us (5);
}
SDA_1; //8位數(shù)據(jù)位發(fā)送完釋放數(shù)據(jù)總線,同時(shí)SDA拉高
// IIC_Recevie(); //接收答信號
}
unsigned char IIC_Read(void )
{
unsigned char i ,data=0;
SDA_DirIn; //在接收模式下,設(shè)置SDA的方向?yàn)檩斎?/div>
for (i=0;i<8;i++)
{
SCL_0;
delay_us(5);
SCL_1 ; //SCL下降沿期間有數(shù)據(jù),當(dāng)SCL為高時(shí)數(shù)據(jù)線上的數(shù)據(jù)才有效
data<<=1;
data|=SDA_in;
delay_us(3);
}
SDA_DirOut; //接收結(jié)束的時(shí)候還要吧SDA的方向切換過來
return data;
}
void WriteToAddr(unsigned char REG_addr, unsigned char REG_data )
{
IIC_Start();
IIC_WriteByte(SlaveAddress+0); //發(fā)送從機(jī)地址+寫入操作0
IIC_RecAck(); //應(yīng)答
IIC_WriteByte(REG_addr); //寫入內(nèi)部寄存器地址
IIC_WriteByte(REG_data); //寫入內(nèi)部寄存器數(shù)據(jù)
IIC_RecAck();
IIC_Stop();
delay_us(5);
}
unsigned char ReadFromAddr(unsigned char REG_addr)
{
unsigned char RecData ;
IIC_Start(); //啟動IIC總線
IIC_WriteByte(SlaveAddress+0); //寫入從機(jī)地址+寫命令0
IIC_WriteByte(REG_addr); //寫入要讀的內(nèi)部寄存器地址
IIC_Start();
IIC_WriteByte(SlaveAddress+1); //寫入從機(jī)地址+讀命令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);
//將采集到的數(shù)據(jù)轉(zhuǎn)換到-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);
}

上一頁 1 2 下一頁

評論


技術(shù)專區(qū)

關(guān)閉