|
//***************************************
// 空氣質量測試儀設計
// 使用單片機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, 下載次數: 45)
下載附件
2021-12-16 14:43 上傳
|