日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PIC单片机 IIC通信及实现

發布時間:2025/4/5 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PIC单片机 IIC通信及实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
IIC通信

??IIC是一種只需要2根數據線就可以實現數據通信的總線式結構。IIC采用主從式通信方式,通信過程完全由主設備決定。完整的通信流程是主設備發送起始信號給從設備,再發送地址來選中從設備,然后就可以開始進行數據傳輸,當傳輸結束后由主設備發送結束信號告知從設備通信結束。

(示例代碼中,PORTA為所用單片機的8位引腳對應的寄存器名稱,采用PORTA<7>作為數據位SDA、PORTA<6>作為時鐘位SCL)

起始信號

??起始信號由兩個下降沿組成,SDA信號先從1置0,然后SCL再從1置0,由此告知從設備要開始通信了。代碼如下:

/************************************************************* 啟動總線函數 函數原型: void start_i2c(); Function: start on the I2C bus *************************************************************/ void start_i2c() {PORTA |= 0b10000000; //SDA=1,發送啟始條件的數據信號delay_10us();PORTA |= 0b01000000; //SCL=1delay_10us();PORTA &= 0b01111111; //SDA=0,發送起始信號delay_10us();PORTA &= 0b10111111; //SCL=0,鉗住I2C總線,準備發送數據或接收數據delay_10us(); }

?

終止信號

??起始信號由兩個上升沿,SCL信號先從0置1,然后SDA再從0置1,由此告知從設備要結束通信。代碼如下:

/************************************************************* 停止總線函數 函數原型: void stop_i2c(); Function: stop the I2C bus **************************************************************/ void stop_i2c() {PORTA &= 0b01111111; //SDA=0,發送結束條件的數據信號delay_10us();PORTA |= 0b01000000; //SCL=1delay_10us();PORTA |= 0b10000000; //SDA=1delay_10us(); }

?

發送8位數據

??無論發送地址還是數據,都是通過相同方式一位一位地發送,并且要從高位開始。首先是將時鐘線SCL置0,意味著數據線SDA要開始準備信息來發送。

??在每一位數據發送前時鐘線都要有一段低電平。當數據線SDA置為要發送的電平后SCl置1,從設備讀取此時SDA電平值作為一個bit,隨后SCL置0,SDA置為下一個待發送位,重復上述步驟,循環8次即完成一次8bit數據傳輸。

/*==================================================== 字節數據傳送函數 函數原型: void send_byte(uchar c); Function: 將數據C發送出去,可以是地址,也可以是數據,發完后等待回應,并對此狀態 位進行操作(不應答或非應答都使ack=0 ),發送數據正常,ack=1;ack=0 表示被控器無應答或損壞。 ====================================================*/ void send_byte(uint8_t c) {uint8_t bit_count;for (bit_count = 0; bit_count < 8; bit_count++){if (c & 0x80){PORTA |= 0b10000000; //SDA=1}else{PORTA &= 0b01111111; //SDA=0}delay_10us();PORTA |= 0b01000000; //SCL=1delay_10us();PORTA &= 0b10111111; //SCL=0c <<= 1;delay_10us();} }

?

等待應答

??為了確保從設備收到了主設備發送來的數據,每次發送后主設備都要等待從設備回復ACK信號才能進行后續通話。

??在等待ACK的過程中,主設備要先釋放總線SDA,將總線權限交給從設備,即SDA置1。后續如果檢測到SDA被置0了就說明從設備答復了ACK信號。

/*==================================================== 等待從設備應答函數 函數原型: void wait_ack(); Function: 等待從設備對主設備發送行為的應答 ====================================================*/ uint8_t wait_ack() {uint8_t re = 0;PORTA |= 0b10000000; //SDA=1,釋放總線,將總線權限交給從設備delay_10us();PORTA |= 0b01000000; //SCL=1TRISA = 0b10000000;delay_10us();if ((PORTA & 0b10000000) == 0){re = 1; //ACK}else{re = 0; //NACK}TRISA &= 0b01111111;PORTA &= 0b10111111; //SCL=0delay_10us();return re; }

?

發送ACK

??主設備發送完數據需要從設備答復ACK信號,而從設備發送給主設備數據后同樣需要主設備給其答復ACK信號以確保收到。

/*==================================================== 給從設備發送應答函數 函數原型: void wait_ack(); Function: 給從設備對主設備發送成功接收的應答 ====================================================*/ void send_ack() {PORTA &= 0b01111111; //SDA=0;delay_10us();PORTA |= 0b01000000; //SCL=1delay_10us();PORTA &= 0b10111111; //SCL=0delay_10us(); }

?

接收8位數據

??與發送數據時相同,SCL置1表示讀取此時SDA電平值作為一個bit,循環8次得到8位數據值。

/*================================================ 字節數據接收函數 函數原型:uchar receive_byte(); FUNCTION: 用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號), 發完后請用應答函數。 ====================================================*/ uint8_t receive_byte() {uint8_t retc = 0;PORTA |= 0b10000000; //SDA=1,釋放總線,將總線權限交給從設備TRISA |= 0b10000000;delay_10us();uint8_t bit_count;for (bit_count = 0; bit_count < 8; bit_count++){retc = retc * 2; //retc<<1PORTA &= 0b10111111; //SCL=0delay_10us();PORTA |= 0b01000000; //SCL=1delay_10us();if (PORTA & 0b10000000){retc++;}delay_10us();}TRISA &= 0b01111111;PORTA &= 0b10111111; //SCL=0delay_10us();return (retc); }

?

通話總程序

??開啟通信——>等待應答——>發送地址和傳輸方向(前7bit為地址,后1bit表示數據方向)——>發送傳感器器件配置信息——>等待應答——>再次開啟通信——>發送地址和傳輸方向——>等待應答——>接收數據——>回復ACK——>結束通信

/*==================================================== IIC通話函數 函數原型: void iic_sensor(void); Function: 以IIC協議與溫度傳感器進行通話,獲取溫度數據 ====================================================*/ void iic_sensor() {start_i2c();send_byte(0b10010010); //發送地址值,并且設置為輸入wait_ack();send_byte(0x00); //發送配置信息wait_ack();start_i2c();send_byte(0b10010011); //發送地址值,并且設置為輸出wait_ack();temp[1] = receive_byte();send_ack();temp[0] = receive_byte();send_ack();stop_i2c(); //通話結束 }

總結

以上是生活随笔為你收集整理的PIC单片机 IIC通信及实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。