找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1675|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

關(guān)于51單片機(jī)模擬串行通信協(xié)議波形的探討

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
本帖最后由 Kituro 于 2022-1-25 01:17 編輯


  1. void I2C_SendOneByte(unsigned char TxValue)
  2. {
  3.         
  4.     unsigned char i, k;

  5.     for(i=0; i<8; i++)
  6.     {
  7.         TxValue <<= 1;               //Data is transferred with MSB first.
  8.         k = CY;
  9.         SDA = k;                         //If MSB is 1, the Carry Flag (CY) will be set to 1 after left logical shift, and vice versa.
  10.         delay();
  11.         SCL = 1;
  12.         delay();  
  13.         SCL = 0;
  14.     }
  15. }
復(fù)制代碼
使用以上程序發(fā)送數(shù)據(jù), 波形如下:(端口懸空未連接設(shè)備, 探頭衰減10X)
單片機(jī)型號STC8A8K64S4A12, 輸出為準(zhǔn)雙向口(傳統(tǒng)8051模式),啟用內(nèi)部4.1K上拉電阻, IO模式圖:









可以看到, 波形有三個(gè)階梯(欠幅), 最下方的波形為0V, 中間的波形為約為2.5v, 最高的波形就是高電平5v
這是為什么? 為什么波形會欠幅?

我有想過可能是變量移位, 取數(shù)據(jù)等消耗了時(shí)間, 但如果這樣也不應(yīng)該欠幅啊, 為什么會有一個(gè)2.5v的電壓出現(xiàn)?

為什么發(fā)送數(shù)據(jù)的波形會出現(xiàn)欠幅現(xiàn)象?
------------------------------------------------------------------------------------------------------------------------------------------
今天又用Keil的debug功能調(diào)試了一下程序, 發(fā)現(xiàn)一個(gè)問題:先上匯編程序:

整個(gè)字節(jié)的發(fā)送過程太過繁瑣, 這里精簡一下, 只考慮發(fā)送一個(gè)bit的情況, 當(dāng)發(fā)送"1"(即高電平)時(shí)
當(dāng)程序運(yùn)行到SDA = 1時(shí), 輸出波形沒有預(yù)想中被拉高到5v, 反而處于2.5v左右的不確定狀態(tài), 有較大波動



但當(dāng)程序運(yùn)行至"SCL = 0"處時(shí), SDA才被穩(wěn)定拉高至5V







整個(gè)發(fā)送中, 以上過程不斷循環(huán), 最終導(dǎo)致了波形產(chǎn)生欠幅現(xiàn)象

綜上, 我最搞不清楚的一點(diǎn)是:為什么執(zhí)行SDA = 1之后SDA管腳會處于不確定狀態(tài)? 而在執(zhí)行完與SDA毫不相干的"SCL = 0"語句后SDA又被拉高?
是上拉電阻的原因嗎? 但如果是因?yàn)闆]有上拉電阻的話, SDA又為什么能被拉高到5V呢?
本人百思不得其解, 如若得君相助, 定感激不盡!







51hei圖片_20220123222634.jpg (3.2 MB, 下載次數(shù): 36)

51hei圖片_20220123222634.jpg
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:624769 發(fā)表于 2022-1-24 00:06 | 只看該作者
首先,如果是發(fā)送  0xff
方法1 是正確發(fā)送的,
方法2 發(fā)送出去是0xfe

其次,哪種方法簡單,你是你以為你看上去覺得簡單,而是單片機(jī)實(shí)際運(yùn)行起來簡單。很明顯,單片機(jī)執(zhí)行方法1才是最簡單的。

最后, CY 是PSW里的一個(gè)位沒錯(cuò),但是就指令來講,他是直接操作的C寄存器。也是C語言方式下,操縱C寄存器的唯一方式。
從字節(jié)中提取位,無論如何都是避不開C寄存器的,所以,直接從C寄存器取值是最理想的一種方式,即便你把C語言代碼整的再怎么好看,最后還是要把位變量移到C寄存器然后再從C寄存器賦值給IO,你可以編譯后看看編譯后的指令,最終還是需要  MOV   xxx,C  來給IO賦值。
回復(fù)

使用道具 舉報(bào)

板凳
ID:739727 發(fā)表于 2022-1-24 01:03 | 只看該作者
法2 發(fā)送的數(shù)據(jù)不對的,需要先發(fā)送再移位
回復(fù)

使用道具 舉報(bào)

地板
ID:884307 發(fā)表于 2022-1-24 11:26 | 只看該作者
AAA_MCU 發(fā)表于 2022-1-24 01:03
法2 發(fā)送的數(shù)據(jù)不對的,需要先發(fā)送再移位

感謝, 這一點(diǎn)沒想到!
回復(fù)

使用道具 舉報(bào)

5#
ID:884307 發(fā)表于 2022-1-24 11:26 | 只看該作者
188610329 發(fā)表于 2022-1-24 00:06
首先,如果是發(fā)送  0xff
方法1 是正確發(fā)送的,
方法2 發(fā)送出去是0xfe

明白了! 學(xué)好匯編還是很重要的, 那為什么波形會呈現(xiàn)階梯狀呢?
回復(fù)

使用道具 舉報(bào)

6#
ID:606226 發(fā)表于 2022-1-24 12:15 | 只看該作者
你這個(gè)電路是什么樣子呢,I2C上有掛什么器件嗎
回復(fù)

使用道具 舉報(bào)

7#
ID:884307 發(fā)表于 2022-1-24 13:01 | 只看該作者
c00156155 發(fā)表于 2022-1-24 12:15
你這個(gè)電路是什么樣子呢,I2C上有掛什么器件嗎

沒有, 我把SDA映射到P1.4, SCL映射到P1.5, 全部懸空沒有掛設(shè)備, 我示波器探頭開的1X, 輸入阻抗相對小, 直接測量P1.5管腳
回復(fù)

使用道具 舉報(bào)

8#
ID:624769 發(fā)表于 2022-1-24 13:30 | 只看該作者
Kituro 發(fā)表于 2022-1-24 13:01
沒有, 我把SDA映射到P1.4, SCL映射到P1.5, 全部懸空沒有掛設(shè)備, 我示波器探頭開的1X, 輸入阻抗相對小, 直 ...

如果你是 89C51 的話, 模擬IIC通信, 應(yīng)當(dāng)接在P0總線,并且4.7K上拉。
如果是增強(qiáng)型51的話,應(yīng)該開啟IO的開漏模式,并且4.7K上拉。

用準(zhǔn)雙向口驅(qū)動 IIC設(shè)備比較容易發(fā)生欠幅問題,因?yàn)闇?zhǔn)雙向口的內(nèi)部弱上拉(約50K)和IIC器件內(nèi)部的弱下拉(約50K),剛好可以形成一個(gè)1/2分壓電壓。
回復(fù)

使用道具 舉報(bào)

9#
ID:884307 發(fā)表于 2022-1-24 21:17 | 只看該作者
188610329 發(fā)表于 2022-1-24 13:30
如果你是 89C51 的話, 模擬IIC通信, 應(yīng)當(dāng)接在P0總線,并且4.7K上拉。
如果是增強(qiáng)型51的話,應(yīng)該開啟IO ...

非常感謝您的回復(fù)! 我的帖子更新了一下, 有更詳細(xì)的描述, 請您看一下, 謝謝!
回復(fù)

使用道具 舉報(bào)

10#
ID:301191 發(fā)表于 2022-1-25 19:26 | 只看該作者
頂一下
回復(fù)

使用道具 舉報(bào)

11#
ID:624769 發(fā)表于 2022-1-26 03:37 | 只看該作者
Kituro 發(fā)表于 2022-1-24 21:17
非常感謝您的回復(fù)! 我的帖子更新了一下, 有更詳細(xì)的描述, 請您看一下, 謝謝!

幾點(diǎn),
首先,代碼過于復(fù)雜,
你不需要  k = CY; 然后  SDA = k;
而是應(yīng)該直接  SDA = CY;

之前回復(fù)我已經(jīng)有說,準(zhǔn)雙向模式, 會在  弱上拉極弱上拉之間切換,所以,是不穩(wěn)定的,IIC器件都是有內(nèi)部下拉的,所以IO口,最好是開漏模式 + 4.7K上拉, 既然你用的是 STC8系列, 那么,你也不需要改電路,他是內(nèi)置有 4.7K上拉的。你翻一下手冊,把內(nèi)置4.7K上拉打開,然后,用開漏模式驅(qū)動,應(yīng)該就能解決這個(gè)問題了。
回復(fù)

使用道具 舉報(bào)

12#
ID:884307 發(fā)表于 2022-1-26 16:36 | 只看該作者
188610329 發(fā)表于 2022-1-26 03:37
幾點(diǎn),
首先,代碼過于復(fù)雜,
你不需要  k = CY; 然后  SDA = k;

非常感謝幫助, 這個(gè)變量k是我在調(diào)試的時(shí)候用來追蹤SDA狀態(tài)用的, 實(shí)際應(yīng)用不會這么寫
使用P1.4口輸出波形
我啟用了上拉電阻和開漏模式后仍然輸出這個(gè)波形, 還有救么?









回復(fù)

使用道具 舉報(bào)

13#
ID:624769 發(fā)表于 2022-1-26 18:07 | 只看該作者
Kituro 發(fā)表于 2022-1-26 16:36
非常感謝幫助, 這個(gè)變量k是我在調(diào)試的時(shí)候用來追蹤SDA狀態(tài)用的, 實(shí)際應(yīng)用不會這么寫
使用P1.4口輸出波形 ...

IIC 通信,  SDA, SCL 兩個(gè)引腳都需要上拉,開漏驅(qū)動,不是說,設(shè)一個(gè)就可以的。
假如是控制 DS1307的話,連SWQ引腳都需要上拉。
你雖然SDA的波跳動,但是,很大的可能是因?yàn)镃LK的上拉不足。
另外,IIC器件的VCC入口一般需要 104電容濾波,如果是類似 TM系列的LED驅(qū)動 芯片, 還需要10uf以上的電解電容,不然都可能造成IIC 傳輸異常。
回復(fù)

使用道具 舉報(bào)

14#
ID:884307 發(fā)表于 2022-1-26 19:29 | 只看該作者
188610329 發(fā)表于 2022-1-26 18:07
IIC 通信,  SDA, SCL 兩個(gè)引腳都需要上拉,開漏驅(qū)動,不是說,設(shè)一個(gè)就可以的。
假如是控制 DS1307的話 ...

好吧, 謝謝您的指點(diǎn)!
回復(fù)

使用道具 舉報(bào)

15#
ID:185846 發(fā)表于 2022-1-26 22:34 | 只看該作者
你可以在輸出時(shí)把SDA設(shè)置成推挽模式;在讀取數(shù)據(jù)時(shí)設(shè)置成IO口模式(如果內(nèi)部上拉電阻足夠小的話);最好外部上拉電阻要接上
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表