cc2530實現i2c資料線

來源:互聯網
上載者:User
本帖最後由 L.fish 於 2010-7-29 15:47 編輯


本人尊重原文作者,這篇文章非本人原創,feibit論壇是個不錯的論壇,希望大家多看看這個網站。

[註:本文源自www.feibit.com--“飛比”Zigbee論壇,如需轉載請保留此行]

近來為了做一個加速度感應器的項目,其中用到了無線模組

由於英明神武的老闆決定用ZigBee來做傳輸

結果就跑出了一些列的問題

其中一個就是MXC6202加速度感應器傳輸的資料用到了IIC協議

要用CC2430來做IIC的類比

因為摸過了一段時間的CC2430,知道其中還是51的核心

以為是很簡單的東西,應該和atmel的8051差不多的

但是做的時候又碰到了一系列的問題

最後繞了一圈才發現,哦,原來如此

2430晶片和51其中一個很大的區別就是:
必須人為的設定IO口的輸入輸出方向

也就是要設定每個連接埠的pin腳的PXDIR是1還是0


說還是太空泛了,那就上程式吧......


和51的程式相比,其實大部分還是相同的,我在這裡就主要講解一下兩者不同的地方

只能算作一個平台的移植吧....

來源程式會附在後面


SDA和SCL的讀寫

其實IIC匯流排協議的實現就是控制這兩根線,讓資料在規定的時候進行傳輸

其中就要最主要的就是對SCL的寫操作和SDA的讀寫


以下是i2c_1.c的來源程式,講解就穿插其中.....


//i2c_1.c

#include "ioCC2430.h"

#include "i2c.h"


#define TRUE 1

#define FALSE 0

/*我的管腳定義是

SDA定義為P1.5

SCL定義為P1.4 */

#define SCL P1_4

#define SDA P1_5


/*

一個nop就是一條機器指令周期 = 1/32MHz

那32個nop就是1us啦

----這裡是outman給我做出的講解,在此再作感謝

*/

void Delay_1u(unsigned int microSecs) {

  while(microSecs--)

  {

    /* 32 NOPs == 1 usecs */

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");

    asm("nop"); asm("nop");

  }

}


unsigned char error; /*錯誤提示,全域變數*/

    
/*

當通過CC2430的IO連接埠往外面寫資料的時候

必須將對應的IO連接埠資料方向設定為輸出

CC2430中DIRPX_Y為1時IO口為輸出功能

DIRPX_Y為0時IO口為輸入功能

我的SDA是P1.5,則SDA為輸出功能時

P1口DIR應該是0010 0000

即0x20,其他可以依次類推......

囉嗦完畢,繼續程式....

*/

    void WriteSDA1(void)//SDA 輸出1,相當於51裡面的SDA=1    {

         P1DIR |= 0x20;

         SDA = 1;

    }

    

    void WriteSDA0(void)//SDA 輸出0    {

         P1DIR |= 0x20;

         SDA = 0;

    }

    

    void WriteSCL1(void)//SCL 輸出1    {

         P1DIR |= 0x10;

         SCL = 1;

    }

    

    void WriteSCL0(void)//SCL 輸出1    {

         P1DIR |= 0x10;

         SCL = 0;

    }

    

    void ReadSDA(void)//這裡設定SDA對應IO口DIR可以接收資料    {

         P1DIR &= 0xDF;

    }


    /*啟動I2C匯流排的函數,當SCL為高電平時使SDA產生一個負跳變*/        

    void I2C_Start_1(void)

    {

        WriteSDA1();

        WriteSCL1();

        Delay_1u(50);

        WriteSDA0();

        Delay_1u(50);

        WriteSCL0();

        Delay_1u(50);

    }


    /*終止I2C匯流排,當SCL為高電平時使SDA產生一個正跳變*/

    void I2C_Stop_1(void)

    {

        WriteSDA0();

        Delay_1u(50);

        WriteSCL1();

        Delay_1u(50);

        WriteSDA1();

        Delay_1u(50);

        WriteSCL0();

        Delay_1u(50);

    }


    /*發送0,在SCL為高電平時使SDA訊號為低*/

    void SEND_0_1(void)   /* SEND ACK */

    {

        WriteSDA0();

        WriteSCL1();

        Delay_1u(50);

        WriteSCL0();

        Delay_1u(50);

    }


    /*發送1,在SCL為高電平時使SDA訊號為高*/

    void SEND_1_1(void)

    {

        WriteSDA1();

        WriteSCL1();

        Delay_1u(50);

        WriteSCL0();

        Delay_1u(50);

    }


   /*發送完一個位元組後檢驗裝置的應答訊號*/    

   char Check_Acknowledge_1(void)

    {

        WriteSDA1();

        WriteSCL1();

        Delay_1u(50);

        F0=SDA;

        Delay_1u(50);

        WriteSCL0();

        Delay_1u(50);

        if(F0==1)

            return FALSE;

        return TRUE;

    }

   

    void Write_Acknowledge_1(void)

    {

        WriteSDA0();   

        Delay_1u(50);

        WriteSCL1();   

        Delay_1u(50);

        WriteSCL0();   

        Delay_1u(50);

    }


    /*向I2C匯流排寫一個位元組*/

    void WriteI2CByte_1(char b)

    {

        char i;

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

        {

          if((b<<i)&0x80)

          {

             SEND_1_1();

          }

          else

          {

             SEND_0_1();

          }

        }

    }


    /*從I2C匯流排讀一個位元組*/

    char ReadI2CByte_1(void)

    {

        char b=0,i;

        WriteSDA1();


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

        {   

            WriteSCL0();

            Delay_1u(50);

            WriteSCL1(); 

            Delay_1u(50);


            ReadSDA();

            F0=SDA;//寄存器中的一位,用於儲存SDA中的一位元據


        if(F0==1)

            {

              b=b<<1;

              b=b|0x01;

            }

            else

              b=b<<1;

        }

        WriteSCL0();

        return b; 

    }


PS:

這裡沒有重要講解IIC的實現原理

比如什麼時候發送1,什麼時候發送0

這裡主要是講解了一下在移植過程中需要注意的問題

如果有什麼問題再問吧

整理一下需要注意的:
1.需要手動設定IO方向

2.延時設定的方式和晶振是有關係的,需要多長時間可以參照前面的程式

程式參考過robin's evolution的那篇用cc2430讀取AT24CXX的驅動程式文章

以及感謝群裡的on the way給我耐心講解51的IIC 

最後還是要感謝一下outman,謝謝你的提醒 

over

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.