並口模擬IIC的經驗之談

2020-12-05 電子產品世界

由於工作需要,用計算機來讀寫AT24C01A,用VC語言實現並口模擬I2C 。

(一)試驗前的準備知識:

一、I2C總線:i2c總線是 Philips 公司首先推出的一種兩線制串行傳輸總線。它由一根數據線(SDA)和一根
時鐘線(SDL)組成。i2c總線的數據傳輸過程如圖3所示,基本過程為:
1、主機發出開始信號。
2、主機接著送出1位元組的從機地址信息,其中最低位為讀寫控制碼(1為讀、0為寫),高7位為從機器件地址
代碼。
3、從機發出認可信號。
4、主機開始發送信息,每發完一字節後,從機發出認可信號給主機。
5、主機發出停止信號。

I2C總線上各信號的具體說明:
開始信號:在時鐘線(SCL)為高電平其間,數據線(SDA)由高變低,將產生一個開始信號。
停止信號:在時鐘線(SCL)為高電平其間,數據線(SDA)由低變高,將產生一個停止信號。
應答信號:既認可信號,主機寫從機時每寫完一字節,如果正確從機將在下一個時鐘周期將數據線(SDA)拉
低,以告訴主機操作有效。在主機讀從機時正確讀完一字節後,主機在下一個時鐘周期同樣也要將數據線(S
DA)拉低,發出認可信號,告訴從機所發數據已經收妥。(註:讀從機時主機在最後1位元組數據接收完以後不
發應答,直接發停止信號)。
注意:在I2C通信過程中,所有的數據改變都必須在時鐘線SCL為低電平時改變,在時鐘線SCL為高電平時必須保 持數據SDA信號的穩定,任何在時鐘線為高電平時數據線上的電平改變都被認為是起始或停止信號。

下面以AT24C01A為例,對幾個主要工作時序做詳細說明。
(1)AT24LC01A的控制字(節)格式:發送時緊跟開始信號後的4位是器件選擇位,通常為『1010',它和後面的3位器件地址碼(由AT24C01的A0、A1、A2上的電平決定)共同構成了7位的從機地址。從機地址後緊跟1位讀/寫控制位,該位為1表示讀,為0表示寫。最後1位是應答位,這裡它由從機給出。
(2)AT24LC01A寫時序:主機發送開始信號,接著發出從機地址和寫控制碼,主機接收從機發出的應答,主發送1位元組的地址信息,主機接收應答,主機寫1位元組數據到從機,主機接收應答,主機發出停止信號。寫操作 完成,1位元組數據被寫入AT24C01內指定地址。AT24C01提供一種頁寫的方式,每次最多可連續寫入8位元組數據再發送停止信號,當寫入數據多時可採用這種方式以加快速度。
(3)AT24CO1隨機讀時序:主機發送開始信號,接著發送從機地址和寫控制碼,主機接收應答,主機發送1位元組的的地址信息,主機接收應答(注意:前面的時序為寫操作,目的把起始地址寫入AT24C01A緩衝中,以告知隨後的讀操作從哪個地址開始,這個步驟在讀時序中有時被稱為"偽寫"),主機發送開始信號,主機發送從機地址和讀控制碼,主機接收應答,主機讀取1位元組數據,主機不發應答,主機發送停止信號。完成上面步驟,主機已從AT24CO1中讀出指定地址內1位元組數據。
(4)AT24LC01讀時序:與隨機讀時序相比,主機沒有給從機寫入起始地址,所以這種方式用於讀取當前地址內的數據。另,AT24C01也可以採用連續讀的方式,這樣每次最多可以讀取8位元組。注意:連續讀時每讀完1位元組後主機要發應答給主機,但在最後1位元組後(即停止信號前)主機不發應答。

數據線(SDA)上的信號:讀時,從機在SCL的上升沿將數據放到SDA上,寫時,遇到SCL的上升沿,從機將接收SDA上的數據。

二、並行口:它包含了一批輸入/輸出埠,在PC機上它是一個25針的 D 型插口,一般用於連接印表機,因此
有時也稱為列印口。

並行口信號:以印表機為例,並口I/0信號中有些是專門用來把數據傳送給印表機的,有些則是用來對傳
送過程給以控制的,還有將印表機的各種工作狀態信息發送給CPU的。詳細如表1所示。表中所有信號用低電平
(0V)表示邏輯0,用高電平(5V)表示邏輯1(電壓都是相對於18-25腳上的接地電勢而言),凡是前綴用符號『-'表示的信號均指低電平為現役信號。

可以看出,編號為2-9針腳上的信號是傳遞實際數的信號,而其它線上的信號則是用在對印表機進行初始化處理和對印表機動作進行同步上。下面簡單介紹一下列印過程以加深對並口的理解,CPU通過並口中16和17腳上
的信號來選擇印表機,並給以初始化處理。且用13腳上的信號給以響應。在印表機已準備好接收數據時,就將
11腳置為低電平(表示可以接收),CPU把數據放到並口的數據線(2-9)上,並通過1腳上的選通信號對印表機的數據進行選通。印表機在收到選通信號時將忙信號(11)置為高電平,表示正在接收數據。數據接收完畢後,印表機在短時間內把現役的確認信號(10腳低電平)發送出去,然後再把忙信號(11)置成低電平(既非現役)並準備好接收更多數據。

並行口硬體:並口行現在通常被集成在系統板上,25針插口上的信號可通過數據鎖存器、列印狀態和列印
機控制三個寄存器(也就是三個輸入/輸出埠)進行程序設計和控制。計算機系統中通常有多個並行埠,
表2列出了它們在輸入/輸出系統中的地址。需要注意的是這些地址是由系統 BIOS 給出的,並不是硬體的物理
地址,所以可以通過設置 BIOS 來改變當前埠的配置。

埠寄存器:表3列出了並行埠寄存器各位的意義。這些信號也是在外部插頭上出現的主要信號。不過
寄存器中有些信號的極性與插頭上相應信號的極性正好相反。比如,選通信號在插頭上為低電平時,信號是現
役的,而在印表機控制寄存器中則為高電平是現役的。


通過上面的準備知識,應有以下理解,1、可以把並口的25個針腳理解為三個寄存器對外的映射,除了傳
送8位實際數據的引腳外,還有用於控制印表機和取得印表機當前狀態的引腳,這些引腳有的為輸入,有的為
輸出,因此可以像用單片機I/O一樣靈活的運用它們。2、I2C總線在通訊過程中,數據線(SDA)上的信號流
動方向是不斷變化的,如:主機正在寫AT24C01時,SDA的方向為主機到從機,SDA為輸出,寫完一字節後,要接收應答時,SDA的方向變為從機到主機,SDA為輸入(對於主機)。3、並口模擬I2C總線,其實是用軟體控制並口的 I/O 來輸入輸出 I2C 總線需要的高、低電平信號,從而產生I2C總線的各種時序。


(二)製作試驗電路:

實驗用電路

相對於並口,P1的13腳接SDA 的輸入,P1的3腳接SDA的輸出,P1的15腳接SCL的輸入,P1的5腳接SCL的輸出。試驗用的電路,分析如後:P1的5腳接IC1的SCL端,用做I2C總線的串行時鐘信號輸出。因I2C總線中數據線(SDA)在不同的時間可能是輸入也可能是輸出,所以接在IC1 SDA端上的信號也有兩路,輸出時,P13腳輸出低電平T1導通,SDA被置為低電平,P13 腳輸出高電平T1截止,因 R1的作用SDA被置為高電平。輸入時,P1 通過判斷 13 腳上的電平高低,來讀取SDA上的數據。要注意的是用於輸入時T1必須是截止的,以免SDA被箝位。

這個電路具有通用性,AT24C01、AT24CO2、24LC64等24系列的I2C EEPROM 均可按這個電路與並口連接,所以 不妨把它當作實用工具來認真製作。先找一條並口電纜,看電纜插頭的形式,找一個與之配套的25針插座,購買一個撥動式的IC插座,將IC插座按圖中IC1的連接方法與找來的並口插座相連,然後按圖將T1、R1、C1、直接焊在IC插座或並口插座上,要儘量作的緊湊些。最後將電路固定在一個合適的小塑料盒內,好了,現在它是我們的試驗器材,等看過後面的內容,你會發現只要為其配上軟體,它就是一個用於讀寫I2C EEPROM 的好工具。


(三)試驗程序編寫:
和其它高級語言相比,C 更適合於對硬體編程。但是由於要求工作界面要美觀,目前實驗用到的是VC++。但是在VC條件編制並口程序需要相關的I/O庫進行配置。

(四)編程:通過上面分析,要用並口來模擬I2C總線來讀寫 AT24C01 ,程序需有以下幾部分:

發送I2C開始信號:SCL和 SDA都為高電平,延時一段時間後,向378H寫入"0XFD"(其它腳狀態不變,只是將位 1 置為低電平),使SDA由高電平變為低電平,即產生了I2C的開始信號。最後將在378H中寫入"0XFC"(即其它腳不變,將位0和位1置為低電平)使SCL為低電平,以完成一個時鐘,也為後面的讀寫作準備。

發送I2C停止信號:I2C的停止信號是在SCL為高時,SDA由低變高。程序可按下面步驟來寫,用寫埠函數
向378H寫入"0XFC",使SCL和SDA為低電平,延時一段時間,向378H寫入"0XFD",使SCL變為高電平,SDA為低電平,延時,向378H寫入"0XFF"SCL保持不變,使SDA由原來的低電平變為高電平,即產生了一個停止信號。延時一段時間,最後向378H寫入"0XFE",使SCL為低電平,以完成一個時鐘。

發送數據:先把要發送的數據放在一個變量裡,然後按位發送。方法為,通過位運算求得欲發送位的值(
1或0),然後用寫埠函數模擬出SCL和SDA,並按I2C的寫時序將一位數據發送出去,程序中可用while循環語句來控制發送的位數和字節數。

主機(並口)發送應答:I2C總線,主機發送應答用在連續讀時序中,每讀取一字節(8位)後,主機使SDA
保持一個時鐘周期的低電平。可以用寫埠函數先將SDA、SCL置為 0,然後將SCL變高,SDA保持低電平,一個應答信號既被發送,最後將SCL置低,完成一個時鐘。

接收數據:並口讀取I2C總線的數據時,必須讓 T1截止,使用並口的13腳來接收SDA上的數據。可按下面步
驟操作,先用寫埠函數使SCL為低電平,同時在並口3腳輸出高電平使 T1 截止。然後用寫埠函數單獨將SCL置1,其它位保持不變,模擬出時鐘上升沿,IC1 將把一位數據放到數據線SDA上,用讀埠函數 讀
取『印表機狀態'寄存器379H當前的值,將結果賦值給一個變量,然後對這個變量進行先右移4位,再左移7位
的運算(用以獲得13 腳電平狀態,即印表機狀態寄存器的位 4 的值),判斷該變量是否為0,最後將判斷結果
移入另外的一個用於存放『已讀取數據'的變量中,完成讀取一位數據的操作,用寫埠函數使SCL為低電平,
在下一個SCL的上升沿,同樣用上面的方法將一位數據加入『已讀取數據'變量中。可用while循環控制要讀的
位數和字節數。注意以上過程都是在 T1 為截止態時進行的。

主機(並口)接收應答:接收應答用於寫 I2C 時,每寫一字節數據到從機後,如果操作成功,從機在下一
個時鐘內使 SDA 為低。主機查詢應答可以加強操作的可靠性。接收應答和上面說的接收數據大致相同,只是僅 接收一位數據並且不存儲,直接判斷其值是否為 0,不為 0 時(即沒有收到應答)轉錯誤處理程序,為 0則繼
續後面的操作。在實際編程時將這個步驟合併到寫I2C的操作中。

有關延時:I2C器件對SDA和SCL上的高、低電平信號需保持的時間是有規定的。如:開始信號的高、低電平
要保持多長時間,數據信號的高、低電平最低要保持多長時間等。不同的器件對這個時間有不同的規定。查找
24LO02的數據手冊,可以知道,它在不同的電壓下對各信號要保持的時間分別在幾百納秒到幾微秒之間。這個
時間也體現了I2C器件的讀寫速度。因為計算機的速度不同,要用計算機並口來模擬I2C很難將這個時間精確到
微秒。為了能夠在不同的計算機上可靠的操作I2C總線,試驗程序用了C語言的延時函數delay();這個函數能產
生的最小延時為1毫秒。雖然這樣做降低了I2C的讀寫速度,但可以保證操作的可靠性。

程序代碼:

/***************************************/
//控制的地址是0x378
//SDA信號: PIN13 模擬作為主機的輸入;
// PIN3 模擬作為主機的輸出;
//SCL信號: PIN15 模擬作為主機的輸入;
// PIN5 模擬作為主機的輸出;
/***************************************/
/*************************************/
//函數名稱:IIC start 函數
//開始信號:在時鐘線(SCL)為高電平其間,
//數據線(SDA)由高變低,將產生一個開始信號。
/*************************************/
void port2iicbase::i2c_start()
{
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);
SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
delay(1);
SetPortVal(PORT1,0x0d,1);/*scl 1, sda 0*/
delay(1);
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
return;
}
/*************************************/
//函數名稱:IIC stop 函數
//停止信號:在時鐘線(SCL)為高電平其間,
//數據線(SDA)由低變高,將產生一個停止信號
/*************************************/
void port2iicbase::i2c_stop()
{
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);
SetPortVal(PORT1,0x0d,1);/*scl 1, sda 0*/
delay(1);/***/
SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
delay(1);/**/
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
}
/*************************************/
//函數名稱:IIC 寫一個字節函數
/*************************************/
int port2iicbase::i2c_writebyte(char c)
{
short int count=7;
char temp;
DWORD dwPortVal;
char e;

while(count>=0)
{
temp=c>>count;
temp=temp7; //確定傳輸的字節
if (temp=='\x80') //傳輸"1"
{
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
delay(1);
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);
SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
delay(1);
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);
}
else //傳輸"0"
{
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
delay(1);
SetPortVal(PORT1,0x0d,1);/*scl 1, sda 0*/
delay(1);
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
delay(1);
}
count--;
}
/**ask**/
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);/***/
SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
delay(1);
// SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
// delay(1);/***/

GetPortVal(PORT2, dwPortVal, 1);
e = (char)dwPortVal;
temp=e>>4;
temp=temp7;

if (temp=='\x0')
return 0;
else
MessageBox(NULL,"Not Acknowledge!!","發送錯誤",MB_OKCANCEL);
return 1;
}
/*************************************/
//函數名稱:IIC 讀一個字符函數
/*************************************/
char port2iicbase::i2c_readbyte()
{
unsigned short count=8;
char d,e,f='\x0';
DWORD dwPortVal;

while(count>0)
{
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);/***/
SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
delay(1);

GetPortVal(PORT2, dwPortVal, 1);
e = (char)dwPortVal;
d=e>>4;
d=d7;

if(d=='\x80')
d='\x1';
f=f1;
f=(f+d); //組合成字節
count--;
}
return f;
}
/*************************************/
//函數名稱:主機(並口)的發送應答
/*************************************/
void port2iicbase::i2c_ask()
{
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
delay(1);/**/
SetPortVal(PORT1,0x0d,1);/*scl 1, sda 0*/
delay(1);
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
delay(1);
}

//////////////////////////////////
//發送數據按鈕
/////////////////////////////////
void Cport2iicdlg1::OnWriteok()
{
// TOD Add your control notification handler code here
port2iicbase port2iic;
char s[100];
char temp[3];
int len;
int i;
char m_cValue;
unsigned int WriValue=0;
int time = 0;

unsigned short c;
char d,e;

#ifdef _PORT2IIC
SetDlgItemText(IDC_WRITE_STATUS,"正在發送....");
GetDlgItem(IDC_EDIT_WRITE)->GetWindowText(s, 100);
len = strlen(s);
c = len/2;
e='\x0';
d='\x0';
i = 0;
c = 5;
//寫一頁
//啟動開始信號;
port2iic.i2c_start();
//發送控制信息
//"\xa0" = 1010(A2)(A1)(A0)(R/W) 其中(R/w) = 0 寫
//"\xa1" = 1010(A2)(A1)(A0)(R/W) 其中(R/w) = 1 讀
port2iic.i2c_writebyte('\xa0');
//發送地址
port2iic.i2c_writebyte(e);
while(c>0)
{
temp[0] = s[i];
temp[1] = s[i+1];
temp[2] = 0x0;
sscanf(temp,"%x",WriValue);
m_cValue = (char)WriValue;
port2iic.i2c_writebyte(m_cValue);
c = c-1;
i+=2;
}
port2iic.i2c_stop();
#if 0
//24c01 寫128個字節,調試寫16個字;
c=20;
e='\x0';
d='\x0';
while(c>0)
{
//啟動開始信號;
port2iic.i2c_start();
//發送控制信息
//"\xa0" = 1010(A2)(A1)(A0)(R/W) 其中(R/w) = 0 寫
//"\xa1" = 1010(A2)(A1)(A0)(R/W) 其中(R/w) = 1 讀
port2iic.i2c_writebyte('\xa0');
//發送地址
port2iic.i2c_writebyte(e);
port2iic.i2c_writebyte(d);
port2iic.i2c_stop();
d = c/5;
c = c-1;
e = e+1;
}
Sleep(50);
//任意讀;
//讀寫入的數據
b = 0;
i = 0;
a = 20;
while(a > 0)
{
//任意讀;
port2iic.i2c_start();
port2iic.i2c_writebyte('\xa0');
d = char(b);
port2iic.i2c_writebyte(d);
port2iic.i2c_start();
port2iic.i2c_writebyte('\xa1');
d = port2iic.i2c_readbyte();
port2iic.i2c_stop();
buff[i] = d;
i++;
b= b+1;
a = a - 1;
}
#endif
#else
len = strlen(s);
for(i = 0; i len; i+=2)
{
temp[0] = s[i];
temp[1] = s[i+1];
temp[2] = 0x0;
sscanf(temp,"%x",WriValue);
m_nValue = (DWORD)WriValue;
SetPortVal(0x378,m_nValue,1);
}
#endif
SetDlgItemText(IDC_WRITE_STATUS,"發送結束");
return;
}

//////////////////////////////////
//在定時器裡接收數據按鈕
/////////////////////////////////
void Cport2iicdlg1::OnTimer(UINT nIDEvent)
{
// TOD Add your message handler code here and/or call default
port2iicbase port2iic;
DWORD m_nValue = 0;
CString temp1,temp2;
CEdit* pReadEdit;
unsigned short buff[100];

unsigned short a,b;
char d;
int i;
pReadEdit = (CEdit*) GetDlgItem(IDC_EDIT_READ);
memset(buff,0x0,100);
#ifdef _PORT2IIC
//任意讀;
#if 0
//讀寫入的數據
b = 0;
a = 5;
i = 0;
while(a > 0)
{
//任意讀;
port2iic.i2c_start();
port2iic.i2c_writebyte('\xa0');
d = char(b);
port2iic.i2c_writebyte(d);
port2iic.i2c_start();
port2iic.i2c_writebyte('\xa1');
d = port2iic.i2c_readbyte();
port2iic.i2c_stop();
b= b+1;
a = a - 1;
buff[i] = (unsigned short)d;
buff[i] = buff [i] 0x00ff;
temp1 = " ";
temp2.Format(_T("%.2x"),buff[i]);
if(m_read != _T(""))
m_read = m_read + temp1;
m_read = m_read + temp2;
i++;
SetDlgItemText(IDC_EDIT_READ,m_read);
DWORD dwSel = pReadEdit->GetSel();
pReadEdit->SetSel(HIWORD(dwSel), -1);
}
#endif
#if 1
//順序讀
//讀寫入的數據
b = 0;
a = 5;
i = 0;
port2iic.i2c_start();
port2iic.i2c_writebyte('\xa0');
d = char(b);
port2iic.i2c_writebyte(d);
port2iic.i2c_start();
port2iic.i2c_writebyte('\xa1');
while(a > 0)
{
d = port2iic.i2c_readbyte();
a = a - 1;
if(a > 0)
port2iic.i2c_ask();
buff[i] = (unsigned short)d;
buff[i] = buff [i] 0x00ff;
temp1 = " ";
temp2.Format(_T("%.2x"),buff[i]);
if(m_read != _T(""))
m_read = m_read + temp1;
m_read = m_read + temp2;
i++;
SetDlgItemText(IDC_EDIT_READ,m_read);
DWORD dwSel = pReadEdit->GetSel();
pReadEdit->SetSel(HIWORD(dwSel), -1);
}
port2iic.i2c_stop();
#endif
#else
GetPortVal(0x378, m_nValue,1);
m_nValue = m_nValue 0x000000ff;
temp1 = " ";
temp2.Format(_T("%.2x"),m_nValue);
if(m_read != _T(""))
m_read = m_read + temp1;
m_read = m_read + temp2;
SetDlgItemText(IDC_EDIT_READ,m_read);
DWORD dwSel = pReadEdit->GetSel();
pReadEdit->SetSel(HIWORD(dwSel), -1);
#endif
CDialog::OnTimer(nIDEvent);
return;
}

以上程序已經經過了驗證能夠正確運行。

相關焦點

  • 硬碟串口IDE與並口SATA接口之比較
    sata接口的機械硬碟1、首先要明確一點,IDE、SATA都是ATA接口,IDE是傳統串口,SATA是新式並口。IDE硬碟是傳統的並口硬碟,現在已經被SATA硬碟即串口硬碟所淘汰。IDE全稱即「電子集成驅動器」,俗稱PATA並口。IDE接口,也稱之為ATA接口,英文含義是「高級技術附加裝置」。ATA接口在九十年代初開始應用於臺式機。它使用一個40芯電纜與主板進行連接。
  • 光耦在並口長線傳輸中的應用
    打開APP 光耦在並口長線傳輸中的應用 潮光光耦網 發表於 2012-08-09 14:54:49
  • 老司機經驗之談,建議新手收藏
    老司機經驗之談,建議新手收藏汽車中被稱為「心臟」的零件就是發動機,大家能知道這個發動對一輛車子有多麼重要也都知道了吧?它能直接關乎一輛車的性能。就和我們的心臟一樣重要,但除了發動機你們還感覺那個零件對一輛車子特別重要呢?對一輛車特別重要的還有離合器,他其中有摩擦片、減震片、離合器片、盤剎減震彈簧等零件組成,離合器可以起到傳遞動力的作用。
  • 古人經驗之談
    看看古人經驗之談今年的立秋是在8月7日,農曆六月十八日。如今距離立秋過去已經有幾天了,在今天早上筆者這裡下起了大雨,所以早上起來的時候,明顯感覺到天氣涼快了很多,並且還有種秋天來了的感覺。立秋節氣已過,中伏也過去了一大半了,現在農民最為關注的就是今年秋季的雨水多少了,還有即將到來的秋收了。
  • 古人經驗之談是迷信嗎?
    古人經驗之談是迷信嗎?答案其實不言自明!究竟什麼是「發旋」?發旋的定義是:毛流在頭頂可形成一個中心向外,周圍頭髮呈漩渦狀的排列;毛幹和皮膚呈一定的傾斜度,許多毛髮的傾斜方向是一致的,稱發流或毛流。從發旋的定義當中,我們知道發旋只是一種體表特徵而已;甚至農村老人的口中還有這樣一句俗語「雙頂女孩沒人要」,雙頂指的什麼?
  • 古人經驗之談
    因此,在一個家庭中,即便有一個有德有才的孩子,但還是敵不過敗家子敗家的速度,所以這句俗語也算是過來人的經驗之談。王阿姨家有兩個孩子,大的是兒子,小的是女兒,可能是因為南方人多少有點重男輕女的緣故,所以王阿姨從小就對兒子很寵愛,只要兒子想要,恨不得天上的星星都摘下來給他,但對女兒她的態度又有點不一樣。
  • 基於XC2V500-6FG256C和AD9858實現複雜信號模擬的設計
    如圖1所示,本文對高頻的載波信號和低頻的調製信號分別模擬後進行疊加,高頻的載波信號cos(Ω0t)使用高性能的DDS晶片AD9858和FPGA控制來模擬,α(t)和θ(t)雙路低頻的調製信號全部在FPGA中實現。
  • 用MC145026/27實現多機並口線通信
    摘要:介紹了一種用三態編解碼晶片MC145026/27實現的基於並口的多機線通信系統的組成原理和實現
  • 老祖宗的經驗之談
    小雞一旦漲到一年左右基本上就會變成老雞,在這種前提下肉質就會特別柴,即使燉的時間很長也不容易爛,這種肉質的小雞吃起來口感特別差,為了能夠在吃雞肉的時候吃到肉質鮮嫩湯汁可口的小雞,人們都會選擇殺未隔年的小雞,別看老祖宗的這句俗語簡短,可以說是人們在長期實踐中總結的經驗之談,不知道對這句老話你是如何理解的。
  • 下半句更經典,古人經驗之談
    下半句更經典,古人經驗之談文章作者:離央配圖聲明:本文所用圖片均源於網絡,侵刪盜用警告:本帳號已與「維權騎士」籤約,可實時監測全網盜用文章行為,請遵守道德底線,莫做伸手黨!
  • 老話「窮三富四,黴五膽六」啥意思,老祖宗的經驗之談,不可不知
    我們上面說的這句俗語,其實就是古人的經驗之談,細細品讀的確獲益良多。今日話題:你還能想到哪些跟數字有關的俗語?歡迎在下方留言,我們一起學習和交流。文 | 國學大觀園
  • 註冊類考試經驗之談:「保大放小」——把必考點、難點,必須掌握
    註冊類考試經驗之談:「保大放小」——把必考點、難點,必須掌握關於註冊類考試的一點經驗和建議接上一條繼續說起,那麼怎樣備考各種註冊類考試呢。其實,經驗和方法也大同小異,本著專業認真負責的態度,我只說我目前擁有的註冊類證書的經驗和個人的一些想法。
  • 俗語「富不添丁,窮不添女」啥意思,老祖宗的經驗之談,長見識了
    實際上是來自於老祖宗的經驗之談,仔細品讀的話也會使人大開眼界。富不添丁,富人家族恐內鬥在古代,所謂的「男女平等」是不可能存在的事情。由於農耕社會的特殊性,有力氣進行耕作養活家人的男性,才是地位比較高的。所以即便知道生兒育女不能人為控制,在女子生育時,還是要求神拜佛,希望能生下延續香火的男丁。而「富不添丁」的「丁」,指的正是男丁。
  • 古人的經驗之談
    「人過六十,莫至二地」這句話是古人的經驗之談,哪怕是到了現代依然適用,如果說我們能夠遵循這個告誡的話
  • 要成為模擬電路的設計者 必須掌握以下四個組成部分
    但值得我們注意的是,模擬電路構建了電子行業的基礎,至今為止,電子技術已經發展到如此高的水平。但如果我們觀察各種電子電路的發展,我們會發現:幾乎所有的電子技術都離不開放大技術。即使是數字晶片內部,其基本單元都是互補型源極接地放大電路。模擬電子技術的重要性時不我待。
  • 全球首款「氫氣級」數字IIC防爆手持機——Hytera PD790Ex
    可靠耐用的質量:PD79XEx品質嚴格符合FM-2010年新標準以及IEC,ATEX防爆標準,產品通過1個月模擬惡劣環境的串行測試。同時符合美國軍用標準MIL-STD-810C/D/E/F和IP67工業防護標準,在各種惡劣的工作環境中都可以發揮優異和安全的性能。