<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • MSP430非模擬IIC總線控制程序

    發布時間:2008-11-4 12:03    發布者:MSP430
    關鍵詞: MSP430 , 控制程序 , 模擬 , 總線
    對于MSP430的學習經歷一個從痛苦到對430很有感情的轉變.當然開始學習的時候那是相當惱火.網上也沒有什么很多的相關資料.就算有資料也是給不全.參考與學習都不很方便.經過多方面的努力和找書再到對程序的仔細讀,感到非模擬的總線帶來的方便還是很多的. 下面就是程序和流程圖:



    IIC.h

    void Init_IIC(void);
    void EEPROM_ByteWrite(unsigned char nAddr,unsigned char nVal);
    unsigned char EEPROM_RandomRead(unsigned char nAddr);
    unsigned char EEPROM_CurrentAddressRead(void);
    void EEPROM_AckPolling(void);
    void Init_CLK(void);
    void Init_IIC_Port(void);

    Main.C

    /*******************************************
                  IIC for AT24c16   OR AT24CXXX 系列
          
    只要控制好IICRM IICSTP IICSTT 其硬件會自動完成
    SCL SDA的一系列時序 只要注意各個發送與接收的控制標志位.
    ******************************************/
    #include
    #include "IIC.h"
    volatile unsigned char Data[6];
    void main(void)
    {
        //volatile unsigned char Data[6];
       
        //停止看門狗
        WDTCTL = WDTPW+WDTHOLD;
       
        //初始化端口
        Init_IIC_Port();
            
        //初始化時鐘
        Init_CLK();
        //I2C初始化
        Init_IIC();        //置傳輸方式及控制方式
       
        //打開中斷
        _EINT();

        //寫入數據
        EEPROM_ByteWrite(0x0000,0x12);
        //等待寫操作完成
        EEPROM_AckPolling();
        //寫入數據
        EEPROM_ByteWrite(0x0001,0x34);
        //等待寫操作完成
        EEPROM_AckPolling();
        //寫入數據
        EEPROM_ByteWrite(0x0002,0x56);
        //等待寫操作完成
        EEPROM_AckPolling();
        //寫入數據
        EEPROM_ByteWrite(0x0003,0x78);
        //等待寫操作完成
        EEPROM_AckPolling();  
        //寫入數據
        EEPROM_ByteWrite(0x0004,0x9A);
        //等待寫操作完成
        EEPROM_AckPolling();
        //寫入數據
        EEPROM_ByteWrite(0x0005,0xBC);
        //等待寫操作完成
        EEPROM_AckPolling();         

        //讀出數據,隨機讀
        Data[0] = EEPROM_RandomRead(0x0000);    //地址自動加1
        //讀出數據,當前地址讀
        Data[1] = EEPROM_CurrentAddressRead();
        //讀出數據,當前地址讀
        Data[2] = EEPROM_CurrentAddressRead();
        //讀出數據,當前地址讀
        Data[3] = EEPROM_CurrentAddressRead();
        //讀出數據,當前地址讀
        Data[4] = EEPROM_CurrentAddressRead();
        //讀出數據,當前地址讀
        Data[5] = EEPROM_CurrentAddressRead();
    }

    IIC.C

    #include
    #include "IIC.h"

    #define SLAVEADDR   0x50;

    int tx_count;
    int rx_count;
    unsigned char I2CBuffer[3];
    void Init_IIC(void)
    {
        //將P3.1和P3.3設置為I2C管腳
        P3SEL = 0x0A;
        //設置P3.1和P3.3管腳的方向
        P3DIR &= ~0x0A;
         //選擇為I2C模式
        U0CTL |= I2C + SYNC;
        //禁止I2C模塊
        U0CTL &= ~I2CEN;     
       //設置I2C為7位地址模式,不使用DMA,
        //字節模式,時鐘源為SMCLK,
        //設置成傳輸模式
        I2CTCTL = I2CTRX + I2CSSEL_2;
        //定義從器件地址
        I2CSA = SLAVEADDR;
        //設置本身的地址
        I2COA = 0x01A5;              
        //I2C時鐘為SMCLK / 160
        I2CPSC = 159;
        //SCL 高電平為:5 *I2C 時鐘
        I2CSCLH = 0x03;  
        //SCL 低電平為:5 *I2C 時鐘
        I2CSCLL = 0x03;
        //I2C 模塊有效
        U0CTL |= I2CEN;
        tx_count = 0;
        rx_count = 0;
    }

    void I2CWriteInit(void)       //對于AT24CXXX的寫操作是置成主模式并置位中斷使能.
    {
        //主(Master)模式
        U0CTL |= MST;  
        //傳輸模式,R/W 為:0
        I2CTCTL |= I2CTRX;   
        //清除中斷標志
        I2CIFG &= ~TXRDYIFG;
        //發送中斷使能
        I2CIE = TXRDYIE;
    }

    void I2CReadInit(void)
    {
        //接收模式,R/W 為:1
        I2CTCTL &= ~I2CTRX;
        //接收中斷使能
        I2CIE = RXRDYIE;
    }

    void EEPROM_ByteWrite(unsigned char nAddr, unsigned char nVal)
    {
        //等待I2C模塊完成所有操作         //在選定的地址寫入數據.
        while (I2CDCTL&I2CBUSY) ;
        //設置地址數據
        I2CBuffer[1] = nAddr;
        //設置數據
        I2CBuffer[0] = nVal;
        //設置緩沖區指針
        tx_count = 1;
        //寫數據初始化
        I2CWriteInit();                          //設置為主模式
        //發送數據的長度
        //1個控制字節,2個數據字節
        I2CNDAT = 2;                           
        //開始和停止條件產生
        //開始I2C通信
        I2CTCTL |= I2CSTT+I2CSTP;
        return;
    }

    unsigned char EEPROM_CurrentAddressRead(void)
    {
        //等待I2C模塊完成所有操作
        while (I2CDCTL&I2CBUSY);
        //讀操作的初始化
        I2CReadInit();
        //主(Master)模式
        U0CTL |= MST;
        //接收1個字節的數據
        I2CNDAT = 1;  
        //清除中斷標志
        I2CIFG &= ~ARDYIFG;
        //開始接收,產生重新起始和停止條件
        I2CTCTL |= I2CSTT + I2CSTP;
        //等待傳輸完成
        while ((~I2CIFG)&ARDYIFG) ;
        //返回數據
        return I2CBuffer[0];
    }

    unsigned char EEPROM_RandomRead(unsigned char nAddr)
    {
        //等待I2C模塊完成所有操作
        while (I2CDCTL&I2CBUSY);
        //設置地址
        I2CBuffer[0] = nAddr;
        //設置緩沖區指針
        tx_count = 0;
        //寫操作初始化
        I2CWriteInit();
        //傳輸數據長度
        //1個控制字節和一個地址數據
        I2CNDAT = 1;
        //清除中斷標志
        I2CIFG &= ~ARDYIFG;
        //起始條件產生
        I2CTCTL |= I2CSTT;
        //等待傳輸完成
        while ((~I2CIFG)&ARDYIFG);
        //讀操作初始化
        I2CReadInit();
        //接收一個字節的數據
        I2CNDAT = 1;
        //清除中斷標志
        I2CIFG &= ~ARDYIFG;
        //開始接收,產生重新起始和停止條件
        I2CTCTL |= I2CSTT + I2CSTP;  
        //等待傳輸完成
        while ((~I2CIFG)&ARDYIFG);
        //返回數據
        return I2CBuffer[0];
    }

    void EEPROM_AckPolling(void)
    {
        unsigned int count;
        //等待I2C模塊完成所有操作
        while (I2CDCTL&I2CBUSY);
      
        count=0;
        //清除I2CEN位
        U0CTL &= ~I2CEN;
        I2CTCTL |= I2CRM;  
        //使能I2C模塊
        U0CTL |= I2CEN;
        //設置NACKIFG標志
        I2CIFG = NACKIFG;
        while (NACKIFG & I2CIFG)
        {
            //清除中斷標志
            I2CIFG=0x00;
            //主(Master)模式
            U0CTL |= MST;
            //設置傳輸模式
            I2CTCTL |= I2CTRX;
            //產生起始條件
            I2CTCTL |= I2CSTT;
          
            //等待I2CSTT被清除
            while (I2CTCTL & I2CSTT) ;
            //產生停止條件
            I2CTCTL |= I2CSTP;
            //等待停止條件復位
            while (I2CDCTL & I2CBUSY) ;
            count = count + 1;
        }
       
        //清除I2CEN位
        U0CTL &= ~I2CEN;
        I2CTCTL &= ~I2CRM;
        //使能I2C
        U0CTL |= I2CEN;

        return;
    }

    #if __VER__ < 200
        interrupt [USART0TX_VECTOR] void ISR_I2C(void)
    #else
        #pragma vector=USART0TX_VECTOR
        __interrupt void ISR_I2C(void)
    #endif        //上面的程序其實只要編寫 :

                      //#pragma vector=USART0TX_VECTOR   __interrupt void ISR_I2C(void)就行.
    {
        switch (I2CIV)
        {
            case I2CIV_AL:
            {
                //仲裁中斷
                break;
            }
            case I2CIV_NACK:  
            {
                //NACK中斷
                break;
            }
            case I2CIV_OA:
            {
                //自己地址中斷
                break;
            }
            case I2CIV_ARDY:
            {
                //訪問準備好中斷
                break;
            }
            case I2CIV_RXRDY:
            {
                //接收準備好中斷
                I2CBuffer[0]=I2CDRB;  
                break;
            }
            case I2CIV_TXRDY:
            {
                //發送準備好中斷
                I2CDRB = I2CBuffer[tx_count];
                tx_count = tx_count - 1;
                if (tx_count < 0)
                {
                    //禁止發送中斷
                    I2CIE &= ~TXRDYIE;
                }
                break;
            }            
            case I2CIV_GC:
            {
                //一般調用中斷
                break;
            }
            case I2CIV_STT:
            {
                //起始條件中斷
                break;
            }
        }
    }
    void Init_IIC_Port(void)
    {
        //初始化端口寄存器         與IIC口無關的PX口關閉以便于對編寫系統板的綜合程序.
        //P1DIR = 0xFF;
        //P2DIR = 0xFF;
        P3DIR = 0xF5;
        //P4DIR = 0xFF;
        P5DIR = 0x7F;
        //P6DIR = 0xFF;
        //P4OUT = 0X11;
        //P5OUT &= 0XF0;
        P3SEL|=BIT1+BIT3;     //在這里如果設置成
       
    }
    void Init_CLK(void)
    {
        unsigned int i;
        //將寄存器的內容清零
        //XT2震蕩器開啟
        //LFTX1工作在低頻模式
        //ACLK的分頻因子為1
        BCSCTL1 = 0X00;      
        do
        {
            // 清除OSCFault標志
    IFG1 &= ~OFIFG;                     
    for (i = 0x20; i > 0; i--);               
        }
        while ((IFG1 & OFIFG) == OFIFG);      // 如果OSCFault =1  
       
        //open XT2, LFTX2 選擇低頻率
        BCSCTL1 &= ~(XT2OFF + XTS);      //BCSCTL1=0X00   功能一樣
        //DCO Rsel=7(Freq=3200k/25攝氏度)
        BCSCTL1 |= RSEL0 + RSEL1 + RSEL2;
        BCSCTL1 |= 0x07;
        //MCLK的時鐘源為TX2CLK,分頻因子為1
        BCSCTL2 += SELM1;  
        //SMCLK的時鐘源為TX2CLK,分頻因子為1
        BCSCTL2 += SELS;     
    }

    //對于系統時鐘的選擇關系到整個程序運行穩定性.

    看到很多賣開發板的人將IIC硬件寫上去后再去搞個模擬的IIC總線程序. 感覺到有點說不出的感覺. 其實430的IIC不是專用來外擴展FLASH的,而是用來和一些特殊的電路連接,實現功能. 對于MSP430147~149 15X 16X 的芯片內部有48~60K的Flash了還有必要來個模擬的IIC總線時序么.裝個UCOS都可以了.開發板要做的事情就是如何做好非模擬IIC程序的設計.更不是為了和C1搞比拼搶占市場.

    上面的程序是經過MSP430F1611的測試.程序的大部分來自單片機原理與應用>上,曾想自己從新開發定義一個,但想到網絡上沒有這個程序的完整版.我就修改了其中的幾個地方.一方面便于自己查看并復習也適于網絡上的朋友來討論交流.
    本文地址:http://www.portaltwn.com/thread-2879-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • Dev Tool Bits——使用MPLAB® Discover瀏覽資源
    • Dev Tool Bits——使用條件軟件斷點宏來節省時間和空間
    • Dev Tool Bits——使用DVRT協議查看項目中的數據
    • Dev Tool Bits——使用MPLAB® Data Visualizer進行功率監視
    • 貿澤電子(Mouser)專區

    相關在線工具

    相關視頻

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷