|
程序编译没错误,但是调试的时候出现这个错误,哪位朋友能帮我解答一下吗芯片选的是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)
|