谁用过GP2Y1051AU0F 能否给一个51单片机的程序?

 我来答
健康的包包
推荐于2016-01-06 · 超过12用户采纳过TA的回答
知道答主
回答量:27
采纳率:100%
帮助的人:18.7万
展开全部

#include <reg52.h>

#include<intrins.h>

#define uchar unsigned char

#define uint unsigned int

#define ushort unsigned short

uchar TxBuf[32];



sbit re=P2^5;  //液晶接口

sbit rw=P2^4;

sbit rs=P2^3;

sbit psb=P2^6;

sbit rst=P2^7;

sbit LED=P1^5;//粉尘传感器控制接口

sbit ADCS=P2^0;//AD0832接口

sbit ADCLK=P2^1;

sbit ADDI=P2^2;

sbit ADDO=P2^2;

sbit SET=P3^3;//按键接口

sbit ADD=P3^4;

sbit DEC=P3^5;

sbit BEEP=P3^6;//蜂鸣器接口


uchar set_st;

uchar tab[4];

uint DUST_SET=35;//固体颗粒物的阀值

int x;    //计数器

//定义标志

uchar FlagStar=0;

float  DUST_Value;

uint DUST;

uchar num=0;

uchar mm;

uchar abc;

uchar ADC_Get[10]={0};//定义AD采样数组

uchar str[5]={0};

uchar code tab0[]="pm2.5:";

uchar code tab1[]="温度值:";

uchar code tab2[]="报警阀值:";

void delaym1s(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void DelayMs(uchar k)

{ uchar i;

i=k;

while(i--);

}

void wr_date(uchar date)//写数据 

uint i;

uchar a,p;

delaym1s(10);

a=date;

rs=1;                //数据命令选择=1时读取数据

re=0;             //串口时钟,未开 

rw=1;              //选择串口方式 

for(i=0;i<5;i++)    //开启字节 

{

  re=1;

  re=0;

}

rw=0;             // 写 

re=1;           //开启时钟脉冲 

re=0;

rw=1;           //选择数据 

          

re=1;         

re=0;

rw=0;          

re=1; 

re=0;

for(p=0;p<2;p++)

{

  for(i=0;i<4;i++)

  {

   a=a<<1;    //左移目的是为了将溢出数据(即0或1)赋予std     

   rw=CY;    //单片机特殊功能寄存器,“CY”用于存放字符串溢出字符    

   re=1;   //一开一锁将数据显示 

   re=0;

  }

  rw=0;         

  for(i=0;i<4;i++)

  {

   re=1;

   re=0;

  }

}

}

void wr_com(uchar com) //写命令

{

uchar a,p;

uint i;

delaym1s(10);

a=com;

rs=1;              //数据命令选择=1时读取数据 

re=0;            //串口时钟,未开 

rw=1;            //选择串口方式 

for(i=0;i<5;i++)   //开启字节 

{

  re=1;

  re=0;

}

rw=0;          

re=1;         //开启时钟脉冲 

re=0;

rw=0;         

re=1;       

re=0;

rw=0;         

re=1;

re=0;

for(p=0;p<2;p++)

{

  for(i=0;i<4;i++)

  {

   a=a<<1;//左移目的是为了将溢出数据(即0或1)赋予std

   rw=CY;//单片机特殊功能寄存器,“CY”用于存放字符串溢出字符    

   re=1;//一开一锁将数据显示

   re=0;

  }

  rw=0;   

  for(i=0;i<4;i++)//延时一下为下一数据到来做准备   

  {

   re=1;

   re=0;

  }

}


}


void write_lcd() //向液晶写入显示内容

{

uchar num;

wr_com(0x80);

for(num=0;num<7;num++)

{

  wr_date(tab0[num]);

  delaym1s(1);

}

wr_com(0x90);

for(num=0;num<7;num++)

{

  wr_date(tab1[num]);

  delaym1s(1);

}

wr_com(0x88);

for(num=0;num<10;num++)

{

  wr_date(tab2[num]);

  delaym1s(1);

}

// wr_com(0x98);

// for(num=0;num<16;num++)

// {

//   wr_date(tab3[num]);

//   delay(1);

// }

}

void init_lcd()

{

rst=1;

psb=0;         //选串口 

wr_com(0x30); //30---基本指令动作 

wr_com(0x01); //清屏,地址指针指向00H

delaym1s(1);

wr_com(0x06); //光标的移动方向即读入或写入数据后指针加一

wr_com(0x0c); //开显示,关游标类似1602

return;

}

void init()

{

init_lcd();

write_lcd();



/*******初始化定时器0***********/

void InitTimer(void)

{

TMOD=0x01;

TH0=(65536-8881)/256;//定时10ms

TL0=(65536-8881)%256;

TR0=1;

ET0=1;

EA=1;

}


/****************显示函数********************/

void disp(uint Data)//PM2,5值显示

{  

uint Temp;  

Temp=Data%10000;

TxBuf[0]=Temp/1000+0x30;//千位             

Temp%=1000;               

TxBuf[1]='.';               

TxBuf[2]=Temp/100+0x30;//百位

Temp%=100;

TxBuf[3]=Temp/10+0x30;//十位

TxBuf[4]=Temp%10+0x30;//个位

wr_com(0x83);  

wr_date(TxBuf[0]);

wr_date(TxBuf[1]);

wr_com(0x84);

wr_date(TxBuf[2]);

wr_date(TxBuf[3]);

wr_com(0x85);

wr_date(TxBuf[4]);

wr_date('u');

wr_com(0x86);

wr_date('g');

wr_date('/');

wr_com(0x87);

wr_date('m');

wr_date('3');

}


/*********报警值显示**********/

void baojing()

{

wr_com(0x8d);

wr_date(TxBuf[12]);

wr_date(TxBuf[13]);

wr_com(0x8e);

wr_date(TxBuf[14]);

wr_date(TxBuf[15]);

}

// /******延时********/

// void Delay(uint num)

// {

// while(--num);

// }

//


/*******按键检测********/

void checkkey()

{

if(SET==0)

{

delaym1s(10);

do{}while(SET==0);

set_st++;

if(set_st>1)set_st=0;

}

if(set_st==0)

{

}

else if(set_st==1)

{

if(DEC==0)

{

delaym1s(10);

do{}while(DEC==0);


if(DUST_SET>0) DUST_SET--;

if(DUST_SET==0) DUST_SET=0;

}

if(ADD==0)

{

delaym1s(10);

do{}while(ADD==0);

DUST_SET++;

if(DUST_SET>80) DUST_SET=80;

}

}

TxBuf[12]=DUST_SET/100;

TxBuf[13]='.';

TxBuf[14]=DUST_SET%100/10;

TxBuf[15]=DUST_SET%100%10; 

}


///******报警子程序*******/

//void Alarm()

//{

// if(x>=10){beep_st=~beep_st;x=0;}

// if(DUST/10>DUST_SET&&beep_st==1) BEEP=1;

// else BEEP=0;

// if(DUST/10>0&&DUST/10<10){LED2=0;LED3=1;LED4=1;}

// if(DUST/10>=10&&DUST/10<30){LED2=1;LED3=0;LED4=1;}

// if(DUST/10>=30){LED2=1;LED3=1;LED4=0;}

//}


/*******AD0832转换程序**********/

uchar AD0832(bit mode,bit channel)      //AD转换,返回结果

{

uchar i,dat,ndat;


ADCS=0;// 拉低CS端

_nop_();

_nop_();


ADDI=1;  //第一个下降沿为高电平

ADCLK=1;  //  拉高CLK端

_nop_();

_nop_();

ADCLK=0;// 拉低CLK端,形成下降沿1

_nop_();

_nop_();


ADDI=mode;  //低电平为差分模式,高电平为单通道模式。

ADCLK=1;  //  拉高CLK端

_nop_();

_nop_();

ADCLK=0;// 拉低CLK端,形成下降沿2

_nop_();

_nop_();


ADDI=channel;  //低电平为CH0,高电平为CH1

ADCLK=1;  //  拉高CLK端

_nop_();

_nop_();

ADCLK=0;// 拉低CLK端,形成下降沿3

ADDI=1;// 控制命令结束(经试验必须)

dat=0;

//下面开始读取转换后的数据,从最高位开始依次输出(D7~D0)

for(i=0;i<8;i++)

{

dat<<=1;

ADCLK=1;//拉高时钟端

_nop_();

_nop_();

ADCLK=0;//拉低时钟端形成一次时钟脉冲

_nop_();

_nop_();

dat|=ADDO;

}

ndat=0;   //记录 D0

if(ADDO==1)

ndat|=0x80;

  //下面开始读取反序的数据从(D1到D7)

  for(i=0;i<7;i++)

  {

  ndat>>=1;

ADCLK=1;//拉高时钟端

_nop_();

_nop_();

ADCLK=0;//拉低时钟端形成一次时钟脉冲

_nop_();

_nop_();

if(ADDO==1)

ndat|=0x80;

  }

  ADCS=1;//拉高cs端,结束转换

  ADCLK=0;//拉低CLK端

  ADDI=1;//拉高数据段,回到初始状态

  if(dat==ndat)

  return(dat);

  else

  return 0;

}


/**********定时器0中断服务程序***************/

void timer0(void) interrupt 1

{

uint j;

x++;

TH0=(65536-8881)/256;//定时10us

TL0=(65536-8881)%256;

LED=1;

for(j=0;j<30;j++);//延时0.28ms

abc=AD0832(1,0);   //开启ADC采集

FlagStar=1;

for(j=0;j<5;j++);          

TR0=0;

EA=0;


LED=0;  //关闭传感器LED

}


/**************************************************************

中值滤波  算法:先进行排序,然后将数组的中间值作为当前值返回。

**************************************************************/

uchar Error_Correct(uchar *str,uchar num)

{

uchar i=0;

uchar j=0;

uchar Temp=0;


//排序

for(i=0;i<num-1;i++)

{

for(j=i+1;j<num;j++)

{

if(str[i]<str[j])

{

Temp=str[i];

str[i]=str[j];

str[j]=Temp;

}

}

}

//去除误差,取中间值

return str[num/2];

}


/*******主函数*********/

void main()

{

// uchar a;

InitTimer();  //初始化定时器  

LED=1;


DelayMs(255);//等待电源稳定,液晶复位完成

init(); //12864 液晶初始化

// DS18B20_Init(); //18B20 初始化,可不用初始化,因为18B20 出厂时默认是12 位精度

delaym1s(100);

while(1)

{

checkkey(); //按键检测 

  baojing(); //显示报警值

disp(DUST);  //显示粉尘浓度值

if(set_st==0)

{

// write_com(0x0c);

if(FlagStar==1)

{

num++;

ADC_Get[num]=abc;

if(num>9)

{

num=0;

DUST=Error_Correct(ADC_Get,10);//求取10次AD采样的值

DUST_Value=(DUST/256.0)*5000;   //转化成电压值mv

DUST_Value=DUST_Value*0.17-0.1; //固体悬浮颗粒浓度计算 Y=0.17*X-0.1  X--采样电压

// if(DUST_Value<0)  DUST_Value=0;

// if(DUST_Value>19600)  DUST_Value=760;  //限位

DUST=(uint)DUST_Value;

}

 TH0=(65536-8881)/256;//定时10ms

 TL0=(65536-8881)%256;

 TR0=1;  //开启定时器0

 EA=1;

 FlagStar=0;           

}

// Alarm();  //报警检测

}

// write_com(0x80+0x4f);

// write_data('3');

// if(set_st==1)  //报警值闪动

//  {

//   write_com(0xca);

// write_com(0x0d);

// delaym1s(150);

//  }

}

}

追问
这个传感器是数字型的
追答
我用的夏普这个系列的传感器可能型号稍微老些,还有模拟量的输出接口。帮不了你了。
意法半导体(中国)投资有限公司
2023-06-12 广告
STM32F103是一款高性能的嵌入式芯片,由意法半导体(STMicroelectronics)公司生产。它是STM32系列芯片之一,具有紧凑、低功耗、高性能等特点,被广泛应用于嵌入式系统中。STM32F103的主要特点包括:1. 集成了A... 点击进入详情页
本回答由意法半导体(中国)投资有限公司提供
匿名用户
2015-03-29
展开全部
LED的脉冲我当时也弄错了,最后修改后才正确。你先置LED高,延时0.28MS,然后读取ADC值,再延时0.04MS,然后再置LED低,9.68MS。就行了。
追问
采用数字型的该如何编写呢
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
查晓筠0i5
2015-03-29 · TA获得超过2752个赞
知道大有可为答主
回答量:2.1万
采纳率:1%
帮助的人:4950万
展开全部
需要给你写一份吗
追问
需要
追答
需要定做可以丘上说
我id
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式