久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4441|回復(fù): 12
收起左側(cè)

學(xué)習(xí)I2C總線感覺有幾個(gè)不明白的地方,希望大家給予幫助

  [復(fù)制鏈接]
ID:485870 發(fā)表于 2019-3-8 21:02 | 顯示全部樓層 |閱讀模式

*****以下代碼來源于清翔電子教程******


    問題1:I2C為什么要初始化呢?感覺不初始化得到的也是一樣的結(jié)果啊
描述:I2C總線初始化
====================================*/
void I2C_init()
{
        SDA = 1;   //數(shù)據(jù)總線高
        _nop_();
        SCL = 1;   //時(shí)鐘總線高
        _nop_();
}


       問題2: I2C的停止信號(hào)函數(shù)為什么要先把數(shù)據(jù)總線SDA拉低呢
描述:I2C停止信號(hào)
====================================*/
void I2C_Stop()
{
        SDA = 0;
        _nop_();
        SCL = 1;
        Delay5us();
        SDA = 1;
        Delay5us();
}

       問題3:I2C主機(jī)發(fā)送應(yīng)答函數(shù)為什么最后要拉高數(shù)據(jù)總線呢?那個(gè)釋放SDA又是什么意思
描述:I2C主機(jī)發(fā)送應(yīng)答
====================================*/
void Master_ACK(bit i)       
{
        SCL = 0; // 拉低時(shí)鐘總線允許SDA數(shù)據(jù)總線上的數(shù)據(jù)變化
        _nop_(); // 讓總線穩(wěn)定
        if (i)         //如果i = 1 那么拉低數(shù)據(jù)總線 表示主機(jī)應(yīng)答
        {
                SDA = 0;
        }
        else         
        {
                SDA = 1;         //發(fā)送非應(yīng)答
        }
        _nop_();//讓總線穩(wěn)定
        SCL = 1;//拉高時(shí)鐘總線 讓從機(jī)從SDA線上讀走 主機(jī)的應(yīng)答信號(hào)
        Delay5us();
        SCL = 0;//拉低時(shí)鐘總線, 占用總線繼續(xù)通信
        _nop_();
        SDA = 1;//釋放SDA數(shù)據(jù)總線。
        _nop_();
}


        問題4: 檢測(cè)到從機(jī)非應(yīng)答或者非應(yīng)答后為什么要把SCL拉低呢(代碼中標(biāo)有問題4處)
描述:I2C檢測(cè)從機(jī)應(yīng)答
====================================*/
bit Test_ACK()         // 檢測(cè)從機(jī)應(yīng)答
{
        SCL = 1;//時(shí)鐘總線為高電平期間可以讀取從機(jī)應(yīng)答信號(hào)
        Delay5us();
        if (SDA)
        {
                SCL = 0;        //問題4
                I2C_Stop();
                return(0);
        }
        else
        {
                SCL = 0;
                return(1);
        }
}


還有為什么在這個(gè)AD—DA轉(zhuǎn)換代碼中,數(shù)碼管顯示轉(zhuǎn)換過來的數(shù)字量不會(huì)隨光照的變化而變化呢,用LED檢測(cè)I2C讀寫結(jié)果都沒有問題。

#include <reg52.h>
#include <intrins.h>
#define MAIN_Fosc                11059200UL        //宏定義主時(shí)鐘HZ
#define PCF8591_ADDR        0x90                //PCF8591地址
#define DACOUT_EN                0x40                //DAC輸出使能

/*====================================
自定義類型名
====================================*/
typedef unsigned char INT8U;
typedef unsigned char uchar;

typedef unsigned int INT16U;
typedef unsigned int uint;

/*====================================
硬件接口位聲明
====================================*/
sbit SDA = P2^0;   //I2C串行數(shù)據(jù)
sbit SCL = P2^1;   //I2C串行時(shí)鐘
sbit DU  = P2^6;   //數(shù)碼管段選
sbit WE  = P2^7;   //數(shù)碼管位選
sbit LED1= P1^0;   //讀取AD的值是否成功(亮成功,滅失敗)
sbit LED2= P1^1;   //DAC成功輸出(亮成功,滅失敗)
sbit BEEP= P2^3;   //蜂鳴器引腳定義

uchar AD_Value;        //存儲(chǔ)AD轉(zhuǎn)換回的數(shù)字量
/*====================================
共陰極數(shù)碼管段選碼
====================================*/
uchar code table[]={
//0                1         2     3     4     5     6     7     8
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9     A     B           C         D           E         F                -         .          關(guān)顯示
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
                   };

/*====================================
數(shù)碼管位選碼
====================================*/
                                  //第1位        2位          3位         4位   5位        6位          7位        8位
uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//數(shù)碼管位碼

/*====================================
函數(shù):void Delay_Ms(INT16U ms)
參數(shù):ms,毫秒延時(shí)形參
描述:12T 51單片機(jī)自適應(yīng)主時(shí)鐘毫秒級(jí)延時(shí)函數(shù)
====================================*/
void Delay_Ms(INT16U ms)
{
     INT16U i;
         do{
              i = MAIN_Fosc / 96000;
                  while(--i);   //96T per loop
     }while(--ms);
}

/*====================================
函數(shù):void Delay5us()
描述:12T 51單片機(jī)5微秒延時(shí)函數(shù)自適應(yīng)時(shí)鐘(11.0592M,12M,22.1184M)
====================================*/
void Delay5us()
{
        #if MAIN_Fosc == 11059200
                _nop_();
        #elif MAIN_Fosc == 12000000
                _nop_()
        #elif MAIN_Fosc == 22118400
                _nop_(); _nop_(); _nop_();
        #endif
}

/*====================================
函數(shù):void Display(INT8U Value)
參數(shù):Value,顯示值 取值0-255
描述:共陰極數(shù)碼管顯示函數(shù)可顯示一個(gè)字節(jié)的數(shù)
====================================*/
void Display(INT8U Value)
{
//------------------------------
        DU = 1;
        P0 = table[Value/100];        //管顯示百位
        DU = 0;

        P0 = 0xff;                                  //清除斷碼

        WE = 1;
        P0 = T_COM[0];                          //第一位數(shù)碼管
        WE = 0;
        Delay_Ms(5);
//-------------------------------
        DU = 1;
        P0 = table[Value%100/10]; //顯示十位
        DU = 0;

        P0 = 0xff;                                  //清除斷碼

        WE = 1;
        P0 = T_COM[1];                          //第二位數(shù)碼管
        WE = 0;
        Delay_Ms(5);
//-------------------------------
        DU = 1;
        P0 = table[Value%10];                //顯示個(gè)位
        DU = 0;
                                                               
        P0 = 0xff;                                        //清除斷碼

        WE = 1;
        P0 = T_COM[2];                                //第三位數(shù)碼管
        WE = 0;
        Delay_Ms(5);
}

/*====================================
函數(shù):I2C_init()
描述:I2C總線初始化
====================================*/
void I2C_init()
{
        SDA = 1;   //數(shù)據(jù)總線高
        _nop_();
        SCL = 1;   //時(shí)鐘總線高
        _nop_();
}

/*====================================
函數(shù):I2C_Start()
描述:I2C起始信號(hào)
====================================*/
void I2C_Start()  
{
        SCL = 1;
        _nop_();
        SDA = 1;
        Delay5us();
        SDA = 0;
        Delay5us();
}

/*====================================
函數(shù):I2C_Stop()
描述:I2C停止信號(hào)
====================================*/
void I2C_Stop()
{
        SDA = 0;
        _nop_();
        SCL = 1;
        Delay5us();
        SDA = 1;
        Delay5us();
}

/*====================================
函數(shù):Master_ACK(bit i)
參數(shù):i 為0時(shí)發(fā)送非應(yīng)答 為1時(shí)發(fā)送應(yīng)答
描述:I2C主機(jī)發(fā)送應(yīng)答
====================================*/
void Master_ACK(bit i)       
{
        SCL = 0; // 拉低時(shí)鐘總線允許SDA數(shù)據(jù)總線上的數(shù)據(jù)變化
        _nop_(); // 讓總線穩(wěn)定
        if (i)         //如果i = 1 那么拉低數(shù)據(jù)總線 表示主機(jī)應(yīng)答
        {
                SDA = 0;
        }
        else         
        {
                SDA = 1;         //發(fā)送非應(yīng)答
        }
        _nop_();//讓總線穩(wěn)定
        SCL = 1;//拉高時(shí)鐘總線 讓從機(jī)從SDA線上讀走 主機(jī)的應(yīng)答信號(hào)
        Delay5us();
        SCL = 0;//拉低時(shí)鐘總線, 占用總線繼續(xù)通信
        _nop_();
        SDA = 1;//釋放SDA數(shù)據(jù)總線。
        _nop_();
}

/*====================================
函數(shù):Test_ACK()
返回:0為非應(yīng)答 1為應(yīng)答
描述:I2C檢測(cè)從機(jī)應(yīng)答
====================================*/
bit Test_ACK()         // 檢測(cè)從機(jī)應(yīng)答
{
        SCL = 1;//時(shí)鐘總線為高電平期間可以讀取從機(jī)應(yīng)答信號(hào)
        Delay5us();
        if (SDA)
        {
                SCL = 0;
                I2C_Stop();
                return(0);
        }
        else
        {
                SCL = 0;
                return(1);
        }
}

/*====================================
函數(shù):I2C_send_byte(uchar byte)
參數(shù):byte 要發(fā)送的字節(jié)
描述:I2C發(fā)送一個(gè)字節(jié)
====================================*/
void I2C_send_byte(uchar byte)
{
        uchar i;
        for(i = 0 ; i < 8 ; i++)
        {
                SCL = 0;
                _nop_();
                if (byte & 0x80)       
                {
                        SDA = 1;
                        _nop_();
                }
                else
                {
                        SDA = 0;
                        _nop_();
                }
                SCL = 1;
                _nop_();
                byte <<= 1;
        }
        SCL = 0;
        _nop_();
        SDA = 1;
        _nop_();       
}

/*====================================
函數(shù):I2C_read_byte()
返回:讀取的字節(jié)
描述:I2C讀一個(gè)字節(jié)
====================================*/
uchar I2C_read_byte()
{
        uchar i, dat;
        SCL = 0 ;
        _nop_();
        SDA = 1;
        _nop_();
        for(i = 0 ; i < 8 ; i++)
        {
                SCL = 1;
                _nop_();
                dat <<= 1;          
                if (SDA)
                {
                        dat |= 0x01;  
                }
                _nop_();
                SCL = 0;
                _nop_();
        }
        return(dat);
}

/*DAC輸出*/
bit DAC_OUT(uchar DAT)
{
        I2C_Start();
        I2C_send_byte(PCF8591_ADDR+0);
        if (!Test_ACK())
        {
                return(0);
        }
        I2C_send_byte(DACOUT_EN);        //DA輸出使能
        if (!Test_ACK())
        {
                return(0);
        }
        I2C_send_byte(DAT);
        if (!Test_ACK())
        {
                return(0);
        }
        I2C_Stop();
        return(1);       
}

/*讀AD數(shù)據(jù)*/
bit ADC_Read(uchar CON)
{
        I2C_Start();
        I2C_send_byte(PCF8591_ADDR+0);
        if (!Test_ACK())
        {
                return(0);
        }
        I2C_send_byte(CON);
        Master_ACK(0);
        I2C_Start();
        I2C_send_byte(PCF8591_ADDR+1);
        if (!Test_ACK())
        {
                return(0);
        }
        AD_Value = I2C_read_byte();
        Master_ACK(0);
        I2C_Stop();
        return(1);       
}

void main()
{
        I2C_init();
        while(1)
        {               
                //單端輸入,讀出通道2的值
                if (ADC_Read(0x02))        LED1 = 0;        else        LED1 = 1;       
                if (DAC_OUT(AD_Value))        LED2 = 0;        else        LED2 = 1;
                Display(AD_Value);
                if (AD_Value > 150)        BEEP = 0;        else        BEEP = 1;
                Delay_Ms(5);
        }       
}







回復(fù)

使用道具 舉報(bào)

ID:469417 發(fā)表于 2019-3-9 02:40 | 顯示全部樓層
所謂初始化并不是一定要達(dá)到什么目的,有時(shí)我們是在做一些聲明,有些是對(duì)一些數(shù)據(jù)進(jìn)行使用前的預(yù)處理或者是清零,方便后面的使用不會(huì)出錯(cuò),比如我們聲明一個(gè)變量的時(shí)候,我們明明知道他開始的值是0,但有時(shí)我們就是要聲明讓它等于0,道理都是一個(gè)樣。不過有的初始化就必須要做。

評(píng)分

參與人數(shù) 1黑幣 +10 收起 理由
zhengchong60 + 10 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:401564 發(fā)表于 2019-3-9 09:12 | 顯示全部樓層
這都是IIC的基礎(chǔ)知識(shí),說了也是和網(wǎng)上復(fù)制過來的一樣。
你應(yīng)該是沒有去看過IIC協(xié)議的時(shí)序圖,IIC是一個(gè)有嚴(yán)格的時(shí)序要求的通訊協(xié)議,每一步都要嚴(yán)格按照IIC的協(xié)議來走的。
推薦你去PIC的官方網(wǎng)站找一下24VL04的中文數(shù)據(jù)手冊(cè),它就是一個(gè)IIC器件,里面有對(duì)于IIC的時(shí)序圖,比較完整的。
需要說明的是“釋放SDA線”,8051的端口是默認(rèn)的雙向端口,既可以讀也可以寫。如果你把這個(gè)SDA端口變成低電平,那么你讀取這個(gè)SDA端口的狀態(tài)就只能讀取到一個(gè)低電平。但如果你把SDA拉高了,它可以讀取到高電平,如果外部是低電平的話,那么這個(gè)低電平會(huì)把SDA線拉低,讀取到的內(nèi)容就是低電平,這樣一來,CPU就可以正確的讀取到SDA的電平狀態(tài)了。
這個(gè)操作只在8051這類默認(rèn)端口為雙向的單片機(jī)上用到,如果是別的單片機(jī)(像PIC這種)就沒有這個(gè)操作了,PIC的端口是要去設(shè)定這個(gè)端口是讀取的還是輸出的,設(shè)定為讀取了就不能輸出了,設(shè)定為輸出了就讀取不到外部的信號(hào)了。

評(píng)分

參與人數(shù) 1黑幣 +10 收起 理由
zhengchong60 + 10 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:485870 發(fā)表于 2019-3-11 19:15 | 顯示全部樓層
刀刀見紅 發(fā)表于 2019-3-9 02:40
所謂初始化并不是一定要達(dá)到什么目的,有時(shí)我們是在做一些聲明,有些是對(duì)一些數(shù)據(jù)進(jìn)行使用前的預(yù)處理或者是 ...

謝謝您!
回復(fù)

使用道具 舉報(bào)

ID:485870 發(fā)表于 2019-3-11 19:16 | 顯示全部樓層
Y_G_G 發(fā)表于 2019-3-9 09:12
這都是IIC的基礎(chǔ)知識(shí),說了也是和網(wǎng)上復(fù)制過來的一樣。
你應(yīng)該是沒有去看過IIC協(xié)議的時(shí)序圖,IIC是一個(gè)有 ...

十分感謝
回復(fù)

使用道具 舉報(bào)

ID:142059 發(fā)表于 2019-3-11 21:13 來自手機(jī) | 顯示全部樓層
不管哪種通訊協(xié)議,總線在空閑的時(shí)候,都是高電平,為什么?因?yàn)閕o口內(nèi)部的設(shè)計(jì)原因,只有高電平能被拉低成低電平,而低電平是不能被拉高成高電平的,因?yàn)槔褪莾?nèi)部mos管直接導(dǎo)通,等效io接在GND,所以怎么拉高都不會(huì)變成高電平。所以我們要用高電平表示空閑,這樣我們要傳輸數(shù)據(jù)的時(shí)候,把總線拉低一下就可以表示要準(zhǔn)備傳輸數(shù)據(jù)了。所以要初始化為高電平。而有的人還有疑問,51單片機(jī)io口開機(jī)狀態(tài)就是高電平啊,初始化再設(shè)置高電平不是多此一舉么?是的,在開機(jī)為高電平的單片機(jī)里是多此一舉,但是有的單片機(jī)開機(jī)后,io口是浮空狀態(tài)的,也就是電平不確定的狀態(tài),這時(shí)候的初始化就很重要了。說了這么多,不知道你有沒有理解。

評(píng)分

參與人數(shù) 2黑幣 +55 收起 理由
_nop_() + 5 很給力!
admin + 50 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:162622 發(fā)表于 2019-3-11 23:47 | 顯示全部樓層
IIC的應(yīng)答是誰接收數(shù)據(jù)(或命令)誰應(yīng)答,因而就有主機(jī)應(yīng)答與從機(jī)應(yīng)答之分,最后一次接收完可以不應(yīng)答給停止信號(hào)
回復(fù)

使用道具 舉報(bào)

ID:473159 發(fā)表于 2019-3-12 06:29 來自手機(jī) | 顯示全部樓層
初始化又不妨礙你什么你干嘛要那樣斤斤計(jì)較

評(píng)分

參與人數(shù) 1黑幣 +15 收起 理由
正規(guī)007 + 15 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:449525 發(fā)表于 2019-3-12 08:24 | 顯示全部樓層
大家都在2跟線上。如何通信?如何判斷是你在發(fā)送還是在接受?所以要規(guī)定下。
回復(fù)

使用道具 舉報(bào)

ID:370231 發(fā)表于 2019-3-12 10:19
51黑論壇_iic協(xié)議.pdf (7.15 MB, 下載次數(shù): 0)

ID:471782 發(fā)表于 2019-3-12 12:00 來自手機(jī) | 顯示全部樓層
建議樓主在網(wǎng)上找個(gè)iic的協(xié)議資料好好看下
回復(fù)

使用道具 舉報(bào)

ID:485870 發(fā)表于 2019-3-14 20:55 | 顯示全部樓層
Angle145 發(fā)表于 2019-3-11 21:13
不管哪種通訊協(xié)議,總線在空閑的時(shí)候,都是高電平,為什么?因?yàn)閕o口內(nèi)部的設(shè)計(jì)原因,只有高電平能被拉低成 ...

非常感謝您的幫助,這點(diǎn)理解到了
回復(fù)

使用道具 舉報(bào)

ID:485870 發(fā)表于 2019-3-14 21:03 | 顯示全部樓層
Y_G_G 發(fā)表于 2019-3-9 09:12
這都是IIC的基礎(chǔ)知識(shí),說了也是和網(wǎng)上復(fù)制過來的一樣。
你應(yīng)該是沒有去看過IIC協(xié)議的時(shí)序圖,IIC是一個(gè)有 ...

我看了時(shí)序圖手冊(cè)的,感覺代碼并沒有完全按照時(shí)序圖的要求來
回復(fù)

使用道具 舉報(bào)

ID:485870 發(fā)表于 2019-3-14 21:15 | 顯示全部樓層
Angle145 發(fā)表于 2019-3-11 21:13
不管哪種通訊協(xié)議,總線在空閑的時(shí)候,都是高電平,為什么?因?yàn)閕o口內(nèi)部的設(shè)計(jì)原因,只有高電平能被拉低成 ...

能加一下qq嗎?以后遇到的問題還希望有人能幫幫忙,謝謝
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久国| 久久国产视频网站 | 中文字幕第一页在线 | 米奇成人网 | 国产午夜精品一区二区三区四区 | 中文字幕久久精品 | 欧美一区二区在线观看 | 超碰成人免费观看 | 欧美日韩亚洲一区 | 成人欧美一区二区三区在线播放 | 欧美三级久久久 | 日日操夜夜操视频 | 自拍偷拍第一页 | 一区二区三区精品 | 亚洲第一黄色网 | 台湾佬伊人 | 激情一区| 精品久久久久久久人人人人传媒 | 五月综合久久 | 成人免费在线观看视频 | 一二三四在线视频观看社区 | 最新一级毛片 | 成人在线欧美 | 久久久久国产精品 | 99热视 | 国产成人一区二区三区久久久 | 精一区二区 | 国产亚洲精品一区二区三区 | 欧美一区二区在线视频 | 四虎在线播放 | 亚洲国产精品一区二区三区 | 国产成人在线视频 | 精品九九在线 | 免费a网 | 亚洲九九精品 | 中日av| 日韩一区和二区 | 中文字幕在线观看一区二区 | 韩国久久| 久久久久综合 | 亚洲一区在线播放 |