|
//***************************************
// 空氣質(zhì)量測(cè)試儀設(shè)計(jì)
// 使用單片機(jī)STC90C516RD
// 晶振:11.0592M
// 顯示:1602液晶顯示//編程思路:
//簡(jiǎn)單的就是做一個(gè)1ms的定時(shí)中斷(要準(zhǔn)點(diǎn)可以定時(shí)時(shí)間減少,反之定時(shí)時(shí)間加大)
//在中斷中檢測(cè)IO口的電平,是低就 加1
//1s內(nèi)總共檢測(cè)1000次 ,檢測(cè)累加的值除以10就是百分?jǐn)?shù),也就是低脈沖率。
//****************************************
#include"Reg52.H" /* 調(diào)用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 無符號(hào)8位整型變量 */
typedef signed char S8; /* defined for signed 8-bits integer variable 有符號(hào)8位整型變量 */
typedef unsigned int U16; /* defined for unsigned 16-bits integer variable 無符號(hào)16位整型變量 */
typedef signed int S16; /* defined for signed 16-bits integer variable 有符號(hào)16位整型變量 */
typedef unsigned long U32; /* defined for unsigned 32-bits integer variable 無符號(hào)32位整型變量 */
typedef signed long S32; /* defined for signed 32-bits integer variable 有符號(hào)32位整型變量 */
typedef float F32; /* single precision floating point variable (32bits) 單精度浮點(diǎn)數(shù)(32位長(zhǎng)度) */
typedef double F64; /* double precision floating point variable (64bits) 雙精度浮點(diǎn)數(shù)(64位長(zhǎng)度) */
unsigned char sChar_i=0;//寫入數(shù)據(jù)sChar指針
unsigned char sendFlag = 0; //未發(fā)送數(shù)據(jù)時(shí)
unsigned char receFlag =0; //未接受到數(shù)據(jù)時(shí)
//*********************************************
//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; //低脈沖時(shí)間
U16 Temp0=0; //低脈沖率
uc sChar[50]={'\0'};
void sendChar(unsigned char sendValue); //發(fā)送一字節(jié)數(shù)據(jù)
void sendAll(unsigned char *pValue); //發(fā)送一組數(shù)據(jù)
//
//*********************定時(shí)器T0用于定時(shí)1MS********
timer0() interrupt 1 using 1 //T/C0中斷服務(wù)程序, 每1ms中斷一次
{
number_t0++;
if(PWM==0) lt_time++; //每1ms檢測(cè)PWM脈沖是否為低電平
if(number_t0==1000) //munber_t0計(jì)數(shù)到1000MS,即1S,計(jì)算低脈沖率
{ TR0=0; //關(guān)閉定時(shí)器0
Temp0=(int)(lt_time/10); //計(jì)算低脈沖率
number_t0=0; //1S時(shí)間計(jì)數(shù)器和低脈沖率變量初始化為0,開始下一個(gè)測(cè)量周期
lt_time=0;
TR0=1; // 啟動(dòng)定時(shí)器0
}
TH0=0xfc;
TL0=0x66;
}
//
void dingshi()
{ TMOD=0x01;
TH0=0xfc; /*晶振:11.0592MHz,定時(shí)1ms*/
TL0=0x66;
ET0=1;
TR0=1;
EA=1;
DelayMs( 200 ); /* 上電延時(shí) */
}
//xin//
void initSer()//初始化
{
TMOD=0x20; //定時(shí)器工作方式,選擇了定時(shí)器1,工作方式2 八位初值自動(dòng)重裝的8位定時(shí)器。
TH1=0xfd; //定時(shí)器1初值 ,設(shè)置波特率為9600 配合為晶振11.0529MHZ,晶振的電容是20uf?
TL1=0xfd;
TR1=1; //開啟定時(shí)器1
SM0=0; //屬于SCON寄存器
SM1=1; //串口工作方式1,10位異步接收,(8位數(shù)據(jù))波特率可變
REN=1; //允許串行口接收位
EA=1; //允許中斷(總閘)
ES=1; //允許串口中斷
}
void sendChar(unsigned char Value) //發(fā)送一個(gè)字節(jié)數(shù)據(jù)
{
SBUF = Value;
sendFlag = 1; //設(shè)置發(fā)送標(biāo)志位,發(fā)一字節(jié)就置位
while(sendFlag); //直到發(fā)完數(shù)據(jù),將sendFlag清零后,才退出sendChar函數(shù)
}
void sendAll(unsigned char *pValue) //發(fā)送一組數(shù)據(jù)
{
while((*pValue) != '\0') //如果沒有發(fā)送完畢就繼續(xù)發(fā)
{
sendChar(*pValue); //發(fā)送1字節(jié)數(shù)據(jù)
pValue++; //指向下1個(gè)字節(jié)
}
}
void serInt() interrupt 4 //中斷函數(shù)
{
//TI——發(fā)送中斷bai標(biāo)志位,可尋址標(biāo)志位。方式0時(shí),發(fā)送完第8位數(shù)據(jù)后,由硬件置位,其它方式下,在發(fā)送或停止位之前由硬件置位,因此,TI=1表示幀發(fā)送結(jié)束,TI可由軟件清“0”。
//RI——接收中斷標(biāo)志位.可尋址標(biāo)志位。接收完第8位數(shù)據(jù)后,該位由硬件置位,在其他工作方式下,該位由硬件置位,RI=1表示幀接收完成。
//在串口中斷處理時(shí),TI,RI都需要軟件清"0",硬件置位后不可能自動(dòng)清0,此外,在進(jìn)行緩沖區(qū)操作時(shí),需要ES=0,以防止中斷出現(xiàn)。
if(RI) //接收數(shù)據(jù),手動(dòng)將RI清0
{
RI=0;
if(SBUF=='\0'||SBUF=='#')
{
sChar[sChar_i++]='\0';
receFlag=1; //修改接受標(biāo)志,便于主函數(shù)進(jìn)入while中發(fā)數(shù)據(jù)
}
else
{
sChar[sChar_i++]=SBUF; //每次接受8位,存在SBUF里,轉(zhuǎn)存到數(shù)組中
}
}
if(TI) //發(fā)送數(shù)據(jù)
{
TI = 0; //發(fā)送完一個(gè)數(shù)據(jù)
sendFlag = 0; //清標(biāo)志位
}
}
//
//***********************主程序****************************
void main()
{ U8 DisplayBuf[16];
/* 存儲(chǔ)轉(zhuǎn)換后的數(shù)據(jù) */
dingshi();
initSer(); //xin /* 上電延時(shí) */
LCD1602_Init();
LCD1602_WriteUSerCode(); /* 寫入用戶自定義字符 */
LCD1602_SetDisplayPosition(0,1); /* 顯示顯示位置 */
LCD1602_WriteString("Air quality test");
while(1) /*循環(huán)*/
{
sprintf(DisplayBuf," low rate=%3d",Temp0); /*顯示低脈沖率*/
LCD1602_SetDisplayPosition(0,2); /* 顯示顯示位置 */
LCD1602_WriteString(DisplayBuf);
if(receFlag)
{
LED=~LED;
sChar_i=0;//接受數(shù)組指針歸0,以便以下次接受
sendAll(sChar);
if(strlen(sChar)==4&&sChar[0]=='L'&&sChar[1]=='E'&&sChar[2]=='D')
{
P1=sChar[3];
}
receFlag=0;
}
if(sendFlag) //發(fā)送完畢之后,在電腦端輸出。
{
TI=1; //printf之前必須將T1置為1才行。
while(!TI);
sendFlag=0;
}
}
}
|
-
1.png
(202.53 KB, 下載次數(shù): 45)
下載附件
2021-12-16 14:43 上傳
|