A. 51單片機模擬IIC匯流排問題
IIC的地址你可以自己定義的
在硬體上提供過IIC地址的你可以直接選擇他的地址進行發送
像你這種情況的話可以自己定義地址:
假設你有兩台或者以上的S3C2410,單片機作為主機,然後單片機發送數據,所有S3C接收(接收的前提是他的接收埠上獲得IIC的開始信號,你可以選擇利用中斷進行檢測),然後你在軟體里可以預先設置好每台S3C的地址,即接收單片機的前8BIT,然後對照地址,一樣的話就開始接收接下來的信息,沒有就放棄這個通信,這樣的話8BIT就可以控制256台S3C了
其實IIC也只是一種通信方式,你可以選擇自己的協議,以IIC為基礎,比如地址位選擇16BIT甚至更多,如果從機是S3C這種32位的RAM9的話,數據位的傳輸可以32位的傳。所謂的開始信號跟終止信號也只是雙方默認的方式而已,就像是「點頭YES,搖頭NO」,你也可以選擇相反的方式,只要兩台通信的機子能懂就好。
不過最好是採用大家一起的,這樣在軟體移植的時候會有幫助,也方便別人看懂。當大家在某一領域都用一種方式的時候也就形成所謂的協議,比如TCP/IP,UART,IIC等等。
B. 三個51單片機實現通信
你好:
暫且想到兩種辦法:
通用IO口通信:茄源櫻因為三個單片機通信,一個主機兩個從機,那麼主機殼引出兩個io口作為從機的工作使能信號,比如主機引出P1.0和P1.1,然後兩個從機分別接入一io,裂如當主機發出高或低電平使能從機工作,在從機的while里判斷接收的io口的電平,當滿足條件執行之後的程序;數據傳送的話主機殼直接引出8個io口連向兩個從機,因為只有使能從機之後才可以接收數據,所以這樣連接不用擔心未使能的從機接收數據。
模擬iic協議:也是兩個信號線,模擬出iic協議,但是在while里不判斷io電平,而是判斷iic信號線傳遞過來的地址數據,比如從機1地址為0x00,從機2地址為0x01,然後判斷是否收到正確的地址。
對比:
1方案簡單,程序量小,操作方便,但是從機數量不宜過多;顫叢2方案稍復雜,但是可靠,安全,最多可接入256個從機。
希望我的回答能幫助到你。
C. 怎麼樣用stm32單片機做iic從機
可以看吳鑒鷹單片機開發板教程的
#include<reg52.h>
sbitHC595_sck=P0^5;
sbitHC595_rck=P0^6;
sbitHC595_data=P0^7;
codeunsignedcharData_One_Array[2]={0x01,0x00};
codeunsignedcharData_Two_Array[2]={0x00,0x00};
voidSend_Data(unsignedcharData_One,unsignedcharData_Two)
{
unsignedchari;
HC595_rck=0;
for(i=0;i<8;i++)
{
HC595_sck=0;
if(0==(Data_One&0x80))
{
HC595_data=0;
}
else
{
HC595_data=1;
}
Data_One=Data_One<<1;
HC595_sck=1;
}
for(i=0;i<8;i++)
{
HC595_sck=0;
if(0==(Data_Two&0x80))
{
HC595_data=0;
}
else
{
HC595_data=1;
}
Data_Two=Data_Two<<1;
HC595_sck=1;
}
HC595_rck=1;
}
voidmain()
{
while(1)
{
Send_Data(Data_One_Array[0],Data_Two_Array[0]);
}
}
D. C51單片機模擬IIC匯流排,應答函數的疑問
應答是接收設別自動產生的,不一定是從機。在IIC上除了開始,停止和重復開始外,所有數據都在在時鍾的低電平變化的,也就是為高後,數據就應該穩定了。所以如果是模擬匯流排,應先有下降沿,再設為輸入,然後讀ACK,如果是從機的應答,是自動產生的,是作為數據通信正確的判斷標志,為了可靠,是要判斷的。主機的應答一般是程序控制的,如果要結束匯流排,可以給也可以不給應答;如果要繼續讀數據,就必須給出應答。
E. 如何實現雙單片機模擬iic通信
對於疑問1:for循環已經把數據從主器件發送到從器件,沒錯,後面加那幾句是為了釋放數據匯流排,這是晶元協議已經規定了的,為什麼是scl=0;而sda=1呢,應該匯流排SCL與SDA都是線與關系,任意一個器件輸出低電平,都使該匯流排的信號變低,你可能會這么想:為什麼不是scl=1;delay();sda=1;delay();呢?那是因為當scl=1;sda=1;這是終止信號。對吧,這樣寫的話IIC將會停止工作。
對於疑問2:加這幾句也一樣,是晶元現已規定:無論是寫數據還是讀數據,寫完讀完之後需釋放匯流排,for循環語句的意思是:
for(i=0;i<8;i++)
{
scl=1; //拉高時鍾匯流排,開始讀數據
delay();
k=(k<<1)|sda; // 將讀取到的sda數據存放到k中,這里你可能有點無法理解,我舉個例子:剛開始k=0x00(系統默認),當讀取到的sda數據為1時,k=0x01;對吧,反之當讀取到的sda數據為0時,k=0x00;
scl=0;// 讀取完一個數據,拉低時鍾匯流排
delay();
}
就這樣循環8次,這樣一個位元組的數據就從主器件讀到了從器件了。對吧。
如果那個釋放匯流排你理解不了,你就記住,這是晶元協議規定,讀完或寫完都必須釋放匯流排。iic協議都是如此。
希望能幫助到你。
F. 單片機模擬串口通信有什麼利弊
串口通信,或者 IIC 通信,應該是由專門的硬體,來完成的。
CPU 對這些硬體,設置一下,再傳送一下數據,就可以等待結果了。
有些單片機,太簡陋,沒有相應的硬體,只能用軟體編程,模擬硬體,來實現。
執行這些程序,當然,必須佔用 CPU 的時間。這就是《佔用大量的cpu資源》。
有時,還要使用定時器、中斷源,這也是《佔用大量的資源》。
G. 51單片機如何模擬I2C匯流排中從機接收ID,發送數據的程序
#include /*頭文件的包含*/
#include
#define uchar unsigned char /*宏定義*/
#define uint unsigned int
/*埠位定義*/
sbit BELL_OUT=P3^5;
sbit SCL="P1"^3;/*模擬I2C數據傳送位*/
sbit SDA="P1"^4;/*模擬I2C時鍾控制位*/
bit ack; /*應答標志位*/
/*********************************************************************
起動匯流排函數
函數原型: void Start_I2c();
功能:啟動I2C匯流排,即發送I2C起始條件
********************************************************************/
void Start_I2c()
{
SDA="1"; /*發送起始條件的數據信號*/
_nop_();
SCL="1"; /*起始條件建立時間大於4.7us,延時*/
_nop_();
SDA="0"; /*發送起始信號*/
_nop_(); /* 起始條件鎖定時間大於4μs*/
SCL="0"; /*鉗住I2C匯流排,准備發送或接收數據 */
_nop_();
}
/***********************************************
結束匯流排函數
函數原型: void Stop_I2c();
功能:結束I2C匯流排,即發送I2C結束條件
***********************************************/
void Stop_I2c()
{
SDA="0"; /*發送結束條件的數據信號*/
_nop_(); /*發送結束條件的時鍾信號*/
SCL="1"; /*結束條件建立時間大於4μs*/
_nop_();
SDA="1"; /*發送I2C匯流排結束信號*/
_nop_();
}
/*******************************************************************
位元組數據傳送函數
函數原型: void SendByte(uchar c);
功能:將數據c發送出去,可以是地址,也可以是數據,發完後等待應答,並對此狀
態位進行操作(不應答或非應答都使ack=0 假) 。發送數據正常,ack=1;
ack=0表示被控器無應答或損壞。
********************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*要傳送的數據長度為8位*/
{
SCL="0";
if((c<
else SDA="0";
SCL="1"; /*置時鍾線為高,通知被控器開始接收數據位*/
_nop_(); /*保證時鍾高電平周期大於4μs*/
}
//從機應答,可以用應答和非應答信號代替
_nop_();
SCL="0";
_nop_();
SDA="1"; //
_nop_();
SCL="1";
_nop_();
if(SDA==1){ack=0;} /*判斷是否接收到應答信號*/
else ack="1";
SCL="0";
_nop_();
}
/*******************************************************************
位元組數據傳送函數
函數原型: uchar RcvByte();
功能:用來接收從器件傳來的數據,並判斷匯流排錯誤(不發應答信號),
發完後請用應答函數。
********************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc="0";
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SCL="1"; /*置時鍾線為高使數據線上數據有效*/
_nop_();
retc="retc"<<1;
if(SDA==1) retc="retc"+1; /*讀數據位,接收的數據位放入retc中 */
SCL="0";
}
return(retc);
}
/********************************************************************
應答子函數
原型: void Ack_I2c();
功能:主控器進行應答信號
********************************************************************/
void Ack_I2c()
{
SDA="0"; /*在此發出應答信號 */
_nop_();
SCL="0";
_nop_();
SCL="1";
_nop_();
SCL="0"; /*清時鍾線,鉗住I2C匯流排以便繼續接收*/
_nop_();
SDA="1";
_nop_();
}
/********************************************************************
非應答子函數
原型: void NoAck_I2c();
功能:主控器進行非應答信號
********************************************************************/
void NoAck_I2c()
{
SDA="1"; /*在此發出非應答信號 */
_nop_();
SCL="1";
_nop_();
SCL="0"; /*清時鍾線,鉗住I2C匯流排以便繼續接收*/
}
/*******************************************************************
向無子地址器件發送位元組數據函數
函數原型: bit ISendByte(uchar sla,ucahr c);
功能:從啟動匯流排到發送地址,數據,結束匯流排的全過程,從器件地址sla。如果
返回1表示操作成功,否則操作有誤。
********************************************************************/
bit ISendByte(uchar sla,uchar c)
{
Start_I2c(); /*啟動匯流排*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(c); /*發送數據*/
if(ack==0)return(0);
Stop_I2c(); /*結束匯流排*/
return(1);
}
/*******************************************************************
向有子地址器件發送多位元組數據函數
函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能:從啟動匯流排到發送地址,子地址,數據,結束匯流排的全過程,從器件地址sla,
子地址suba,發送內容是s指向的內容,發送no個位元組。如果返回1表示
操作成功,否則操作有誤。
********************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*啟動匯流排*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*發送器件子地址*/
if(ack==0)return(0);
for(i=0;i
{
SendByte(*s); /*發送數據*/
if(ack==0)return(0);
s++;
}
Stop_I2c(); /*結束匯流排*/
//delayMs(1); //
return(1);
}
/*******************************************************************
向無子地址器件讀位元組數據函數
函數原型: bit IRcvByte(uchar sla,ucahr *c);
功能:從啟動匯流排到發送地址,讀數據,結束匯流排的全過程,從器件地址sla,返
回值在c。如果返回1表示操作成功,否則操作有誤。
********************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{
Start_I2c(); /*啟動匯流排*/
SendByte(sla+1); /*發送器件地址*/
if(ack==0)return(0);
*c=RcvByte(); /*讀取數據*/
NoAck_I2c(); /*發送非就答位*/
Stop_I2c(); /*結束匯流排*/
return(1);
}
/**********************************************************************
向有子地址器件讀取多位元組數據函數
函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能:從啟動匯流排到發送地址,子地址,讀數據,結束匯流排的全過程,從器件地址sla,
子地址suba,讀出的內容放入s指向的存儲區,讀no個位元組。如果返回1
表示操作成功,否則操作有誤。
**********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
Start_I2c(); /*啟動匯流排*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*發送器件子地址*/
if(ack==0)return(0);
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
while(no!=1)
{
*s=RcvByte();/*發送數據*/
Ack_I2c(); /*發送就答位*/
s++;
no--;
}
*s=RcvByte();
NoAck_I2c(); /*發送非應位*/
Stop_I2c(); /*結束匯流排*/
return(1);
}