国产成人精品a视频一区www_国产区视频在线观看_99色视频_欲色av_亚洲一区电影_亚洲综合视频一区

PIC單片機之I2C(從模式)實例講解

來源:網絡

點擊:1714

A+ A-

所屬頻道:新聞中心

關鍵詞: PIC單片機,I2C

      網上有許多講解單片機實現I2C主模式,但是從模式的很少。我現在就來講講PIC單片機使用MSSP模塊實現I2C從模式。

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

      實例講解:我們模仿 AT24C02 EEPROM 的協議。讓一個主模式的單片機,來讀取從模式單片機的數據。

      下面為AT24C02的隨機地址讀取的協議。

      第一個字節 :輸入7位地址和一位的寫狀態位,

      第二個字節:然后寫入EEPROM數據地址,

      第三個字節:輸入7位地址和一位的讀狀態位,

      第四~N個字節:讀出的EEPROM的數據。

    PIC單片機之I2C(從模式)實例講解

      我們來講解下程序的基本思路:我們使能了MSSP中斷,即是I2C接收中斷,當PIC單片機接收到一個數據后就會產生中斷。那是接收到設備地址,還是接收到數據,由SSP1STAT寄存器的狀態位來判斷。

      需要判斷的狀態位分別是 :

      數據和地址: 用來判斷接收到是地址還是數據

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

      讀寫: 用來判斷是寫狀態還是讀狀態。

      緩存滿: 用來判斷緩沖區是否滿

      我們以隨機地址讀取為例:講講程序執行的過程

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

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

    PIC單片機之I2C(從模式)實例講解

      我們以寫字節數據為例:

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

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

      初始化設置:

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

      TRISB6 = input;

      TRISB4 = input;

      2,將MSSP設置為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,設置從設備地址為 0xA0

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

      5,開啟I2C

      SSP1CONbits.SSPEN=1;//enable I2c

      6,清楚狀態標志

      SSPSTAT=0;

      7,使能I2C中斷

      PIE1bits.SSP1IE = 1;//Enabe interrupt MSSP

      INTCONbits.PEIE = 1;

      INTCONbits.GIE = 1;

      如果你要使用PIC單片機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;

      }

      }

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

      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;

      }

      }

      }
     

    (審核編輯: 智匯李)

    聲明:除特別說明之外,新聞內容及圖片均來自網絡及各大主流媒體。版權歸原作者所有。如認為內容侵權,請聯系我們刪除。

    主站蜘蛛池模板: 国内精品成人 | 日本色综合 | 99国产视频 | 久久三区 | 亚洲免费成人 | 99福利| 曰本人做爰大片免费观看 | 午夜在线电影 | 国产日产久久久久久 | 久久精品国产99国产 | 青草青草久热精品视频在线观看 | 免费一区二区三区 | 日韩精品免费看 | 久久久网| 日韩欧美中文 | 欧美成人a交片免费看 | 国产综合精品一区二区三区 | 日韩成人在线一区 | 欧美视频区 | 国产精品久久毛片 | 黄色网址视频在线观看 | 国产精品国产 | 国产99久久精品一区二区永久免费 | 欧美久久影视 | 国产精品无码久久久久 | 亚洲欧美一区二区三区在线 | 日韩av在线电影 | 亚洲精品久久一区二区三区 | av电影天堂网| 欧美性受| 欧美性生活免费 | 亚洲一区电影 | 国产激情视频在线 | 日韩在线观看不卡 | 久久久久久久一区 | 在线观看黄 | 午夜视频在线观看网站 | 亚洲嫩草 | 亚洲蜜桃精久久久久久久 | 久久另类ts人妖一区二区 | 天堂在线视频 |