新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > PIC IIC & 24c02

        PIC IIC & 24c02

        作者: 時間:2016-11-21 來源:網絡 收藏
        #include //調用頭文件,可以去PICC18軟件下去查找PIC18FXX2.H
        __CONFIG(1,XT) ; //晶振為外部4M
        __CONFIG(2,WDTDIS) ; //看門狗關閉
        __CONFIG(4,LVPDIS) ; //禁止低電壓編程
        #define uint unsigned int
        #define uchar unsigned char
        #define nop NOP()
        #define scl RC3 //時鐘線
        #define sda RC4 //數據線
        char shuma[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
        uint count=0;
        uchar sec;
        void usdelay()
        {
        nop; //其實在用IIC對EEPROM操作時,它反應很快,延時可以很短,但必須延時,只要一個NOP()就可以了
        }
        void init_24c() //初始化24C,就是把兩根線拉高
        {
        TRISC4=0;
        scl=1;
        sda=1;
        usdelay();
        }

        void start() //開始信號,根據時序圖(sx)
        {
        TRISC4=0;
        scl=1;
        usdelay();
        sda=1;
        usdelay();
        sda=0;
        }
        void stop() //結束信號 sx
        {
        TRISC4=0;
        scl=1;
        usdelay();
        sda=0;
        usdelay();
        sda=1;
        }
        void ack() //不知道為什么,在PIC中不能用ack,好像一用就會出錯= =?
        {
        uchar i;
        TRISC4=0;
        sda=1;
        nop;
        TRISC4=1;
        scl=1;
        nop;
        while(sda==1&&i<10)i++;
        scl=0;
        }

        void write_byte(uchar dat) //寫字節 sx 由于不僅要寫數據,還要寫地址,所以只能先寫字節的最高位R7,最后寫最低位R0
        {
        uchar i;
        TRISC4=0;
        sda=0;
        scl=0;
        nop;
        for(i=0;i<=8;i++)
        {
        sda=(dat&0x80)>>7;
        nop;
        scl=1;
        nop;
        scl=0;
        dat<<=1;
        nop;
        }
        }
        uchar read_byte() //讀字節 sx 先讀高位R7,最后讀地位R0
        {
        uchar i,dat=0;
        TRISC4=1;
        sda=0;
        usdelay();
        scl=1;
        usdelay();
        for(i=0;i<8;i++)
        {
        dat<<=1;
        usdelay();
        scl=1;
        nop;
        dat=dat|sda;
        nop;
        scl=0;
        usdelay();
        }
        return dat;
        }


        void write_add(uchar add,uchar dat) //寫數據到地址 sx 注意不要用ack
        {
        start();
        write_byte(0xa0);
        write_byte(add);
        write_byte(dat);
        stop();
        }


        uchar read_add(uchar add) //從地址讀數據 sx 注意不要用ack
        {
        uchar dat;
        start();
        write_byte(0xa0);
        write_byte(add);
        start();
        write_byte(0xa1);
        dat=read_byte();
        stop();
        return dat;
        }
        void interrupt kaito() //定時器中斷0
        {
        if(TMR0IF==1)
        {
        TMR0IF=0;
        TMR0=0xff13;
        count++;
        if(count==4000)
        {
        count=0;
        sec++;
        if(sec>9)
        sec=0;
        write_add(0x10,sec); //每次要顯示的數據發生變化,就寫入到24c02中存起來,方便斷電后保留
        }
        }
        }
        void main(void)
        {
        sec=0;
        ADCON1=0X06;
        TRISD=0x00;
        TRISC3=0;
        TRISC4=0;
        init_24c();
        GIE=1;
        IPEN=0;
        TMR0IE=1;
        TMR0IF=0;
        T0CON=0x88;
        TMR0=0xff13;
        GIE=1;
        sec=read_add(0x10);
        while(1)
        {
        PORTD=shuma[sec];
        }
        }
        就是感覺很奇怪,為什么不能用attack,時序圖上明明有,可是一寫上就是錯的= =?
        達到效果,定時器計數,數碼管顯示,如果關機或者復位,數碼管從關機前的數開始繼續計數。
        如果對一個地址以前沒有用過,它里面存的是出廠時設置在里面的數據,很多是ff,如果不對它做正確的寫入,讀出的數據就會是ff,如果用1602來顯示,要取十位和個位,都是f,在加上顯示時的0x30,就變成0x59,和0x35,顯示出來的就是I5
        還有在定時器中斷中要寫入多個數據,必須按照條件分開寫入,同時寫入的話會有幾條語句可能寫入失敗。


        關鍵詞: PICIIC24c0

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 崇阳县| 铜山县| 渝北区| 长汀县| 五大连池市| 海林市| 佛坪县| 富源县| 冀州市| 嘉定区| 郁南县| 额尔古纳市| 农安县| 天台县| 黑龙江省| 成武县| 马边| 镇沅| 阿拉善右旗| 寻乌县| 马山县| 梁河县| 会同县| 岳阳县| 巴林右旗| 五峰| 临颍县| 宜兰县| 桐柏县| 温宿县| 福安市| 绿春县| 嘉祥县| 河西区| 惠州市| 遂宁市| 丁青县| 囊谦县| 乌什县| 绥阳县| 防城港市|