我想用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(); //计算辐射强度
}
|