|
程序編譯沒錯誤,但是調(diào)試的時候出現(xiàn)這個錯誤,哪位朋友能幫我解答一下嗎 芯片選的是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轉(zhuǎn)換芯片端口定義
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; //設(shè)置鍵
sbit ADD_key=P1^6; //加鍵
sbit DEC_key=P1^7; //減鍵
/*****************************************/
/*********寄存器定義**********************/
//以下為串口用到的寄存器
bit busy; //串口忙檢測
bit uart_R_flag; //串口數(shù)據(jù)接收完畢標志
uchar uart_buf; //串口數(shù)據(jù)寄存器
uchar time_count; //定時采樣計數(shù)
//以下為PM2_5相關(guān)寄存器定義
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采樣數(shù)組
//以下為PM2_5值和顯示緩存
uchar PM_buf[6]; //PM2.5值顯示緩存
uint DUST;
//蜂鳴器
bit alarm_flag; //報警標志
bit beep_flag; //蜂鳴標志
uchar beep_cnt; //蜂鳴計數(shù)
//按鍵相關(guān)寄存器定義
bit set_flag; //設(shè)置標志
//EEPROM相關(guān)寄存器定義
uint EEPROM_addr_dat; //EEPROM地址寄存器
uchar value_dat;
/*****************************************/
/*********延時函數(shù)************************/
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地址扇區(qū)尋址*******************/
uint EEPROM_addr_set(uchar value) //地址扇區(qū)尋址 value 要大于等于1
{
uchar c;
uint add;
add=EEPROM_start_addr-0x200;
for(c=0;c<value;c++) //尋址到第value個扇區(qū)
{
add=add+0x200;
}
return (add);
}
/**********************************************/
/*******保存數(shù)據(jù)到EEPROM***********************/
void storage_dat(void)
{
EEPROM_addr_dat=EEPROM_addr_set(1); //EEPROM扇區(qū)尋址
Sector_Erase(EEPROM_addr_dat); //先擦除扇區(qū)
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數(shù)據(jù)***********************/
void Init_EEPROM_dat() //初始化數(shù)據(jù)
{
Alarm_DUST=0;
EEPROM_addr_dat=EEPROM_addr_set(1); //EEPROM扇區(qū)尋址
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;
}
/*****************************************/
/*****中值濾波函數(shù)************************/
uchar median(uchar *dat,uchar num_d) //需要排序的數(shù)組
{
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轉(zhuǎn)換程序*************/
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個下降沿之前,設(shè)DI=1/0
//選擇單端/差分(SGL/DIF)模式中的單端輸入模式
CLK = 0;DIO = 1; _nop_(); _nop_();
CLK = 1; _nop_(); _nop_();
//第2個下降沿之前,設(shè)置DI=0/1,選擇CHO/CH1
CLK = 0;DIO = 0; _nop_(); _nop_(); //通道0 內(nèi)部電壓測試
CLK = 1; _nop_(); _nop_();
//第3個下降沿之前,設(shè)置DI=1
CLK = 0;DIO = 1; _nop_(); _nop_();
//第4-11個下降沿讀數(shù)據(jù)(MSB->LSB)
for(i=0;i<8;i++)
{
CLK = 1; _nop_(); _nop_();
CLK = 0; _nop_(); _nop_();
dat1 = dat1 << 1 | DIO;
}
//第11-18個下降沿讀數(shù)據(jù)(LSB->MSB)
for(i=0;i<8;i++)
{
CLK = 1; _nop_(); _nop_();
CLK = 0; _nop_(); _nop_();
dat2 = dat2 << ((uchar)(DIO)<<i);
}
CS = 1;//取消片選一個周期結(jié)束
//如果MSB->LSB和LSB->MSB讀取的結(jié)果相同,則返回讀取的結(jié)果,否則返回0
return dat1;
// return (dat1 == dat2) ? dat1:0;//取消校驗
}
/*****************************************/
/**********定時器0中斷服務(wù)程序***************/
void timer0(void) interrupt 1
{
time0_f=!time0_f;
if(time0_f)
{
TL0 = 0xE8; //設(shè)置定時初值 定時0.28ms 12MHz
TH0 = 0xFE; //設(shè)置定時初值
PM2_5_LED=1; //開啟傳感器LED
}
else
{
ADC_Get[PM2_5_num]=Get_AD_Result(); //將通道0采樣結(jié)果存到數(shù)組
Delay40us();
PM2_5_LED=0; //關(guān)閉傳感器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值轉(zhuǎn)換顯示*******************/
void covert_PM2_5(uint PM_dat) //PM2.5值轉(zhuǎn)換顯示
{
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'; //結(jié)束符
}
/**********************************************/
/**********按鍵處理程序************************/
void scan_key(void)
{
if(SET_key==0)
{
Delay1ms(100);
if(SET_key==0)
{
set_flag=~set_flag; //設(shè)置標志
if(set_flag==1) //設(shè)置功能
{
alarm_flag=0; //報警標志清0
beep_cnt=0; //蜂鳴計數(shù)
beep_flag=0; //蜂鳴標志
beep=1; //關(guān)蜂鳴器
GotoXY(0,0); //設(shè)置顯示數(shù)據(jù)地址 列位,行
Print("SET Alarm Value "); //PM2.5空氣質(zhì)量指數(shù)
GotoXY(0,1); //設(shè)置顯示數(shù)據(jù)地址 列位,行
Print(" mg/m3");
covert_PM2_5(Alarm_DUST); //報警值轉(zhuǎn)換顯示
LCD1602_Print(5,1,&PM_buf[0]); //顯示值
}
else //退出設(shè)置
{
storage_dat(); //保存數(shù)據(jù)
GotoXY(0,0); //設(shè)置顯示數(shù)據(jù)地址 列位,行
Print("PM2.5: mg/m3"); //PM2.5空氣質(zhì)量指數(shù)
GotoXY(0,1); //設(shè)置顯示數(shù)據(jù)地址 列位,行
Print("Alarm: mg/m3");
covert_PM2_5(Alarm_DUST); //報警值轉(zhuǎn)換顯示
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); //報警值轉(zhuǎn)換顯示
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); //報警值轉(zhuǎn)換顯示
LCD1602_Print(5,1,&PM_buf[0]); //顯示值
}
}
}
}
/**********************************************/
/**********主程序****************************/
void main()
{
// while(1);
LCD1602_init(); //LCD初始化
Init_EEPROM_dat(); //初始化數(shù)據(jù) 將保存到EEPROM中的數(shù)據(jù)讀出
beep=1; //關(guān)蜂鳴器
GotoXY(0,0); //設(shè)置顯示數(shù)據(jù)地址 列位,行
Print("PM2.5: mg/m3"); //PM2.5空氣質(zhì)量指數(shù)
GotoXY(0,1); //設(shè)置顯示數(shù)據(jù)地址 列位,行
Print("Alarm: mg/m3");
covert_PM2_5(Alarm_DUST); //PM2.5報警值轉(zhuǎn)換顯示
LCD1602_Print(6,1,&PM_buf[0]); //顯示PM2.5報警值
PM2_5_LED=0; //關(guān)閉傳感器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; //轉(zhuǎn)化成電壓值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,更新一次顯示數(shù)據(jù)
{
time_count=0;
if(DUST>Alarm_DUST) //判斷報警
{
alarm_flag=1;
beep=0; //開蜂鳴器
}
else
{
alarm_flag=0;
beep_flag=0;
beep=1; //關(guān)蜂鳴器
}
covert_PM2_5(DUST); //PM2.5值轉(zhuǎn)換顯示
LCD1602_Print(6,0,&PM_buf[0]); //顯示PM2.5值
}
}
}
Delay1ms(1);
if(alarm_flag==1) //報警標志
{
beep_cnt++;
if(beep_cnt>=200)
{
beep_cnt=0; //蜂鳴計數(shù)
beep_flag=~beep_flag; //蜂鳴標志
}
}
if(beep_flag==1)
{
beep=0; //開蜂鳴器
}
else beep=1; //關(guān)蜂鳴器
}
}
|
-
1.png
(278.29 KB, 下載次數(shù): 90)
下載附件
2019-5-1 13:10 上傳
|