找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2422|回复: 0
打印 上一主题 下一主题
收起左侧

求助有关keil uvision4调试的问题!

[复制链接]
跳转到指定楼层
楼主
程序编译没错误,但是调试的时候出现这个错误,哪位朋友能帮我解答一下吗芯片选的是STC89C51RC

程序如下:
#include<reg52.h>
#include<intrins.h>
#include"LCD1602.h"   //LCD1602液晶头文件
#include"EEPROM.h"

#define uint unsigned int
#define uchar unsigned char
#define EEPROM_start_addr 0x2000   //STC89C52RC EEPROM起始地址
/*********端口定义************************/
//AD转换芯片端口定义
sbit CS  = P1^4; //ADC0832片选
sbit CLK = P1^1; //ADC0832时钟
sbit DIO = P1^2; //输入输出
//PM2.5传感器端口定义
sbit PM2_5_LED=P1^0;  //粉尘传感器控制接口
sbit beep=P3^6;  //蜂鸣器
sbit SET_key=P1^5;  //设置键
sbit ADD_key=P1^6;    //加键
sbit DEC_key=P1^7;    //减键
/*****************************************/
/*********寄存器定义**********************/
//以下为串口用到的寄存器
bit busy;               //串口忙检测
bit uart_R_flag;      //串口数据接收完毕标志
uchar uart_buf;      //串口数据寄存器     
uchar time_count;    //定时采样计数   
//以下为PM2_5相关寄存器定义
bit PM2_5_flag;
bit time0_f;       //280us延时标志
float DUST_Value;
uint DUST;           //PM2.5最终值 取整     
uint Alarm_DUST;   //报警值  
uchar PM2_5_num=0;
uchar ADC_Get[10]; //A/D采样数组
//以下为PM2_5值和显示缓存
uchar PM_buf[6]; //PM2.5值显示缓存
uint DUST;
//蜂鸣器
bit alarm_flag;  //报警标志
bit beep_flag;   //蜂鸣标志
uchar beep_cnt;  //蜂鸣计数
//按键相关寄存器定义
bit set_flag;  //设置标志
//EEPROM相关寄存器定义
uint EEPROM_addr_dat;          //EEPROM地址寄存器
uchar value_dat;
/*****************************************/
/*********延时函数************************/
void Delay1ms(uint t)    //1ms延时程序
{
    uchar j;
    while(t--)
    {
        for(j=0;j<125;j++)
        { ; }
    }
}
/*****************************************/
/********40us延时*************************/
void Delay40us()        //@12.000MHz
{
    unsigned char i;

    _nop_();
    i = 17;
    while (--i);
}

/*****************************************/
/**********EEPROM地址扇区寻址*******************/
uint EEPROM_addr_set(uchar value)    //地址扇区寻址 value 要大于等于1
{
    uchar c;
    uint add;
    add=EEPROM_start_addr-0x200;
    for(c=0;c<value;c++)           //寻址到第value个扇区
    {
        add=add+0x200;      
    }
    return (add);
}
/**********************************************/
/*******保存数据到EEPROM***********************/
void storage_dat(void)
{
    EEPROM_addr_dat=EEPROM_addr_set(1);  //EEPROM扇区寻址
    Sector_Erase(EEPROM_addr_dat);     //先擦除扇区
    value_dat=Alarm_DUST>>8;
    Byte_Program(EEPROM_addr_dat,value_dat); //保存报警值高位
    EEPROM_addr_dat++;
    value_dat=(uchar)Alarm_DUST;
    Byte_Program(EEPROM_addr_dat,value_dat); //保存报警值低位
}
/*******初始化EEPROM数据***********************/
void Init_EEPROM_dat()  //初始化数据
{
    Alarm_DUST=0;
    EEPROM_addr_dat=EEPROM_addr_set(1);  //EEPROM扇区寻址
    value_dat=Byte_Read(EEPROM_addr_dat);
    Alarm_DUST=value_dat*256;   //报警值 高位
    EEPROM_addr_dat++;
    value_dat=Byte_Read(EEPROM_addr_dat);
    Alarm_DUST=Alarm_DUST+value_dat;  //报警值
}
/*****************************************/
/*********初始化定时器0*******************/
void InitTimer0(void)
{
    TMOD=0x21;
    TH0=0xDA;//定时9.68ms  12MHz
    TL0=0x30;
    time0_f=0;
    TR0=1;
    ET0=1;
    EA=1;
}
/*****************************************/
/*****中值滤波函数************************/   
uchar median(uchar *dat,uchar num_d)  //需要排序的数组
{
    uchar i,j;
    uchar temp;
    for(i=0;i<num_d-1;i++) //采用冒泡法对采样温度进行排序
    {
        for(j=i+1;j<num_d;j++)
        {
            if(dat[i]<dat[j])
            {
                temp=dat[i];
                dat[i]=dat[j];
                dat[j]=temp;
            }
        }
    }
    return dat[num_d/2];
}
/*****************************************/
/********ADC0832的A/D转换程序*************/
uchar Get_AD_Result(void)
{
     uchar i,dat1=0,dat2=0;

    CS  = 0; _nop_(); _nop_();                             //片选使能,低电平有效
    CLK = 0; _nop_(); _nop_();                              //芯片时钟输入
    DIO = 1; _nop_(); _nop_();
    CLK = 1; _nop_(); _nop_();
    //第1个下降沿之前,设DI=1/0
    //选择单端/差分(SGL/DIF)模式中的单端输入模式   
    CLK = 0;DIO = 1; _nop_(); _nop_();
    CLK = 1;         _nop_(); _nop_();
    //第2个下降沿之前,设置DI=0/1,选择CHO/CH1

    CLK = 0;DIO = 0; _nop_(); _nop_(); //通道0 内部电压测试

    CLK = 1;         _nop_(); _nop_();
    //第3个下降沿之前,设置DI=1
    CLK = 0;DIO = 1; _nop_(); _nop_();
   //第4-11个下降沿读数据(MSB->LSB)
    for(i=0;i<8;i++)
    {
         CLK = 1; _nop_(); _nop_();
        CLK = 0; _nop_(); _nop_();
        dat1 = dat1 << 1 | DIO;        
    }
    //第11-18个下降沿读数据(LSB->MSB)
    for(i=0;i<8;i++)
    {
        CLK = 1; _nop_(); _nop_();
        CLK = 0; _nop_(); _nop_();
         dat2 = dat2 << ((uchar)(DIO)<<i);
    }
    CS = 1;//取消片选一个周期结束
    //如果MSB->LSB和LSB->MSB读取的结果相同,则返回读取的结果,否则返回0
    return dat1;
//    return (dat1 == dat2) ? dat1:0;//取消校验
}
/*****************************************/
/**********定时器0中断服务程序***************/
void timer0(void) interrupt 1
{
    time0_f=!time0_f;
    if(time0_f)
    {
        TL0 = 0xE8;        //设置定时初值    定时0.28ms    12MHz
        TH0 = 0xFE;        //设置定时初值
        PM2_5_LED=1;   //开启传感器LED
    }
    else
    {
        ADC_Get[PM2_5_num]=Get_AD_Result();    //将通道0采样结果存到数组
        Delay40us();
        PM2_5_LED=0;   //关闭传感器LED
        PM2_5_num++;
        if(PM2_5_num>9)   //4
        {
            PM2_5_flag=1;
            PM2_5_num=0;         
            TR0=0;
            ET0=0;
        }
        else
        {
            TH0=0xDA;//定时9.68ms  12MHz
            TL0=0x30;
        }
    }
}
/********************************************/
/************PM2.5值转换显示*******************/
void covert_PM2_5(uint PM_dat)  //PM2.5值转换显示
{
    uint Temp;
    Temp=PM_dat%10000;
    PM_buf[0]=Temp/1000+0x30;//千位            
    Temp%=1000;               
    PM_buf[1]='.';               
    PM_buf[2]=Temp/100+0x30; //百位
    Temp%=100;
    PM_buf[3]=Temp/10+0x30;  //十位
    PM_buf[4]=Temp%10+0x30;  //个位
    PM_buf[5]='\0';  //结束符
}
/**********************************************/
/**********按键处理程序************************/
void scan_key(void)
{
    if(SET_key==0)
    {
        Delay1ms(100);
        if(SET_key==0)
        {
            set_flag=~set_flag;  //设置标志
            if(set_flag==1)  //设置功能
            {
                alarm_flag=0;  //报警标志清0
                beep_cnt=0;  //蜂鸣计数
                beep_flag=0;   //蜂鸣标志
                beep=1;       //关蜂鸣器
                GotoXY(0,0);    //设置显示数据地址  列位,行
                Print("SET Alarm Value ");      //PM2.5空气质量指数
                GotoXY(0,1);    //设置显示数据地址  列位,行
                Print("           mg/m3");
                    covert_PM2_5(Alarm_DUST);  //报警值转换显示
                    LCD1602_Print(5,1,&PM_buf[0]);     //显示值
            }
            else    //退出设置
            {
            storage_dat(); //保存数据
            GotoXY(0,0);    //设置显示数据地址  列位,行
            Print("PM2.5:     mg/m3");      //PM2.5空气质量指数
            GotoXY(0,1);    //设置显示数据地址  列位,行
            Print("Alarm:     mg/m3");
                covert_PM2_5(Alarm_DUST);  //报警值转换显示
                LCD1602_Print(6,1,&PM_buf[0]);     //显示值
            }
            while(!SET_key);  //等待按键释放
        }
    }
    if(set_flag==1)
    {
        if(ADD_key==0)
        {
            Delay1ms(80);
            if(ADD_key==0)
            {
                Alarm_DUST++;   //报警值
                if(Alarm_DUST>650)   //报警值
                {
                    Alarm_DUST=650;   //报警值
                }
                covert_PM2_5(Alarm_DUST);  //报警值转换显示
                LCD1602_Print(5,1,&PM_buf[0]);     //显示值
            }
        }
        if(DEC_key==0)
        {
            Delay1ms(80);
            if(DEC_key==0)
            {
                Alarm_DUST--;   //报警值
                if(Alarm_DUST==0xFFFF)   //报警值
                {
                    Alarm_DUST=0;   //报警值
                }
                covert_PM2_5(Alarm_DUST);  //报警值转换显示
                LCD1602_Print(5,1,&PM_buf[0]);     //显示值
            }
        }
    }
}
/**********************************************/
/**********主程序****************************/
void main()
{
//    while(1);
    LCD1602_init();  //LCD初始化
    Init_EEPROM_dat();  //初始化数据 将保存到EEPROM中的数据读出
    beep=1;  //关蜂鸣器
    GotoXY(0,0);    //设置显示数据地址  列位,行
    Print("PM2.5:     mg/m3");      //PM2.5空气质量指数
    GotoXY(0,1);    //设置显示数据地址  列位,行
    Print("Alarm:     mg/m3");
    covert_PM2_5(Alarm_DUST);  //PM2.5报警值转换显示
    LCD1602_Print(6,1,&PM_buf[0]);     //显示PM2.5报警值
    PM2_5_LED=0;  //关闭传感器LED
    InitTimer0();//初始化定时器  PM2_5采样定时
    while(1)
    {
        scan_key();  //按键扫描程序
        if(set_flag==0)
        {
            if(PM2_5_flag==1)
            {
                PM2_5_flag=0;
                DUST=median(ADC_Get,10);//冒泡排序,10次 求取中值
                DUST_Value=(DUST/256.0)*5000;   //转化成电压值mv 8位A/D
                DUST_Value=DUST_Value*0.172-0.0999;//固体悬浮颗粒浓度计算  (V-0.0356)*120000
                if(DUST_Value<0)  DUST_Value=0;
                if(DUST_Value>650)  DUST_Value=650;  //限位
                DUST=(uint)DUST_Value;
                TH0=0xDA;//定时9.68ms  12MHz
                TL0=0x30;
                ET0=1;
                TR0=1;
                time_count++;
                if(time_count>=10)    //每隔大约500ms,更新一次显示数据
                {
                    time_count=0;
                    if(DUST>Alarm_DUST)      //判断报警
                    {
                        alarm_flag=1;
                        beep=0;  //开蜂鸣器
                    }
                    else
                    {
                        alarm_flag=0;
                        beep_flag=0;
                        beep=1;  //关蜂鸣器
                    }
                    covert_PM2_5(DUST);  //PM2.5值转换显示
                    LCD1602_Print(6,0,&PM_buf[0]);     //显示PM2.5值
                }
            }
        }
        Delay1ms(1);
        if(alarm_flag==1)  //报警标志
        {
            beep_cnt++;
            if(beep_cnt>=200)
            {
                beep_cnt=0;  //蜂鸣计数
                beep_flag=~beep_flag;   //蜂鸣标志
            }
        }
        if(beep_flag==1)
        {
            beep=0;  //开蜂鸣器
        }
        else beep=1;  //关蜂鸣器
    }
}

1.png (278.29 KB, 下载次数: 89)

1.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表