MSP430非模擬IIC總線(xiàn)控制程序

發(fā)布時(shí)間:2008-11-4 12:03    發(fā)布者:MSP430
關(guān)鍵詞: MSP430 , 控制程序 , 模擬 , 總線(xiàn)
對于MSP430的學(xué)習經(jīng)歷一個(gè)從痛苦到對430很有感情的轉變.當然開(kāi)始學(xué)習的時(shí)候那是相當惱火.網(wǎng)上也沒(méi)有什么很多的相關(guān)資料.就算有資料也是給不全.參考與學(xué)習都不很方便.經(jīng)過(guò)多方面的努力和找書(shū)再到對程序的仔細讀,感到非模擬的總線(xiàn)帶來(lái)的方便還是很多的. 下面就是程序和流程圖:



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 其硬件會(huì )自動(dòng)完成
SCL SDA的一系列時(shí)序 只要注意各個(gè)發(fā)送與接收的控制標志位.
******************************************/
#include
#include "IIC.h"
volatile unsigned char Data[6];
void main(void)
{
    //volatile unsigned char Data[6];
   
    //停止看門(mén)狗
    WDTCTL = WDTPW+WDTHOLD;
   
    //初始化端口
    Init_IIC_Port();
        
    //初始化時(shí)鐘
    Init_CLK();
    //I2C初始化
    Init_IIC();        //置傳輸方式及控制方式
   
    //打開(kāi)中斷
    _EINT();

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

    //讀出數據,隨機讀
    Data[0] = EEPROM_RandomRead(0x0000);    //地址自動(dòng)加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,
    //字節模式,時(shí)鐘源為SMCLK,
    //設置成傳輸模式
    I2CTCTL = I2CTRX + I2CSSEL_2;
    //定義從器件地址
    I2CSA = SLAVEADDR;
    //設置本身的地址
    I2COA = 0x01A5;              
    //I2C時(shí)鐘為SMCLK / 160
    I2CPSC = 159;
    //SCL 高電平為:5 *I2C 時(shí)鐘
    I2CSCLH = 0x03;  
    //SCL 低電平為:5 *I2C 時(shí)鐘
    I2CSCLL = 0x03;
    //I2C 模塊有效
    U0CTL |= I2CEN;
    tx_count = 0;
    rx_count = 0;
}

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

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

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

unsigned char EEPROM_CurrentAddressRead(void)
{
    //等待I2C模塊完成所有操作
    while (I2CDCTL&I2CBUSY);
    //讀操作的初始化
    I2CReadInit();
    //主(Master)模式
    U0CTL |= MST;
    //接收1個(gè)字節的數據
    I2CNDAT = 1;  
    //清除中斷標志
    I2CIFG &= ~ARDYIFG;
    //開(kāi)始接收,產(chǎn)生重新起始和停止條件
    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;
    //寫(xiě)操作初始化
    I2CWriteInit();
    //傳輸數據長(cháng)度
    //1個(gè)控制字節和一個(gè)地址數據
    I2CNDAT = 1;
    //清除中斷標志
    I2CIFG &= ~ARDYIFG;
    //起始條件產(chǎn)生
    I2CTCTL |= I2CSTT;
    //等待傳輸完成
    while ((~I2CIFG)&ARDYIFG);
    //讀操作初始化
    I2CReadInit();
    //接收一個(gè)字節的數據
    I2CNDAT = 1;
    //清除中斷標志
    I2CIFG &= ~ARDYIFG;
    //開(kāi)始接收,產(chǎn)生重新起始和停止條件
    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;
        //產(chǎn)生起始條件
        I2CTCTL |= I2CSTT;
      
        //等待I2CSTT被清除
        while (I2CTCTL & I2CSTT) ;
        //產(chǎn)生停止條件
        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        //上面的程序其實(shí)只要編寫(xiě) :

                  //#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:
        {
            //訪(fǎng)問(wèn)準備好中斷
            break;
        }
        case I2CIV_RXRDY:
        {
            //接收準備好中斷
            I2CBuffer[0]=I2CDRB;  
            break;
        }
        case I2CIV_TXRDY:
        {
            //發(fā)送準備好中斷
            I2CDRB = I2CBuffer[tx_count];
            tx_count = tx_count - 1;
            if (tx_count < 0)
            {
                //禁止發(fā)送中斷
                I2CIE &= ~TXRDYIE;
            }
            break;
        }            
        case I2CIV_GC:
        {
            //一般調用中斷
            break;
        }
        case I2CIV_STT:
        {
            //起始條件中斷
            break;
        }
    }
}
void Init_IIC_Port(void)
{
    //初始化端口寄存器         與IIC口無(wú)關(guān)的PX口關(guān)閉以便于對編寫(xiě)系統板的綜合程序.
    //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震蕩器開(kāi)啟
    //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的時(shí)鐘源為T(mén)X2CLK,分頻因子為1
    BCSCTL2 += SELM1;  
    //SMCLK的時(shí)鐘源為T(mén)X2CLK,分頻因子為1
    BCSCTL2 += SELS;     
}

//對于系統時(shí)鐘的選擇關(guān)系到整個(gè)程序運行穩定性.

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

上面的程序是經(jīng)過(guò)MSP430F1611的測試.程序的大部分來(lái)自單片機原理與應用>上,曾想自己從新開(kāi)發(fā)定義一個(gè),但想到網(wǎng)絡(luò )上沒(méi)有這個(gè)程序的完整版.我就修改了其中的幾個(gè)地方.一方面便于自己查看并復習也適于網(wǎng)絡(luò )上的朋友來(lái)討論交流.
本文地址:http://selenalain.com/thread-2879-1-1.html     【打印本頁(yè)】

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

相關(guān)在線(xiàn)工具

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復 返回頂部 返回列表
午夜高清国产拍精品福利|亚洲色精品88色婷婷七月丁香|91久久精品无码一区|99久久国语露脸精品|动漫卡通亚洲综合专区48页