新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > msp430單片機模擬IIC總線讀取MMA7660三軸加速度傳感器

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

        作者: 時間:2016-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);
        }

        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 理塘县| 宿州市| 安庆市| 泰来县| 通江县| 兴宁市| 龙门县| 旬阳县| 娄烦县| 自贡市| 沁水县| 五原县| 沈丘县| 洪洞县| 长垣县| 阳高县| 霍林郭勒市| 固原市| 溧水县| 铜鼓县| 平和县| 靖宇县| 迁西县| 五家渠市| 西青区| 于田县| 惠来县| 长海县| 宣威市| 宁波市| 耿马| 岳阳县| 汉沽区| 龙海市| 小金县| 稷山县| 华容县| 洪雅县| 马龙县| 崇文区| 兴城市|