单片机读取PM2.5数字检测器数据并1602显示
下面是夏普GP2Y1051AU0F传感器输出的数据:

快来大神啊,,,,,,,
你只要用单片机自带的串口读取数据就行啦,很简单的
1.设置串口接收缓存,最少13个字节。一般是建一个1维数组。
2.用的什么单片机,晶振是多少。串口初始化,设置波特率为2400,中断接收,这个资料网上也好找。
3.开串口中断,开始接收数据。延时150毫秒后,关串口中断。
4.扫描数组,第一个0xaa及其后面的6字节数据就是你需要的一组完整数据。
5.按说明书算校验值,看是否一致。不一致舍弃。返回第3步执行。一致的话,就计算PM2.5的值,用液晶显示。
大体步骤就是大虾讲的这样,用的是89C52,正好准备好好弄弄串口程序,初学者还没弄懂。
时钟频率:11.953022M
自己写程序是步步难行,哎
一步一步来,先从串口接收和发送数据开始练吧。可以把你的程序贴出来,正好最近事不多,可以帮你改改。
还有你说的时钟频率:11.953022M,是烧录软件显示的值吧?我的理解你的晶振应该是12M。
#include <reg51.h>
void delay10ms();
void init(void);
void writecom(unsigned char com);
void writedata(unsigned char dat);
void shezhicanshu();
void senddata(unsigned char sendat);
//--?¨ò?è???±?á?--//
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0?¢1?¢2?¢3?¢4?¢5?¢6?¢7?¢8?¢9?¢A?¢b?¢C?¢d?¢E?¢Fμ???ê???
unsigned char DisplayData[8];
sbit RS=P2^6;
sbit RW=P2^5;
sbit E=P2^7;
unsigned char code str1[16]={"PM2.5="};
unsigned char buf;
unsigned char sum;
unsigned char cal[7]={0};
int i=0;
float v0;
float PM2_5;
int pm;
//?óê±10ms
void delay10ms()
{
unsigned char a,b;
for(b=19;b>0;b--)
for(a=130;a>0;a--);
}
void init(void) //3?ê??ˉLCD1602?á
{
delay10ms();
writecom(0x38);
delay10ms();
writecom(0x38);
delay10ms();
writecom(0x38);
writecom(0x38);
writecom(0x08);
writecom(0x01);
writecom(0x06);
writecom(0x0c);
}
void writecom(unsigned char com) //D′??á?
{
E=0;
RS=0;
RW=0;
P0=com;
delay10ms();
E=1;
delay10ms();
E=0;
}
void writedata(unsigned char dat) //D′êy?Y
{
E=0;
RS=1;
RW=0;
P0=dat;
delay10ms();
E=1;
delay10ms();
E=0;
}
void shezhicanshu()
{
SCON=0x50;
PCON=0x00;
TMOD=0x20;
EA=1;
ES=1;
TL1=0xfd;
TH1=0xfd;
TR1=1;
}
void main()
{
int e;
init();
shezhicanshu();
while(1)
{
writecom(0x80);
for(e=0;e<6;e++)
{
writedata(str1[e]);
}
}
}
void serial() interrupt 4
{
ES = 0; //1?±?′?DD?D??
RI = 0; //??3y′?DD?óêü±ê????
buf = SBUF; //′ó′??ú?o3???è?μ?êy?Y
senddata(buf);
ES = 1; //?êDí′??ú?D??
}
void senddata(unsigned char sendat)
{
if(sendat==170)
{
i=0;
cal=sendat;
}
else
{
i=i+1;
cal=sendat;
if(i==6)
{
sum= cal[1]+cal[2]+cal[3]+cal[4];
if(sum == cal[5] && cal[6]==255)
{
// for(i=0;i<=6;i++)
// {
// SBUF =cal;
// while(!TI);
// TI = 0;
// }
// SBUF =cal[1]; //ê?3?Vout(H)
// while(!TI);
// TI = 0;
// SBUF =cal[2]; //ê?3?Vout(L)
// while(!TI);
// TI = 0;
//
// //????pm
// v0=(cal[1]*256+cal[2])/1024*5;//????
// PM2_5=v0*200;
// SBUF =CMD_WARE; //ê?3?pm
// while(!TI);
// TI = 0;
// SBUF =~CMD_WARE; //ê?3?pm
// while(!TI);
// TI = 0;
pm=(int)((cal[1]*256+cal[2])/(1.024));
DisplayData[4]=DIG_CODE[(pm/1000)];
DisplayData[5]=DIG_CODE[(pm/100%10)];
DisplayData[6]=DIG_CODE[(pm/10%10)];
DisplayData[7]=DIG_CODE[(pm%10)];
pm=(int)pm;
// SBUF =pm; //ê?3?pm
// while(!TI);
// TI = 0;
// SBUF =~CMD_WARE; //ê?3?pm
// while(!TI);
// TI = 0;
// SBUF =CMD_WARE; //ê?3?pm
// while(!TI);
// TI = 0;
}
}
}
}
数码管只能显示”PM2.5=“这个,后面的是空白
如何将
DisplayData[4]=DIG_CODE[(pm/1000)];
DisplayData[5]=DIG_CODE[(pm/100%10)];
DisplayData[6]=DIG_CODE[(pm/10%10)];
DisplayData[7]=DIG_CODE[(pm%10)];
这几位数字显示在其后面
#include <reg51.h>
void delay10ms();
void init(void);
void writecom(unsigned char com);
void writedata(unsigned char dat);
void shezhicanshu();
void senddata(unsigned char sendat);
//--定义全局变量--//
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char DisplayData[8];
sbit RS=P2^6;
sbit RW=P2^5;
sbit E=P2^7;
unsigned char code str1[16]={"PM2.5="};
unsigned char buf;
unsigned char sum;
unsigned char cal[7]={0};
int i=0;
float v0;
float PM2_5;
int pm;
//延时10ms
void delay10ms()
{
unsigned char a,b;
for(b=19;b>0;b--)
for(a=130;a>0;a--);
}
void init(void) //初始化LCD1602屏
{
delay10ms();
writecom(0x38);
delay10ms();
writecom(0x38);
delay10ms();
writecom(0x38);
writecom(0x38);
writecom(0x08);
writecom(0x01);
writecom(0x06);
writecom(0x0c);
}
void writecom(unsigned char com) //写指令
{
E=0;
RS=0;
RW=0;
P0=com;
delay10ms();
E=1;
delay10ms();
E=0;
}
void writedata(unsigned char dat) //写数据
{
E=0;
RS=1;
RW=0;
P0=dat;
delay10ms();
E=1;
delay10ms();
E=0;
}
void shezhicanshu()
{
SCON=0x50;
PCON=0x00;
TMOD=0x20;
EA=1;
ES=1;
TL1=0xfd;
TH1=0xfd;
TR1=1;
}
void main()
{
int e;
init();
shezhicanshu();
while(1)
{
writecom(0x80);
for(e=0;e<6;e++)
{
writedata(str1[e]);
}
}
}
void serial() interrupt 4
{
ES = 0; //关闭串行中断
RI = 0; //清除串行接受标志位
buf = SBUF; //从串口缓冲区取得数据
senddata(buf);
ES = 1; //允许串口中断
}
void senddata(unsigned char sendat)
{
if(sendat==170)
{
i=0;
cal=sendat;
}
else
{
i=i+1;
cal=sendat;
if(i==6)
{
sum= cal[1]+cal[2]+cal[3]+cal[4];
if(sum == cal[5] && cal[6]==255)
{
// for(i=0;i<=6;i++)
// {
// SBUF =cal;
// while(!TI);
// TI = 0;
// }
// SBUF =cal[1]; //输出Vout(H)
// while(!TI);
// TI = 0;
// SBUF =cal[2]; //输出Vout(L)
// while(!TI);
// TI = 0;
//
// //计算pm
// v0=(cal[1]*256+cal[2])/1024*5;//计算
// PM2_5=v0*200;
// SBUF =CMD_WARE; //输出pm
// while(!TI);
// TI = 0;
// SBUF =~CMD_WARE; //输出pm
// while(!TI);
// TI = 0;
pm=(int)((cal[1]*256+cal[2])/(1.024));
DisplayData[4]=DIG_CODE[(pm/1000)];
DisplayData[5]=DIG_CODE[(pm/100%10)];
DisplayData[6]=DIG_CODE[(pm/10%10)];
DisplayData[7]=DIG_CODE[(pm%10)];
pm=(int)pm;
// SBUF =pm; //输出pm
// while(!TI);
// TI = 0;
// SBUF =~CMD_WARE; //输出pm
// while(!TI);
// TI = 0;
// SBUF =CMD_WARE; //输出pm
// while(!TI);
// TI = 0;
}
}
}
}
支持一下
不错的资料
不要把程序都写在一个文件中,这样别人看着费劲,你自己后期维护也麻烦。最好每句话都要加上注释,这样才说明你理解了。即使理解的不对,别人看到了,也能及时告知你。不要怕丢人,再牛的人,也可能从新手那里学到知识。贴两张我的程序截图,供你参考,不一定就按照我这样写。

回归正题,你是只负责软件,还是软件硬件都负责?
波特率2400是比较慢的,12M晶振下传输有误差,如果可以换的话,最好用11.0592M。
参见截图:


问题要一个一个解决。刚开始说串口通信,你又跑到怎么显示那里。如果你只是想要一个完整的程序交差,我没兴趣写。
我只想求得89c2051的接收数据的汇编程序谢谢.
好乱
