標(biāo)題: DS18B20怎么調(diào)用I2C通訊協(xié)議實現(xiàn)閘值的掉電存儲 [打印本頁]

作者: 菜鳥9    時間: 2023-6-28 21:01
標(biāo)題: DS18B20怎么調(diào)用I2C通訊協(xié)議實現(xiàn)閘值的掉電存儲
#include <REGX51.H>
sbit I2C_SCL = P1^3;
sbit I2C_SDA = P1^4;

I2C:
//延時
void delay_us(unsigned char i)
{
        while(i--);
}

// 開始信號:在I2C_SCL時鐘信號在高電平期間I2C_SDA信號產(chǎn)生一個下降沿
void I2C_Start()
{
        I2C_SDA=1;
        delay_us(1);
        I2C_SCL=1;
        delay_us(1);//保持時間>4.7us
        I2C_SDA=0;
        delay_us(1);//保持時間是>4us
        I2C_SCL=0;                       
        delay_us(1);               
}

//結(jié)束信號:在I2C_SCL時鐘信號高電平期間I2C_SDA信號產(chǎn)生一個上升沿
void I2C_Stop()
{
        I2C_SDA=0;
        delay_us(1);
        I2C_SCL=1;
        delay_us(1);
        I2C_SDA=1;
        delay_us(1);               
}

//通過I2C發(fā)送一個字節(jié)。在I2C_SCL時鐘信號高電平期間, 保持發(fā)送信號I2C_SDA保持穩(wěn)定
unsigned char I2C_SendByte(unsigned char dat, unsigned char ack)
{
        unsigned char a = 0,b = 0;                       
        for(a=0; a<8; a++)//要發(fā)送8位,從最高位開始
        {
                I2C_SDA=dat>>7;         
                dat=dat<<1;//傳輸
                delay_us(1);
                I2C_SCL=1;
                delay_us(1);
                I2C_SCL=0;
                delay_us(1);       
        }
                I2C_SDA=1;
                delay_us(1);
                I2C_SCL=1;
                delay_us(1);
                while(I2C_SDA&&(ack==1))//等待應(yīng)答
        {
                b++;
                if(b>255)         //如果超過255us沒有應(yīng)答發(fā)送失敗,或者為非應(yīng)答,表示接收結(jié)束
                {
                        I2C_SCL=0;
                        delay_us(1);
                        return 0;
                }
        }
        I2C_SCL=0;
        delay_us(1);
        return 1;       
}

// 使用I2c讀取一個字節(jié)
unsigned char I2C_ReadByte()
{
        unsigned char a = 0,dat = 0;
        I2C_SDA = 1;//時序
        delay_us(1);       
        for(a=0; a<8; a++)//接收8個字節(jié)
        {
                I2C_SCL = 1;
                delay_us(1);       
                dat<<=1;
                dat|=I2C_SDA;
                delay_us(1);       
                I2C_SCL=0;
                delay_us(1);       
        }
        return dat;               
}

//往24c02的一個地址寫入一個數(shù)據(jù)
void At24c02Write(unsigned char addr,unsigned char dat)
{
        I2C_Start();
        I2C_SendByte(0xa0,1);//發(fā)送寫器件地址
        I2C_SendByte(addr,1);//發(fā)送要寫入內(nèi)存地址
        I2C_SendByte(dat,0);        //發(fā)送數(shù)據(jù)
        I2C_Stop();
}

// 讀取24c02的一個地址的一個數(shù)據(jù)
unsigned char At24c02Read(unsigned char addr)
{
        unsigned char num;
        I2C_Start();
        I2C_SendByte(0xa0, 1); //發(fā)送寫器件地址
        I2C_SendByte(addr, 1); //發(fā)送要讀取的地址
        I2C_Start();
        I2C_SendByte(0xa1, 1); //發(fā)送讀器件地址
        num=I2C_ReadByte(); //讀取數(shù)據(jù)
        I2C_Stop();
        return num;       
}
這個I2C時序應(yīng)該沒寫錯吧,下面是我的掉電存儲函數(shù):
從主函數(shù)中截出來的
unsigned int shangxian=35;unsigned int xiaxian=10;
unsigned char set_st=0;
unsigned char As=0,Ds=0;//As是第二個按鍵(加一ADD)按下的次數(shù),Ds是第三個按鍵(減一)按下的次數(shù)
//{
//        while(1)
//        {
//                if(set_st==0)                 //設(shè)置按鍵按下,等待
//                        while(1);
//                else if(set_st==1)//轉(zhuǎn)到上限設(shè)置
//                                {
//                                        if(As--){
//                                                shangxian=shangxian+As;
//                                                At24c02Write(2,shangxian);
//                                        shangxian=At24c02Read(2);}
//                                        else if(Ds--){
//                                                shangxian=shangxian-Ds;
//                                                At24c02Write(3,shangxian);
//                                        shangxian=At24c02Read(3);}
//                                        }
//                        else if(set_st==2)//轉(zhuǎn)到下限設(shè)置
//                                {
//                                        if(As--){
//                                                xiaxian=xiaxian+As;
//                                                At24c02Write(4,xiaxian);
//                                        xiaxian=At24c02Read(4);}
//                                        else if(Ds--){
//                                                xiaxian=xiaxian-Ds;
//                                                At24c02Write(5,xiaxian);
//                                        xiaxian=At24c02Read(5);}
//                                        }
//                        }
//}

而As的外部中斷函數(shù):
void Xint0 () interrupt 0//外部中斷0------
{
        EX0=0;
        if(ADD==0&&set_st==1){//進(jìn)入上限第二個按鍵按下,增大上限值
        do{
                display_anjian(shangxian,set_st);
        }
                while(ADD==0);//設(shè)置范圍
        As++;
        shangxian=shangxian+1;
        if(shangxian>99)
                shangxian=99;}
        else if(ADD==0&&set_st==2)//進(jìn)入下限第二個按鍵按下,增大下限值
        {
                do{
                        display_anjian(xiaxian,set_st);
                }
                        while(ADD==0);//設(shè)置范圍
                xiaxian=xiaxian+1;
                if(xiaxian>shangxian)
                        xiaxian=shangxian;
        }

望解答,急用。。。!



作者: hange_v    時間: 2023-6-28 21:31
你學(xué)雜了吧,18b20和I2C是一塊用的嗎?
作者: 菜鳥9    時間: 2023-6-28 21:54
hange_v 發(fā)表于 2023-6-28 21:31
你學(xué)雜了吧,18b20和I2C是一塊用的嗎?

DS18B20單線肯定不能用啊,只不過我問的是存儲的是閘值跟AC24C02的交換,就相當(dāng)于數(shù)碼管或者LCD(或者說是I/O口)與AC24C02的調(diào)用。我再說明白一點就是,怎么把改變的上下限存到AC24C02,又怎么取出來。
作者: wulin    時間: 2023-6-29 07:18
單純就DS18B20溫度上下限報警功能而言,不需要用24c02保存報警閾值。DS18B20 內(nèi)部含有 EEPROM ,在系統(tǒng)掉電以后,它仍可保存分辨率及報警溫度的設(shè)定值。只是網(wǎng)上大多數(shù)示例程序沒有使用這一塊。
作者: zhuls    時間: 2023-6-29 08:48
18B20與I2C,風(fēng)馬牛不相及~~
作者: 菜鳥9    時間: 2023-6-29 11:54
wulin 發(fā)表于 2023-6-29 07:18
單純就DS18B20溫度上下限報警功能而言,不需要用24c02保存報警閾值。DS18B20 內(nèi)部含有 EEPROM ,在系統(tǒng)掉電 ...

大體思路是有了,謝謝!




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1