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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1315|回復: 1
打印 上一主題 下一主題
收起左側

為什么這個單片機程序打開之后,出現很多未定義的錯誤啊,有大佬幫忙看看么

[復制鏈接]
跳轉到指定樓層
樓主
#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char        // 以后unsigned char就可以用uchar代替
#define uint  unsigned int        // 以后unsigned int 就可以用uint 代替

sfr ISP_DATA  = 0xe2;                        // 數據寄存器
sfr ISP_ADDRH = 0xe3;                        // 地址寄存器高八位
sfr ISP_ADDRL = 0xe4;                        // 地址寄存器低八位
sfr ISP_CMD   = 0xe5;                        // 命令寄存器
sfr ISP_TRIG  = 0xe6;                        // 命令觸發寄存器
sfr ISP_CONTR = 0xe7;                        // 命令寄存器


sbit LcdRs_P   = P2^7;                // 1602液晶的RS管腳      
sbit LcdRw_P   = P2^6;                // 1602液晶的RW管腳
sbit LcdEn_P   = P2^5;                // 1602液晶的EN管腳
sbit Trig_P    = P2^2;                // 超聲波模塊的Trig管腳
sbit Echo_P    = P2^3;                // 超聲波模塊的Echo管腳
sbit KeySet_P  = P3^2;                // “設置”按鍵的管腳
sbit KeyDown_P = P3^3;                // “減”按鍵的管腳
sbit KeyUp_P   = P3^4;                // “加”按鍵的管腳
sbit Buzzer_P  = P2^1;                // 蜂鳴器的管腳
sbit Led_P     = P2^0;                // LED報警燈的管腳
sbit DQ        = P1^0;                // 溫度傳感器的引腳定義


uint  gAlarm;                                                        // 報警距離變量
float gSpeed;                                                        // 保存超聲波的速度值



/*********************************************************/
// 單片機內部EEPROM不使能
/*********************************************************/
void ISP_Disable()
{
        ISP_CONTR = 0;
        ISP_ADDRH = 0;
        ISP_ADDRL = 0;
}


/*********************************************************/
// 從單片機內部EEPROM讀一個字節,從0x2000地址開始
/*********************************************************/
unsigned char EEPROM_Read(unsigned int add)
{
        ISP_DATA  = 0x00;
        ISP_CONTR = 0x83;
        ISP_CMD   = 0x01;
        ISP_ADDRH = (unsigned char)(add>>8);
        ISP_ADDRL = (unsigned char)(add&0xff);
        // 對STC89C51系列來說,每次要寫入0x46,再寫入0xB9,ISP/IAP才會生效
        ISP_TRIG  = 0x46;           
        ISP_TRIG  = 0xB9;
        _nop_();
        ISP_Disable();
        return (ISP_DATA);
}


/*********************************************************/
// 往單片機內部EEPROM寫一個字節,從0x2000地址開始
/*********************************************************/
void EEPROM_Write(unsigned int add,unsigned char ch)
{
        ISP_CONTR = 0x83;
        ISP_CMD   = 0x02;
        ISP_ADDRH = (unsigned char)(add>>8);
        ISP_ADDRL = (unsigned char)(add&0xff);
        ISP_DATA  = ch;
        ISP_TRIG  = 0x46;
        ISP_TRIG  = 0xB9;
        _nop_();
        ISP_Disable();
}


/*********************************************************/
// 擦除單片機內部EEPROM的一個扇區
// 寫8個扇區中隨便一個的地址,便擦除該扇區,寫入前要先擦除
/*********************************************************/
void Sector_Erase(unsigned int add)         
{
        ISP_CONTR = 0x83;
        ISP_CMD   = 0x03;
        ISP_ADDRH = (unsigned char)(add>>8);
        ISP_ADDRL = (unsigned char)(add&0xff);
        ISP_TRIG  = 0x46;
        ISP_TRIG  = 0xB9;
        _nop_();
        ISP_Disable();
}



/*********************************************************/
// 毫秒級的延時函數,time是要延時的毫秒數
/*********************************************************/
void DelayMs(uint time)
{
        uint i,j;
        for(i=0;i<time;i++)
                for(j=0;j<112;j++);
}


/*********************************************************/
// 延時15微秒
/*********************************************************/
void Delay15us(void)
{
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
}


/*********************************************************/
// 1602液晶寫命令函數,cmd就是要寫入的命令
/*********************************************************/
void LcdWriteCmd(uchar cmd)
{
        LcdRs_P = 0;
        LcdRw_P = 0;
        LcdEn_P = 0;
        P0=cmd;
        DelayMs(2);
        LcdEn_P = 1;   
        DelayMs(2);
        LcdEn_P = 0;        
}


/*********************************************************/
// 1602液晶寫數據函數,dat就是要寫入的數據
/*********************************************************/
void LcdWriteData(uchar dat)
{
        LcdRs_P = 1;
        LcdRw_P = 0;
        LcdEn_P = 0;
        P0=dat;
        DelayMs(2);
        LcdEn_P = 1;   
        DelayMs(2);
        LcdEn_P = 0;
}


/*********************************************************/
// 1602液晶初始化函數
/*********************************************************/
void LcdInit()
{
        LcdWriteCmd(0x38);        // 16*2顯示,5*7點陣,8位數據口
        LcdWriteCmd(0x0C);        // 開顯示,不顯示光標
        LcdWriteCmd(0x06);        // 地址加1,當寫入數據后光標右移
        LcdWriteCmd(0x01);        // 清屏
}


/*********************************************************/
// 液晶光標定位函數
/*********************************************************/
void LcdGotoXY(uchar line,uchar column)
{
        // 第一行
        if(line==0)        
                LcdWriteCmd(0x80+column);
        // 第二行
        if(line==1)        
                LcdWriteCmd(0x80+0x40+column);
}



/*********************************************************/
// 液晶輸出字符串函數
/*********************************************************/
void LcdPrintStr(uchar *str)
{
        while(*str!='\0')
                        LcdWriteData(*str++);
}


/*********************************************************/
// 液晶輸出數字
/*********************************************************/
void LcdPrintNum(uint num)
{
        LcdWriteData(num/100+0x30);                                // 百位
        LcdWriteData(num%100/10+0x30);                // 十位
        LcdWriteData(num%10+0x30);                                // 個位
}


/*********************************************************/
// 在液晶上顯示溫度
/*********************************************************/
void LcdPrintTemp(int temp)
{
        if(temp<0)                                                                 
        {
                LcdWriteData('-');                                                        // 負號        
                temp=0-temp;                                                                                // 負數轉為正數
        }
        if(temp>999)                                                                  
        {
                LcdWriteData(temp/1000+0x30);                // 百位        
        }
        LcdWriteData(temp%1000/100+0x30);        // 十位
        LcdWriteData(temp%100/10+0x30);                // 個位
        LcdWriteData('.');                                                                 // 小數點
        LcdWriteData(temp%10+0x30);                                // 小數后一位
        LcdWriteData(0xdf);                                                                // 攝氏度符號
        LcdWriteData('C');
        LcdWriteData(' ');
}



/*********************************************************/
// 復位DS18B20(初始化)
/*********************************************************/
void DS18B20_ReSet(void)
{
        uchar i;
        DQ=0;
        i=240;
        while(--i);
        DQ=1;
        i=30;
        while(--i);
        while(~DQ);
        i=4;
        while(--i);
}


/*********************************************************/
// 向DS18B20寫入一個字節
/*********************************************************/
void DS18B20_WriteByte(uchar dat)
{
        uchar j;
        uchar btmp;
        
        for(j=0;j<8;j++)
        {
                btmp=0x01;
                btmp=btmp<<j;
                btmp=btmp&dat;
               
                if(btmp>0)                // 寫1
                {
                        DQ=0;
                        Delay15us();
                        DQ=1;
                        Delay15us();
                        Delay15us();
                        Delay15us();
                        Delay15us();
                }
                else                        // 寫0
                {
                        DQ=0;
                        Delay15us();
                        Delay15us();
                        Delay15us();
                        Delay15us();
                        DQ=1;
                        Delay15us();
                }
        }
}


/*********************************************************/
// 讀取溫度值
/*********************************************************/
int DS18B20_ReadTemp(void)
{
        uchar j;
        int b,temp=0;        

        DS18B20_ReSet();                                                        // 產生復位脈
        DS18B20_WriteByte(0xcc);                        // 忽略ROM指令
        DS18B20_WriteByte(0x44);                        // 啟動溫度轉換指令

        DS18B20_ReSet();                                                        // 產生復位脈
        DS18B20_WriteByte(0xcc);                        // 忽略ROM指令
        DS18B20_WriteByte(0xbe);                        // 讀取溫度指令

        for(j=0;j<16;j++)                                                        // 讀取溫度數量
        {                                                
                DQ=0;
                _nop_();
                _nop_();
                DQ=1;        
                Delay15us();
                b=DQ;
                Delay15us();
                Delay15us();
                Delay15us();
                b=b<<j;
                temp=temp|b;
        }
        
        temp=temp*0.0625*10;                                        // 合成溫度值并放大10倍                                       
        return (temp);                                                                // 返回檢測到的溫度值
}



/*********************************************************/
// 計算測到的距離
/*********************************************************/
uint GetDistance(void)
{
        uint ss;                                        // 用于記錄測得的距離

        TH0=0;
        TL0=0;

        Trig_P=1;                                        // 給超聲波模塊一個開始脈沖
        DelayMs(1);
        Trig_P=0;

        while(!Echo_P);                // 等待超聲波模塊的返回脈沖
        TR0=1;                                                // 啟動定時器,開始計時
        while(Echo_P);                // 等待超聲波模塊的返回脈沖結束
        TR0=0;                                                // 停止定時器,停止計時

        ss=((TH0*256+TL0)*gSpeed)/2;                // 距離cm=(時間us * 速度cm/us)/2

        if(ss>999)                                // 把檢測結果限制999厘米內
                ss=999;
        
        return ss;
}


/*********************************************************/
// 按鍵掃描
/*********************************************************/
void KeyScanf()
{
        uchar i;
        uchar dat1,dat2;

        if(KeySet_P==0)                                                                // 判斷是否有按鍵按下
        {
                LcdGotoXY(1,0);                                                        // 液晶第二行刷新顯示
                LcdPrintStr("  alarm=   cm   ");
                LcdGotoXY(1,8);                                                        // 顯示當前的報警值
                LcdPrintNum(gAlarm);                                
               
                DelayMs(10);                                                                // 消除按鍵按下的抖動
                while(!KeySet_P);                                                // 等待按鍵釋放
                DelayMs(10);                                                                // 消除按鍵松開的抖動

                i=1;

                while(i)
                {                                                         
                        if(KeyDown_P==0)                // 報警值減的處理
                        {
                                if(gAlarm>2)
                                        gAlarm--;
                                LcdGotoXY(1,8);
                                LcdPrintNum(gAlarm);        
                                DelayMs(300);
                        }

                        if(KeyUp_P==0)                        // 報警值加的處理
                        {
                                if(gAlarm<400)
                                        gAlarm++;
                                LcdGotoXY(1,8);
                                LcdPrintNum(gAlarm);
                                DelayMs(300);
                        }
                        
                        if(KeySet_P==0)                        // 再次按下設置鍵的判斷
                        {
                                LcdGotoXY(1,0);                                                // 液晶恢復測量時的內容顯示
                                LcdPrintStr("  dist=   cm    ");
                                DelayMs(10);                                                  // 消除按鍵按下的抖動
                                while(!KeySet_P);                                        // 等待按鍵釋放
                                DelayMs(10);                                                  // 消除按鍵松開的抖動
                                i=0;
                        }                           
                }
               
                dat1=gAlarm/100;
                dat2=gAlarm%100;
                Sector_Erase(0x2000);
                EEPROM_Write(0x2000,dat1);
                EEPROM_Write(0x2001,dat2);
        }        
}


/*********************************************************/
// 報警判斷
/*********************************************************/
void AlarmJudge(uint ss)
{
        uchar i;
        float alr1,alr2,alr3,alr4;

        alr1=gAlarm/4.00*1;
        alr2=gAlarm/4.00*2;
        alr3=gAlarm/4.00*3;
        alr4=gAlarm/4.00*4;


        // 報警頻率最快
        if(ss<alr1)                        
        {
                for(i=0;i<10;i++)
                {
                        Led_P=0;
                        Buzzer_P=0;
                        DelayMs(50);
                        Led_P=1;
                        Buzzer_P=1;
                        DelayMs(50);
                        KeyScanf();
                }
        }
        // 報警頻率第二快
        else if(ss<alr2)               
        {
                for(i=0;i<5;i++)
                {
                        Led_P=0;
                        Buzzer_P=0;
                        DelayMs(100);
                        Led_P=1;
                        Buzzer_P=1;
                        DelayMs(100);
                        KeyScanf();
                }        
        }
        // 報警頻率第三快
        else if(ss<alr3)         
        {
                for(i=0;i<2;i++)
                {
                        Led_P=0;
                        Buzzer_P=0;
                        DelayMs(200);
                        Led_P=1;
                        Buzzer_P=1;
                        DelayMs(200);
                        KeyScanf();
                }        
        }
        // 報警頻率最慢
        else if(ss<alr4)        
        {
                for(i=0;i<2;i++)
                {
                        Led_P=0;
                        Buzzer_P=0;
                        DelayMs(300);
                        Led_P=1;
                        Buzzer_P=1;
                        DelayMs(300);
                        KeyScanf();
                }        
        }
        // 不報警
        else
        {
                Led_P=1;
                Buzzer_P=1;
                for(i=0;i<100;i++)
                {
                        KeyScanf();
                        DelayMs(10);
                }        
        }
}


/*********************************************************/
// 主函數
/*********************************************************/
void main()
{
        uchar dat1,dat2;
        uint dist;                                                                                                // 保存超聲波模塊測量到的結果
        int  temp;                                                                                                // 保存溫度傳感器測量到的結果

        Trig_P=0;
        
        LcdInit();                                                                                                // 執行液晶初始化
        TMOD = 0x01;                                                                                        // 選擇定時器0,并且確定是工作方式1(為了超聲波模塊測量距離計時用的)
        
        LcdGotoXY(0,0);                                                                    // 定位到第0行第0列
        LcdPrintStr("  temp=         ");        // 第0行顯示“  temp=         ”
        LcdGotoXY(1,0);                                                                    // 定位到第1行第0列
        LcdPrintStr("  dist=   cm    ");        // 第1行顯示“  dist=   cm    ”

        while(DS18B20_ReadTemp()==850)                // 等待溫度傳感器初始化完成
        {
                DelayMs(10);
        }
        
        dat1=EEPROM_Read(0x2000);                                        // 從EEPROM讀取報警值
        dat2=EEPROM_Read(0x2001);
        gAlarm=dat1*100+dat2;

        if((gAlarm==0)||(gAlarm>400))                        // 如果讀取到的報警值異常(等于0或大于400則認為異常)
        {
                gAlarm=25;                                                                                        // 重新賦值報警值為25
        }

        while(1)
        {
                temp=DS18B20_ReadTemp();                                // 獲取溫度傳感器的溫度值
                LcdGotoXY(0,7);                                                                        // 定位到第0行第7列
                LcdPrintTemp(temp);                                                        // 顯示當前的溫度值
               
                gSpeed=0.607*(temp/10)+331.4;                // 根據公式 v=0.607T+331.4 計算出當前溫度值對應的超聲波速度,這時的單位是“米/秒”
                gSpeed=gSpeed/10000;                                                // 將超聲波的速度從單位“m/s”轉為“cm/us”,方便后面的計算
               
                dist=GetDistance();                                                        // 通過超聲波模塊獲取距離
                LcdGotoXY(1,7);                                                            // 光標定位
                LcdPrintNum(dist);                                                        // 將獲取到的距離在液晶上面顯示

                AlarmJudge(dist);                                                                // 判斷一下是否需要報警,是的話則報警        
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:161164 發表于 2023-6-27 22:01 | 只看該作者
沒有錯誤

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品伦精品一区二区三区视频 | 欧美在线视频观看 | 国产精品99久久久久久动医院 | 国产精品毛片在线 | 毛片免费视频 | 羞羞的视频免费看 | 亚洲美乳中文字幕 | 精品欧美黑人一区二区三区 | 欧美三级网站 | 久久在线免费 | 亚洲国产精品视频 | 欧美美女爱爱 | 国产婷婷综合 | 搞av.com| 日本成人综合 | 综合久久久久 | 精品国产乱码久久久久久闺蜜 | 蜜桃精品视频在线 | 91精品久久久久久久久久小网站 | 久久久精品久久 | 国产精品久久久久一区二区三区 | 国产亚洲精品区 | 一道本一区二区 | 全免费a级毛片免费看视频免费下 | 欧美乱淫视频 | 午夜影视大全 | 日韩精品一区二区三区视频播放 | 精品中文字幕久久 | 日韩欧美中文 | 视频精品一区二区三区 | 日本韩国电影免费观看 | 欧美视频成人 | 免费在线视频一区二区 | 国产精品免费一区二区三区四区 | 北条麻妃一区二区三区在线视频 | 精品国产一区二区三区久久影院 | 欧美性猛片aaaaaaa做受 | 精品九九九| 先锋资源亚洲 | 四虎影院在线免费观看 | 涩涩视频网 |