免费色播,亚洲国产欧美国产第一区二区三区,毛片看,日本精品在线观看视频,国产成人精品一区二区免费视频,日本黄色免费网站,一级毛片免费

PIC單片機(jī)之I2C(從模式)實(shí)例講解

來源:網(wǎng)絡(luò)

點(diǎn)擊:1604

A+ A-

所屬頻道:新聞中心

關(guān)鍵詞: PIC單片機(jī),I2C

      網(wǎng)上有許多講解單片機(jī)實(shí)現(xiàn)I2C主模式,但是從模式的很少。我現(xiàn)在就來講講PIC單片機(jī)使用MSSP模塊實(shí)現(xiàn)I2C從模式。

      有關(guān)I2C協(xié)議的具體介紹可以看 《PIC單片機(jī)之I2C(主模式)》,我們這里直接講解實(shí)例

      實(shí)例講解:我們模仿 AT24C02 EEPROM 的協(xié)議。讓一個主模式的單片機(jī),來讀取從模式單片機(jī)的數(shù)據(jù)。

      下面為AT24C02的隨機(jī)地址讀取的協(xié)議。

      第一個字節(jié) :輸入7位地址和一位的寫狀態(tài)位,

      第二個字節(jié):然后寫入EEPROM數(shù)據(jù)地址,

      第三個字節(jié):輸入7位地址和一位的讀狀態(tài)位,

      第四~N個字節(jié):讀出的EEPROM的數(shù)據(jù)。

    PIC單片機(jī)之I2C(從模式)實(shí)例講解

      我們來講解下程序的基本思路:我們使能了MSSP中斷,即是I2C接收中斷,當(dāng)PIC單片機(jī)接收到一個數(shù)據(jù)后就會產(chǎn)生中斷。那是接收到設(shè)備地址,還是接收到數(shù)據(jù),由SSP1STAT寄存器的狀態(tài)位來判斷。

      需要判斷的狀態(tài)位分別是 :

      數(shù)據(jù)和地址: 用來判斷接收到是地址還是數(shù)據(jù)

      啟動位: 用來判斷是否接收到啟動位

      讀寫: 用來判斷是寫狀態(tài)還是讀狀態(tài)。

      緩存滿: 用來判斷緩沖區(qū)是否滿

      我們以隨機(jī)地址讀取為例:講講程序執(zhí)行的過程

      1,從單片機(jī)接收到啟示位和設(shè)備地址中斷:我們判斷SSP1STAT的狀態(tài)位為(寫狀態(tài),地址,緩存滿,接收到啟示位) 然后讀取緩存中的設(shè)備地址, 接著在讀取 需要讀/寫的數(shù)據(jù)地址。

      2,單片機(jī)再次接收到設(shè)備地址:我們判斷是SSP1STAT的狀態(tài)為(讀狀態(tài))然后從設(shè)備就輸出數(shù)據(jù)

    PIC單片機(jī)之I2C(從模式)實(shí)例講解

      我們以寫字節(jié)數(shù)據(jù)為例:

      1,從單片機(jī)接收到啟示位和設(shè)備地址中斷:我們判斷SSP1STAT的狀態(tài)位為(寫狀態(tài),地址,緩存滿,接收到啟示位) 然后讀取緩存中的設(shè)備地址, 接著在讀取 需要讀/寫的數(shù)據(jù)地址。

      2,單片機(jī)判斷SSP1STAT的狀態(tài)位為(寫狀態(tài),數(shù)據(jù),緩存滿)那么單片機(jī)就接收輸入的數(shù)據(jù)。

      初始化設(shè)置:

      1,設(shè)置I2C通信的兩引腳為CLK SCL為輸入,

      TRISB6 = input;

      TRISB4 = input;

      2,將MSSP設(shè)置為I2C從模式,七位從地址

      SSP1CONbits.SSPM0 = 0;

      SSP1CONbits.SSPM1 = 1;

      SSP1CONbits.SSPM2 = 1;

      SSP1CONbits.SSPM3 = 0;// I2C slave mode ,7bit address

      3,使能CLK時鐘

      SSP1CONbits.CKP = 1; // enable clock

      4,設(shè)置從設(shè)備地址為 0xA0

      SSP1ADD =0xA0; //slave address is 0xa0

      5,開啟I2C

      SSP1CONbits.SSPEN=1;//enable I2c

      6,清楚狀態(tài)標(biāo)志

      SSPSTAT=0;

      7,使能I2C中斷

      PIE1bits.SSP1IE = 1;//Enabe interrupt MSSP

      INTCONbits.PEIE = 1;

      INTCONbits.GIE = 1;

      如果你要使用PIC單片機(jī)I2C從模式只要使用下面的代碼:

      將void i2c_salve_interrupt_tx();void i2c_salve_interrupt_rx();放到中斷程序中,如下:

      void interrupt isr(void)

      {

      if(SSP1IE && SSP1IF)

      {

      i2c_salve_interrupt_tx();

      i2c_salve_interrupt_rx();

      SSP1IF=0;

      }

      }

      將初始化函數(shù)init_i2c_slave();放到主函數(shù)中

      void main()

      {

      init_i2c_slave();

      }

      頭文件 :i2c_salve.h

      #ifndef _I2C_SALVE_H

      #define _I2C_SALVE_H

      void init_i2c_slave();

      void i2c_salve_interrupt_tx();

      void i2c_salve_interrupt_rx();

      #endif

      代碼:i2c_salve.c

      #include ;

      #define input 1

      #define RX_BUF_LEN 29

      #define while_delay 6000

      unsigned char i2c_address,word_address,Register[29];

      unsigned char RANDOM_READ,i2c_counter;

      extern unsigned char A_readflag;

      /*I2C SALVE */

      void init_i2c_slave()

      {

      TRISB6 = input;

      TRISB4 = input;

      SSP1CONbits.SSPM0 = 0;

      SSP1CONbits.SSPM1 = 1;

      SSP1CONbits.SSPM2 = 1;

      SSP1CONbits.SSPM3 = 0;// I2C slave mode ,7bit address

      SSP1CONbits.CKP = 1; // enable clock

      SSP1ADD =0xA0; //slave address is 0xa0

      SSP1CONbits.SSPEN=1;//enable I2c

      SSPSTAT=0;

      PIE1bits.SSP1IE = 1;//Enabe interrupt MSSP

      INTCONbits.PEIE = 1;

      INTCONbits.GIE = 1;

      }

      /*I2C salve mode interrupt */

      void i2c_salve_interrupt_tx()//master read

      {

      unsigned char Temp;

      unsigned int timercounter;

      Temp=SSP1STAT;

      Temp &= 0x2D;

      if(SSP1STATbits.R_nW ==1)//Read operation.

      {

      A_readflag=0;

      SSP1IF = 0;

      i2c_address = SSP1BUF;

      i2c_counter = word_address;

      while(i2c_counter < RX_BUF_LEN)

      {

      SSP1BUF=Register[i2c_counter];//send data

      SSP1CONbits.CKP=1;// enable colck

      timercounter=while_delay;

      while(PIR1bits.SSP1IF == 0)

      {

      timercounter--;

      if(timercounter==0)

      {

      return;

      }

      }//waiting for ~ACK

      SSP1IF = 0;

      if(SSP1CON2bits.ACKSTAT == 1)

      {

      return ; //NOACK

      }

      else

      {

      i2c_counter++;//ACK

      }

      }

      SSP1IF = 0;

      }

      }

      void i2c_salve_interrupt_rx()//master writer

      {

      unsigned char rx_status;

      unsigned char Temp;

      unsigned int timercounter;

      rx_status=false;

      Temp=SSP1STAT;

      Temp &= 0x2D;

      if(Temp==0x09)//Write operation,last byte was an address,buffer is full

      {

      SSP1IF = 0;

      i2c_address = SSP1BUF;

      timercounter=while_delay;

      while(PIR1bits.SSP1IF == 0)

      {

      timercounter--;

      if(timercounter==0)

      {

      return ;

      }

      }//waiting for send ~ACK

      SSP1IF = 0;

      word_address = SSP1BUF;

      return ;

      }

      if(Temp==0x29)//Write operation,last byte was data,buffer is full

      {

      SSP1IF=0;

      Register[word_address]=SSP1BUF;

      word_address++;

      if(word_address>=RX_BUF_LEN)

      {

      word_address=0;

      }

      }

      }
     

    (審核編輯: 智匯李)

    聲明:除特別說明之外,新聞內(nèi)容及圖片均來自網(wǎng)絡(luò)及各大主流媒體。版權(quán)歸原作者所有。如認(rèn)為內(nèi)容侵權(quán),請聯(lián)系我們刪除。