我想用51單片機做一個蓋革計數器,蓋革管發出脈沖經過芯片過濾成方波,用外部中斷器1進行計數,定時器0定20s通過公式計算一次輻射強度然后通過1602顯示,定時器1專門用于延時的定時,不知道為什么老卡在歡迎語那里不動,請大佬指點QAQ這卡了我一個星期卡的好難受啊,以下是代碼:
/*********************************************************************
*名稱:蓋革計數器
*功能:測量電離輻射值
*版本:0.13
*********************************************************************/
#include <reg51.h>
#include "lcd.h"
#define _2s 200 //延時2s
float S; //單精度數
uint t; //定義全局變量用于延時計數
uint k; //定義全局變量用于計算脈沖數
sbit rad = P3^2; //電離計數
sbit beep = P1^0; //蜂鳴器引腳
uchar revo[]=" Revolution! "; //歡迎語部分
uchar dang[]=" Danger! "; //危險輻射報警
uchar radi[]=" Radiation "; //輻射值標題
uchar code unit[5] = {'u','S','v','/','h'}; //輻射單位顯示數組
uchar code ASCII[11] = {'0','1','2','3','4','5','6','7','8','9','.'}; //數字顯示數組
uchar disbuff[8] ={0,0,0,0,0,0,0,0};
bit flag = 0;
/*********************************************************************
*名稱:定時器模塊
*功能:定時器延時及中斷
*輸入:無
*輸出:無
*********************************************************************/
void delayms(uint x)//定時器10毫秒級延時函數
{
t=x;
while(t);
}
void InitTimer0()//定時器0初始化函數(得到20s時間計時)
{
TMOD=0x01; //定時器0,工作方式1
//定時10ms
TH0 = 0xDC; //高八位
TL0 = 0x00; //低八位
ET0= 1; //打開定時器0中斷
EA = 1; //打開總中斷
TR0= 1; //打開定時器0
}
void InitTimer1()//定時器1初始化函數(延時定時器)
{
TMOD=0x10; //定時器1,工作方式1
//定時10ms
TH1 = 0xDC; //高八位
TL1 = 0x00; //低八位
ET1= 1; //打開定時器1中斷
EA = 1; //打開總中斷
TR1= 1; //打開定時器1
}
void Timer0() interrupt 1 //定時器1服務函數
{
static uint i;
TH1=0XDC;
TL1=0X00;
i++;
if(i==2000) //20s計算一次
{
i=0;
}
}
void Timer1() interrupt 3 //定時器0服務函數
{
TH0 = 0xDC;
TL0 = 0x00;
t--;
}
/*********************************************************************
*名稱:顯示模塊
*功能:lcd1602液晶顯示
*輸入:無
*輸出:無
*********************************************************************/
void welcome()//歡迎語函數
{
InitLcd1602(); //屏幕初始化
LcdShowStr(0,0,revo); //顯示歡迎語
delayms(_2s);
Lcd1602_Write_Cmd(0x01); //清屏
LcdShowStr(0,0,radi); //顯示輻射標題
DisplayOneChar(4,1,ASCII[10]); //顯示小數點
DisplayOneChar(11,1,unit[0]); //顯示輻射單位uSv/h
DisplayOneChar(12,1,unit[1]);
DisplayOneChar(13,1,unit[2]);
DisplayOneChar(14,1,unit[3]);
DisplayOneChar(15,1,unit[4]);
}
/*********************************************************************
*名稱:外部中斷模塊
*功能:外部中斷計數及危險報警
*輸入:無
*輸出:無
*********************************************************************/
void Int1Init()
{
//設置INT1
IT1=1;//跳變沿出發方式(下降沿)
EX1=1;//打開INT1的中斷允許。
EA=1;//打開總中斷
}
void Int1() interrupt 2 //外部中斷1的中斷函數(測量蓋革管脈沖數)
{
delayms(1000); //延時消抖
if(rad==0)
++k;
if(k>65535)
flag=1;
}
/*********************************************************************
*名稱:脈沖計數模塊
*功能:蓋革計數器脈沖計數
*輸入:無
*輸出:無
*********************************************************************/
void calculate()
{
S=k/(1.67*235);
k=0;
if(S>=9999||flag==1)
{
Lcd1602_Write_Cmd(0x01); //清屏
LcdShowStr(0,0,dang); //顯示危險
while(1)
{
beep=~beep; //蜂鳴器常響,LED燈常亮
delayms(1); //頻率尖銳
}
}
else
{
long A;
A=S*10000;
disbuff[0]=A/10000000; //千位
disbuff[1]=A%10000000/1000000; //百位
disbuff[2]=A%1000000/100000; //十位
disbuff[3]=A%100000/10000; //個位
disbuff[4]=A%10000/1000; //十分位
disbuff[5]=A%1000/100; //百分位
disbuff[6]=A%100/10; //千分位
disbuff[7]=A%10; //萬分位
DisplayOneChar(0, 1, ASCII[disbuff[0]]);
DisplayOneChar(1, 1, ASCII[disbuff[1]]);
DisplayOneChar(2, 1, ASCII[disbuff[2]]);
DisplayOneChar(3, 1, ASCII[disbuff[3]]);
DisplayOneChar(5, 1, ASCII[disbuff[4]]);
DisplayOneChar(6, 1, ASCII[disbuff[5]]);
DisplayOneChar(7, 1, ASCII[disbuff[6]]);
DisplayOneChar(8, 1, ASCII[disbuff[7]]);
}
}
/*********************************************************************
*名稱:main
*功能:蓋革計數器
*輸入:無
*輸出:無
*********************************************************************/
void main()
{
InitTimer0(); //設置定時器0
Int1Init(); //設置外部中斷1
InitTimer1(); //設置定時器1
welcome(); //歡迎語
calculate(); //計算輻射強度
}
|