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

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

QQ登錄

只需一步,快速開(kāi)始

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

51單片機(jī)和24C16

[復(fù)制鏈接]
ID:217830 發(fā)表于 2017-7-7 10:17 | 顯示全部樓層 |閱讀模式
1.     24C16 E2PROM簡(jiǎn)介
24C16是一個(gè)16K位串行CMOSE2PROM,內(nèi)部含有2048個(gè)8位字節(jié),它有一個(gè)16字節(jié)的頁(yè)寫(xiě)緩沖器,該器件通過(guò)I2C總線(xiàn)接口進(jìn)行操作,有一個(gè)專(zhuān)門(mén)的寫(xiě)保護(hù)功能引腳。在本實(shí)驗(yàn)系統(tǒng)中,24C16的接口電路如4-4所示。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gif
4-4 24C16的接口電路
4-4可看出,24C16的接口電路非常簡(jiǎn)單,只引出了2根控制線(xiàn)SDASCLJ6。各引腳功能簡(jiǎn)單描述如下:
SCL:串行時(shí)鐘。24C16串行時(shí)鐘輸入管腳,用于產(chǎn)生器件數(shù)據(jù)收發(fā)的時(shí)鐘;
SDA:串行數(shù)據(jù)/地址。24C16雙向串行數(shù)據(jù)/地址管腳用于器件所有的收據(jù)收發(fā)。SDA是一個(gè)開(kāi)漏輸出管腳,可與其它開(kāi)漏輸出或集電極開(kāi)路輸出進(jìn)行線(xiàn)或(wire-OR);
A0A1A2:器件地址輸入。這些輸入腳用于多個(gè)器件掛接在同一對(duì)I2C總線(xiàn)上時(shí)設(shè)置器件地址,以便主控器件識(shí)別。當(dāng)這些引腳懸空時(shí)其默認(rèn)值為0
WP:寫(xiě)保護(hù)。當(dāng)WP腳連接到VCC時(shí),所有內(nèi)存變成寫(xiě)保護(hù)(只能讀)。當(dāng)WP引腳連接到VSS或懸空時(shí),允許器件進(jìn)行讀/寫(xiě)操作。
2.     I2C總線(xiàn)接口的特性
I2C接口的信息傳輸僅需要SDASCL兩條線(xiàn),均為雙向I/O口,通過(guò)上拉電阻接正電源。當(dāng)總線(xiàn)空閑時(shí),兩根線(xiàn)都是高電平。接入總線(xiàn)器件的輸出必須是集電極或漏極開(kāi)路方式的,即具有線(xiàn)“與”功能。
I2C總線(xiàn)是一個(gè)半雙工、多主器件的總線(xiàn),即總線(xiàn)上可以連接多個(gè)可控制總線(xiàn)的器件。總線(xiàn)上發(fā)送數(shù)據(jù)的發(fā)送器(主器件)與接收數(shù)據(jù)的接收器(從器件)的角色不是一成不變的,而是取決于當(dāng)時(shí)數(shù)據(jù)傳送的方向。當(dāng)一個(gè)器件開(kāi)始一個(gè)總線(xiàn)周期,尋址其它器件并發(fā)送數(shù)據(jù)時(shí),它就是發(fā)送器,其他被尋址器件均作為接收器存在。
I2C總線(xiàn)進(jìn)行數(shù)據(jù)傳送時(shí),每一位數(shù)據(jù)都與時(shí)鐘脈沖相對(duì)應(yīng),在時(shí)鐘信號(hào)高電平期間,數(shù)據(jù)線(xiàn)上必須保持穩(wěn)定的邏輯電平。只有在時(shí)鐘線(xiàn)為低電平時(shí),才允許數(shù)據(jù)線(xiàn)的電平發(fā)生變化。
3.     I2C總線(xiàn)的時(shí)序
一次完整的I2C總線(xiàn)時(shí)序過(guò)程由起始信號(hào)、從器件地址信號(hào)、應(yīng)答信號(hào)ACK、字節(jié)數(shù)據(jù)信號(hào)和停止信號(hào)等幾部分組成。
(1)     起始和停止信號(hào)
在一次通信過(guò)程中,應(yīng)該有一個(gè)起始信號(hào)和一個(gè)停止信號(hào)。在I2C總線(xiàn)協(xié)議中,起始信號(hào)(S)和停止信號(hào)(P)都是由主器件產(chǎn)生的。起始信號(hào)表明一次I2C總線(xiàn)傳送的開(kāi)始,停止信號(hào)則表明I2C總線(xiàn)通信結(jié)束。當(dāng)SCL線(xiàn)為高電平時(shí),SDA線(xiàn)由高電平到低電平的負(fù)跳變被定義為起始信號(hào),而SDA由低電平到高電平的正跳變?yōu)橥V剐盘?hào)。I2C總線(xiàn)的起始和停止信號(hào)時(shí)序如4-5所示。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.gif
4-5 I2C總線(xiàn)起始信號(hào)和停止信號(hào)的時(shí)序
當(dāng)總線(xiàn)上出現(xiàn)起始信號(hào)后,就認(rèn)為總線(xiàn)處于工作狀態(tài);總線(xiàn)上出現(xiàn)停止信號(hào),總線(xiàn)就被認(rèn)為是處在空閑狀態(tài)。如果連接到總線(xiàn)上的設(shè)備具有I2C的接口硬件,那么檢測(cè)起始和停止信號(hào)的過(guò)程將由硬件自動(dòng)完成。但是,如果微處理器沒(méi)有I2C硬件接口電路,則必須由軟件檢測(cè)電平的跳變判斷起始與停止信號(hào)。
(2)     器件地址
I2C總線(xiàn)上的每一個(gè)器件均有一個(gè)唯一的地址。每次發(fā)送器發(fā)出起始信號(hào)后,必須接著發(fā)出一個(gè)字節(jié)的地址信息,以選取連接在總線(xiàn)上的某一從機(jī)。地址字節(jié)用“從器件地址+ R/W(____)”表示。從器件地址是7bit的器件地址編碼,占用字節(jié)的高7位(D7D1);D0位是數(shù)據(jù)的傳送方向位,又稱(chēng)讀/寫(xiě)選擇位,用R/W(____)表示,當(dāng)R/W(____)=0時(shí),表示主器件向從器件寫(xiě)數(shù)據(jù)(發(fā)送數(shù)據(jù));R/W(____)=1時(shí),表示主器件從從器件讀取數(shù)據(jù)(接收數(shù)據(jù))。
從器件地址由一個(gè)固定部分和一個(gè)可編程部分組成。固定部分為器件的標(biāo)識(shí),表明器件類(lèi)型,在出廠時(shí)設(shè)置。可編程部分為器件的地址,用以區(qū)分連接在同一I2C總線(xiàn)上的同類(lèi)器件。器件的地址由硬件接線(xiàn)而定,只有主器件送來(lái)的地址信息中的可編程部分和從器件的地址引腳狀態(tài)一致,該器件才會(huì)響應(yīng)總線(xiàn)的操作。例如E2PROM器件24C16的地址格式如下:
D7
D6
D5
D4
D3
D2
D1
D0
1
0
1
0
A2
A1
A0
R/W(____)
其中:高四位1010E2PROM器件標(biāo)識(shí)類(lèi)型,A2A0為引腳地址,對(duì)應(yīng)于該芯片引腳A2A0的接線(xiàn),最低位為讀寫(xiě)選擇比特。當(dāng)A2A0引腳均接低電平時(shí),該器件的地址為A0HA1H,主器件訪(fǎng)問(wèn)地址0xA0表示寫(xiě)數(shù)據(jù)到該器件,訪(fǎng)問(wèn)0xA1表示從該器件讀數(shù)據(jù)。
(3)     應(yīng)答信號(hào)ACK
I2C總線(xiàn)上的發(fā)送器發(fā)送完地址字節(jié)和每一個(gè)字節(jié)數(shù)據(jù)后,接收器都必須產(chǎn)生一個(gè)應(yīng)答信號(hào),應(yīng)答的器件在第9個(gè)時(shí)鐘周期時(shí)將SDA線(xiàn)拉低,表示已收到一個(gè)8位數(shù)據(jù)。
與應(yīng)答信號(hào)相對(duì)應(yīng)的第9個(gè)時(shí)鐘由發(fā)送器產(chǎn)生,發(fā)送器必須在輸出該時(shí)鐘時(shí)釋放數(shù)據(jù)線(xiàn)SDA,使其處于高阻狀態(tài),以便接收器在SDA線(xiàn)上輸出低電平應(yīng)答信號(hào)(ACK),表示繼續(xù)接收。若接收器輸出高電平則為非應(yīng)答信號(hào)(NO ACK),表示結(jié)束接收。
如果是主器件在接收數(shù)據(jù),例如當(dāng)從器件為存儲(chǔ)器,主器件讀從器件中的數(shù)據(jù)時(shí),它收到最后一個(gè)數(shù)據(jù)字節(jié)后,必須向從器件發(fā)送一個(gè)非應(yīng)答信號(hào)(NO ACK),使從器件釋放SDA線(xiàn),以便主器件產(chǎn)生終止信號(hào),停止數(shù)據(jù)傳送。
I2C總線(xiàn)的數(shù)據(jù)應(yīng)答時(shí)序如4-6所示。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image006.gif
4-6 I2C總線(xiàn)應(yīng)答時(shí)序
(4)     數(shù)據(jù)字節(jié)信號(hào)
利用I2C總線(xiàn)進(jìn)行數(shù)據(jù)傳送時(shí),傳送的字節(jié)數(shù)是沒(méi)有限制的,但是每一個(gè)字節(jié)必須保證是8位長(zhǎng)度,并且首先發(fā)送數(shù)據(jù)的最高位,每傳送一個(gè)字節(jié)數(shù)據(jù)后都必須跟隨一位應(yīng)答脈沖,即接收器發(fā)回的應(yīng)答信號(hào)ACK。然后由發(fā)送器繼續(xù)發(fā)送數(shù)據(jù)字節(jié)或發(fā)出停止信號(hào)P后結(jié)束數(shù)據(jù)的傳送。如果接收器不能接收下一個(gè)字節(jié),例如正在處理一個(gè)外部中斷,可以把SCL線(xiàn)拉成低電平,迫使發(fā)送器處于等待狀態(tài)。當(dāng)從機(jī)準(zhǔn)備好接收下一個(gè)字節(jié)時(shí)再釋放時(shí)鐘線(xiàn)SCL,使數(shù)據(jù)傳輸繼續(xù)進(jìn)行。連續(xù)發(fā)送多字節(jié)數(shù)據(jù)的格式如4-7所示。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image008.gif
4-7 I2C總線(xiàn)多字節(jié)操作時(shí)序
4.     單片機(jī)通過(guò)IO端口模擬I2C總線(xiàn)時(shí)序操作24Cxx系列E2PROM的接口程序
參考I2C總線(xiàn)的時(shí)序以及24Cxx芯片的數(shù)據(jù)手冊(cè),可設(shè)計(jì)出單片機(jī)通過(guò)IO端口模擬I2C總線(xiàn)時(shí)序控制24Cxx系列E2PROM的接口程序。程序分為24Cxx.H24Cxx.C兩部分。24Cxx.H文件用來(lái)做函數(shù)說(shuō)明和常量定義等,可供最終的調(diào)用程序包含,24Cxx.C文件為各功能函數(shù)的具體實(shí)現(xiàn)。程序列表如下:
文件:24Cxx.H
#ifndef __24Cxx__
#define __24Cxx__
#define ERRORCOUNT  10
enum E2PROMType{M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256};
void Delay(unsigned char);
void I2CStart(void);
void I2CStop(void);
bit I2CRecAck(void);
void I2CNoAck(void);
void I2CAck(void);
unsigned char I2CReceiveByte(void);
void I2CSendByte(unsigned char);
bit RWE2PROM(unsigned char *, unsigned char, unsignedint, unsigned char, enum E2PROMType);
#endif
文件:24Cxx.C
#include <reg51.h>
#include <intrins.h>
#include "24Cxx.h"
sbit    SDA =P1^0;
sbit    SCL =P1^1;                         // 模擬總線(xiàn)接口引腳,可根據(jù)實(shí)際電路修改
enum    EEPROMTypeEepromType;
/************************************************************************
函數(shù)說(shuō)明:24C01~24C2569E2PROM的讀寫(xiě)操作函數(shù)。
參數(shù)說(shuō)明:讀寫(xiě)數(shù)據(jù)緩沖區(qū)指針,讀寫(xiě)的字節(jié)數(shù),E2PROM首址,EEPROM控制字節(jié),E2PROM類(lèi)型
************************************************************************/
bit RWE2PROM(   unsignedchar *Buf,
                unsignedchar Bytes,
                unsignedint Address,
                unsignedchar ControlByte,
                enumE2PROMType EepromType)
{
    unsigned chardata j,i = ERRORCOUNT;
   
    bit errorflag= 1;
   
    while(i--)
    {
        I2CStart();                         // 首先選擇器件及設(shè)置器件的內(nèi)部地址
        I2CSendByte(ControlByte&0xfe);
        if(I2CRecAck())continue;
        if(EepromType>M2416)
        {
            I2CSendByte((unsignedchar)(Address>>8));
            if(I2CRecAck())continue;
        }
        I2CSendByte((unsignedchar)Address);
        if(I2CRecAck())continue;
        
        if(!(ControlByte&0x01))             // 判斷進(jìn)行的是否是寫(xiě)操作
        {                                   // 是寫(xiě)操作
            j =Bytes;
            errorflag= 0;                  // 清除錯(cuò)誤標(biāo)志
            
            while(j--)
            {
                I2CSendByte(*Buf++);
                if(!I2CRecAck())continue;
                errorflag= 1;
                 break;
            }
            
            if(errorflag==1)continue;
            break;
        }
        else                                // 是讀操作
        {
            I2CStart();
            I2CSendByte(ControlByte);
            if(I2CRecAck())continue;
            
            while(--Bytes)
            {
                *Buf++= I2CReceiveByte();
                I2CAck();
            }
            
            *Buf= I2CReceiveByte();        // 讀最后一個(gè)字節(jié)
            I2CNoAck();
            errorflag= 0;
            break;
        }
    }
   
    I2CStop();                              // 向總線(xiàn)送停止信號(hào)
    if(!(ControlByte&0x01))                 // 判斷剛才進(jìn)行的是否為寫(xiě)操作
    {
        Delay(255);                         // 如果是寫(xiě)操作,延時(shí)以等待E2PROM
        Delay(255);                         //完成擦寫(xiě)過(guò)程。具體延時(shí)長(zhǎng)度可參考
    }                                       // 數(shù)據(jù)手冊(cè)并根據(jù)實(shí)際情況加以調(diào)整。
    return(errorflag);
}
/********************以下是模擬I2C總線(xiàn)操作時(shí)序的子程序********************/
// 啟動(dòng)I2C總線(xiàn)
void I2CStart(void)
{
    SCL=0; SDA=1;SCL=1;                    // 參見(jiàn)I2C總線(xiàn)的Start狀態(tài)
    _nop_();
    SDA=0;                                  // 少許延時(shí),等待總線(xiàn)信號(hào)穩(wěn)定
    _nop_();
    SCL=0;
    SDA=1;
}
// 停止I2C總線(xiàn)
void I2CStop(void)
{
    SCL=0; SDA=0;SCL=1;
    _nop_();
    SDA=1;
    _nop_();
    SCL=0;
}
// 檢查ACK信號(hào)
bit I2CRecAck(void)
{
    SCL=0; SDA=1;SCL=1;
    _nop_();
    CY=SDA;                                 // 結(jié)果放入進(jìn)位位:PSW的一位
    SCL=0;
    return(CY);
}
// I2C總線(xiàn)上產(chǎn)生ACK信號(hào)
void I2CACK(void)
{
    SDA=0; SCL=1;
    _nop_();
    SCL=0;
    _nop_();
    SDA=1;
}
// I2C總線(xiàn)上產(chǎn)生NOACK信號(hào)
void I2CNoAck(void)
{
    SDA=1;
    SCL=1;
    _nop_();
    SCL=0;
}
// I2C總線(xiàn)寫(xiě)數(shù)據(jù)
void I2CSendByte(unsigned char sendbyte)
{
    unsigned chardata j = 8;
    for(;j>0;j--)
    {
        SCL=0;
        sendbyte<<=1;
        SDA=CY;
        SCL=1;
    }
    SCL=0;
}
// I2C總線(xiàn)讀數(shù)據(jù)
unsigned char I2CReceiveByte(void)
{
    registerreceivebyte,i=8;
    SCL=0;  
    while(i--)
    {
        SCL=1;
       //延時(shí)4.7us穩(wěn)定數(shù)據(jù)
        receivebyte=(receivebyte<<1)|SDA;
        SCL = 0;
    }
    return(receivebyte);
}
// 循環(huán)延時(shí)函數(shù)
void Delay(unsigned char DelayCount)
{
    while(DelayCount--);
}
在實(shí)際項(xiàng)目中使用24Cxx系列E2PROM接口函數(shù)時(shí)主控程序只要包含24Cxx.H,并將24Cxx.C加入到工程中即可。
一、    實(shí)驗(yàn)過(guò)程
1.     電路連接
CPU板上的單片機(jī)P1.0J2J61號(hào)引腳)和模擬總線(xiàn)接口IO板上24C16SDAJ61號(hào)引腳)相連;
CPU板上的單片機(jī)P1.1J2J62號(hào)引腳)和模擬總線(xiàn)接口IO板上24C16SCLJ62號(hào)引腳)相連;
CPU板上的COM1PC機(jī)的串行口相連。
2.     程序設(shè)計(jì)
根據(jù)實(shí)驗(yàn)要求,設(shè)計(jì)實(shí)驗(yàn)代碼如下:
#include <reg51.h>
#include <stdio.h>
#include <string.h>
#include "24Cxx.h"
#define OSC         11059200
#define BAUDRATE    9600
void main(void)
{
    char Buf[32];
    int i;
    bit bb;
   
    TMOD = 0x20;
    SCON = 0x50;
    PCON |= 0x80;
    TL1 =256-(OSC/12/16/BAUDRATE);
    TH1 =256-(OSC/12/16/BAUDRATE);
    TR1 = 1;
    TI = 1;
   
    printf("\r\nTesting24Cxx...");
   
    bb =RW24XX(Buf,16,0,0xA1,M2416);
   
    if(bb == 0)
    {
        printf("\r\nReaded!\r\n");
        for(i=0;i<16;i++)printf("%02bX ",Buf);
        printf("| ");
        for(i=0;i<16;i++)printf("%c",Buf);
    }
    elseprintf("\r\nRead failed!");
   
    printf("\r\nEnterto write to 24Cxx...");
    scanf("%s",Buf);
    bb =RW24XX(Buf,strlen(Buf),0,0xA0,M2416);
   
    if(bb == 0)printf("\r\nWrite success...");
    elseprintf("\r\nWrite failed...");
   
    while(1);
}
3.     驗(yàn)證結(jié)果
按實(shí)驗(yàn)要求連接好電路,在Keil中建立新工程,將上述程序代碼加入工程,編譯鏈接后,將生成的HEX文件燒寫(xiě)到單片機(jī)中;
PC機(jī)的串行口和單片機(jī)的串行口相連,打開(kāi)超級(jí)終端并設(shè)置波特率等參數(shù);
復(fù)位單片機(jī)即可接收到單片機(jī)輸出的24C16的數(shù)據(jù)。根據(jù)提示在PC機(jī)輸入數(shù)據(jù),按回車(chē)發(fā)送后可觀察到單片機(jī)寫(xiě)24C16的結(jié)果。如果寫(xiě)入正確,再次復(fù)位單片機(jī)后即可接收到單片機(jī)讀出的上次寫(xiě)入24C16的數(shù)據(jù)。

回復(fù)

使用道具 舉報(bào)

ID:674764 發(fā)表于 2021-11-21 22:01 | 顯示全部樓層
別的講的挺好,就是程序里IIC的 START與STOP時(shí)序不對(duì)哦!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 我要看一级黄色片 | www.青青草.com | 欧美美女性生活 | www色| av在线天堂 | 国产精品一区二区三区免费 | 日韩伦理视频 | 日本中文字幕在线观看 | 欧美一级欧美三级在线观看 | 日韩精品一区在线 | 欧美精品99| 欧产日产国产69 | 亚洲一区二区 | 免费一级片 | 国产精品一区二区三 | 精品一区在线播放 | 超碰在线中文字幕 | 亚洲天堂色图 | 婷婷久久五月天 | 成人黄性视频 | 岛国av免费观看 | 久久精品久久久久久久 | www黄色片 | 亚洲a级片| 国产精品手机在线观看 | 黄色av日韩 | 性生活网址 | 在线免费看黄色 | 久久国产一区二区三区 | 欧美日本精品 | 欧美美女视频 | 九月丁香婷婷 | h片免费看 | 国产一区在线视频 | 在线a| 欧美性猛交xxxx乱大交退制版 | 亚洲区在线 | 欧美精品一区在线 | 久久精品av | 欧美理论在线观看 | 右手影院亚洲欧美 |