|
//***************************************
// 空气质量测试仪设计
// 使用单片机STC90C516RD
// 晶振:11.0592M
// 显示:1602液晶显示//编程思路:
//简单的就是做一个1ms的定时中断(要准点可以定时时间减少,反之定时时间加大)
//在中断中检测IO口的电平,是低就 加1
//1s内总共检测1000次 ,检测累加的值除以10就是百分数,也就是低脉冲率。
//****************************************
#include"Reg52.H" /* 调用MCS51寄存器头文件 */
#include"intrins.H"
#include "LCD1602.H"
#include"stdio.h"
#include <string.h>
#define uc unsigned char
#define uint unsigned int
typedef unsigned char U8; /* defined for unsigned 8-bits integer variable 无符号8位整型变量 */
typedef signed char S8; /* defined for signed 8-bits integer variable 有符号8位整型变量 */
typedef unsigned int U16; /* defined for unsigned 16-bits integer variable 无符号16位整型变量 */
typedef signed int S16; /* defined for signed 16-bits integer variable 有符号16位整型变量 */
typedef unsigned long U32; /* defined for unsigned 32-bits integer variable 无符号32位整型变量 */
typedef signed long S32; /* defined for signed 32-bits integer variable 有符号32位整型变量 */
typedef float F32; /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
typedef double F64; /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
unsigned char sChar_i=0;//写入数据sChar指针
unsigned char sendFlag = 0; //未发送数据时
unsigned char receFlag =0; //未接受到数据时
//*********************************************
//MON51必须用到的
code unsigned char stop[3] _at_ 0x3b;
//*********************************************
sbit PWM=P1^0; //脉冲输出//xin//
sbit LED=P3^7;
U16 number_t0=0;
U16 lt_time=0; //低脉冲时间
U16 Temp0=0; //低脉冲率
uc sChar[50]={'\0'};
void sendChar(unsigned char sendValue); //发送一字节数据
void sendAll(unsigned char *pValue); //发送一组数据
//
//*********************定时器T0用于定时1MS********
timer0() interrupt 1 using 1 //T/C0中断服务程序, 每1ms中断一次
{
number_t0++;
if(PWM==0) lt_time++; //每1ms检测PWM脉冲是否为低电平
if(number_t0==1000) //munber_t0计数到1000MS,即1S,计算低脉冲率
{ TR0=0; //关闭定时器0
Temp0=(int)(lt_time/10); //计算低脉冲率
number_t0=0; //1S时间计数器和低脉冲率变量初始化为0,开始下一个测量周期
lt_time=0;
TR0=1; // 启动定时器0
}
TH0=0xfc;
TL0=0x66;
}
//
void dingshi()
{ TMOD=0x01;
TH0=0xfc; /*晶振:11.0592MHz,定时1ms*/
TL0=0x66;
ET0=1;
TR0=1;
EA=1;
DelayMs( 200 ); /* 上电延时 */
}
//xin//
void initSer()//初始化
{
TMOD=0x20; //定时器工作方式,选择了定时器1,工作方式2 八位初值自动重装的8位定时器。
TH1=0xfd; //定时器1初值 ,设置波特率为9600 配合为晶振11.0529MHZ,晶振的电容是20uf?
TL1=0xfd;
TR1=1; //开启定时器1
SM0=0; //属于SCON寄存器
SM1=1; //串口工作方式1,10位异步接收,(8位数据)波特率可变
REN=1; //允许串行口接收位
EA=1; //允许中断(总闸)
ES=1; //允许串口中断
}
void sendChar(unsigned char Value) //发送一个字节数据
{
SBUF = Value;
sendFlag = 1; //设置发送标志位,发一字节就置位
while(sendFlag); //直到发完数据,将sendFlag清零后,才退出sendChar函数
}
void sendAll(unsigned char *pValue) //发送一组数据
{
while((*pValue) != '\0') //如果没有发送完毕就继续发
{
sendChar(*pValue); //发送1字节数据
pValue++; //指向下1个字节
}
}
void serInt() interrupt 4 //中断函数
{
//TI——发送中断bai标志位,可寻址标志位。方式0时,发送完第8位数据后,由硬件置位,其它方式下,在发送或停止位之前由硬件置位,因此,TI=1表示帧发送结束,TI可由软件清“0”。
//RI——接收中断标志位.可寻址标志位。接收完第8位数据后,该位由硬件置位,在其他工作方式下,该位由硬件置位,RI=1表示帧接收完成。
//在串口中断处理时,TI,RI都需要软件清"0",硬件置位后不可能自动清0,此外,在进行缓冲区操作时,需要ES=0,以防止中断出现。
if(RI) //接收数据,手动将RI清0
{
RI=0;
if(SBUF=='\0'||SBUF=='#')
{
sChar[sChar_i++]='\0';
receFlag=1; //修改接受标志,便于主函数进入while中发数据
}
else
{
sChar[sChar_i++]=SBUF; //每次接受8位,存在SBUF里,转存到数组中
}
}
if(TI) //发送数据
{
TI = 0; //发送完一个数据
sendFlag = 0; //清标志位
}
}
//
//***********************主程序****************************
void main()
{ U8 DisplayBuf[16];
/* 存储转换后的数据 */
dingshi();
initSer(); //xin /* 上电延时 */
LCD1602_Init();
LCD1602_WriteUSerCode(); /* 写入用户自定义字符 */
LCD1602_SetDisplayPosition(0,1); /* 显示显示位置 */
LCD1602_WriteString("Air quality test");
while(1) /*循环*/
{
sprintf(DisplayBuf," low rate=%3d",Temp0); /*显示低脉冲率*/
LCD1602_SetDisplayPosition(0,2); /* 显示显示位置 */
LCD1602_WriteString(DisplayBuf);
if(receFlag)
{
LED=~LED;
sChar_i=0;//接受数组指针归0,以便以下次接受
sendAll(sChar);
if(strlen(sChar)==4&&sChar[0]=='L'&&sChar[1]=='E'&&sChar[2]=='D')
{
P1=sChar[3];
}
receFlag=0;
}
if(sendFlag) //发送完毕之后,在电脑端输出。
{
TI=1; //printf之前必须将T1置为1才行。
while(!TI);
sendFlag=0;
}
}
}
|
-
1.png
(202.53 KB, 下载次数: 32)
|