国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

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://m.qingdxww.cn/thread-2879-1-1.html     【打印本頁】

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

廠商推薦

  • Microchip視頻專區
  • PIC32CM LS60 Curiosity Pro評估工具包
  • PIC32CK SG單片機——輕松滿足新型網絡安全要求
  • 實時控制解決方案的正確選擇——數字信號控制器(DSC)或通用MCU
  • dsPIC® DSC集成電機驅動器:非常適合在緊湊空間內進行實時控制
  • 貿澤電子(Mouser)專區

相關在線工具

相關視頻

關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩在线成人免费| 香蕉综合视频| 手机在线黄色网址| 青青操精品| 午夜精品久久久久久久第一页| 亚洲不卡| 日本黄色小视频在线观看| 亚洲精品在线影院| 欧美成人午夜免费福利785| 日本欧美大码a在线视频播放| 色噜噜 男人的天堂在线观看 | 天天国产视频| 欧美影视一区二区三区| 性a视频| 欧美日韩一| 青草视频免费看| 亚洲一区国产| 热re久久精品国产99热| 亚洲三级小视频| 色吧色吧| 无极色影院| 亚洲免费视频一区| 一级毛片一级毛片一级毛片aa| 色99色| 日韩小视频在线播放| 日韩一区视频在线| 欧美专区综合| 亚洲国产精品综合久久2007| 亚洲人成一区二区不卡| 亚洲男人的天堂2019| 日本一区二区三区四区公司 | 亚洲永久免费网站| 亚洲国产精品成人综合久久久| 亚洲国产91在线| 日本九九精品一区二区| 日韩亚洲欧美综合| 婷婷在线综合| 人人爱人人搞| 亚洲人6666成人观看| 一本伊在人香蕉线观新在线| 欧美理论片在线观看一区二区|