51单片机脉冲信号的计数和LCD显示

51单片机脉冲信号的计数和LCD显示

设计目标和思路

在个人剂量仪开发的过程中,从探头输出的核脉冲信号经过后期放大,成形,滤波以及甄别之后,成为一系列脉冲信号输出,这种脉冲信号由于衰变的随机性,并不是固定频率的脉冲信号。我们本次设计就是针对这种脉冲进形脉冲信号的计数以及在LCD1602显示屏上面的显示。
这是C语言的代码部分

#include"reg51.h"	
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <intrins.h>
#define uint8_t unsigned char	 //0-255
#define uint16_t unsigned int	//0-65535
#define uint32_t unsigned long 	   //0-4294967295
#define uchar unsigned char
#define u8 unsigned char
#define u16 uint16_t
#define uchar unsigned char 
#define uint unsigned int 
unsigned long millis = 0; //1MS¼ÆÊý

sbit rs = P2^0; //LCD1602 RS
sbit rw = P2^1;	//LCD1602 RW
sbit en = P2^2;	//LCD1602 EN		 

sbit Input1 = P3^2;   //定义P32为第一路脉冲输入
uint8_t Input_1_Last_V = 0;
uint16_t Input_1_Count = 0; 

sbit Input2  = P3^3; //定义P33为第二路脉冲输入
uint8_t Input_2_Last_V = 0;
uint16_t Input_2_Count = 0;/

sbit Key1 = P1^0;  //这个向下翻
sbit Key2 = P1^1;	//向上翻按键
#define display_Flag_Jishu_CH1_CH2 1   //
#define display_Flag_Jishu_DY 2
#define MIN_Display_flag display_Flag_Jishu_CH1_CH2
#define MAX_Display_flag display_Flag_Jishu_DY
uint8_t display_Mode_or_Set = 0; 
uint8_t display_Flag = 1;		

uint8_t display_sec = 0; 

uint8_t jishu_sec = 0;   

uint16_t CH_Count_Buffer[30];  
uint8_t Count_D = 0;
*******************************************************************************/
void delay(uint8_t i)	
{
    while(i--);
}
void delay_1s(uint8_t s)
{
	unsigned int i;
	unsigned char j; 

	while(s--)
		for (i = 1000; i > 0; i--) 

			for (j = 124; j > 0; j--) ; 
}

/*******************************************************************************
* 这段程序很容易找到		   : LCD初始化
*******************************************************************************/
void lcd_wcom(uint8_t com)  //LCD1602 写命令
{
	rs = 0;
	rw = 0;
	en = 0;
	P0 = com;
	delay(100);
	en = 1;
	delay(100);
	en = 0;
}
void lcd_wdat(uint8_t dat)	//LCD1602写数据
{
	rs = 1;
	rw = 0;
	en = 0;
	P0 = dat;
	delay(100);
	en = 1;
	delay(100);
	en = 0;
}
void lcd_init(void)    //LCD1602初始化
{
	lcd_wcom(0x38);
	lcd_wcom(0x0c);
	lcd_wcom(0x06);
	lcd_wcom(0x01);	
}

/***********************************************************************
/**********************************************************************
*******************************************************************************/
void Timer_Init(void)  //
{
	TMOD |= 0x01; 


	TH0 = 0xFC;
	TL0 = 0x18;

	EA = 1;	
	ET0 = 1; 
	   
	TR0 = 0;/
}
 /***********************************************************************
一路脉冲显示数值
*******************************************************************************/
void ReadInput(void)   
{
	if(Input1 == 0)
	{
		Input_1_Last_V = 0;
	}
	else if((Input1 == 1)&&(Input_1_Last_V == 0))
	{
		Input_1_Last_V = 1;
		Input_1_Count++;
	}
	//第二路脉冲显示计数值
	if(Input2 == 0)
	{
		Input_2_Last_V = 0;
	}
	else if((Input2 == 1)&&(Input_2_Last_V == 0))
	{
		Input_2_Last_V = 1;
		Input_2_Count++;
	}
}
 /***********************************************************************
LCD显示程序
*******************************************************************************/
void LCD_DisPlay_Jishulv_CH1_CH2(void)  
{

	lcd_wcom(0x80);
	lcd_wdat('C');
	lcd_wdat('H');
	lcd_wdat('1');
	lcd_wdat(':');


	lcd_wdat((Input_1_Count%100000/10000) +'0');//万
	lcd_wdat((Input_1_Count%10000/1000) +'0');//千
	lcd_wdat((Input_1_Count%1000/100) +'0');//百
	lcd_wdat((Input_1_Count%100/10) +'0');//十
	lcd_wdat((Input_1_Count%10) +'0');//个


	//通道2显示
	lcd_wcom(0x80+0x40);
	lcd_wdat('C');
	lcd_wdat('H');
	lcd_wdat('2');
	lcd_wdat(':');
	
	lcd_wdat((Input_2_Count%100000/10000) +'0');//万
	lcd_wdat((Input_2_Count%10000/1000) +'0');//千
	lcd_wdat((Input_2_Count%1000/100) +'0');//百
	lcd_wdat((Input_2_Count%100/10) +'0');//十
	lcd_wdat((Input_2_Count%10) +'0');//个
}
 /***********************************************************************
LCD显示自检程序
*******************************************************************************/
void Display_Checking(void)
{
	lcd_wcom(0x80);
	lcd_wdat('C');
	lcd_wdat('h');
	lcd_wdat('e');
	lcd_wdat('c');
	lcd_wdat('k');
	lcd_wdat('i');
	lcd_wdat('n');
	lcd_wdat('g');	
}
void Display_CheckFall(void)//自检失败
{
	lcd_wcom(0x80+0x40);
	lcd_wdat('C');
	lcd_wdat('h');
	lcd_wdat('e');
	lcd_wdat('c');
	lcd_wdat('k');
	lcd_wdat(' ');
	lcd_wdat('F');
	lcd_wdat('a');
	lcd_wdat('i');
	lcd_wdat('l');
}
void Display_CheckOk(void)//自检成功
{
	lcd_wcom(0x80+0x40);
	lcd_wdat('C');
	lcd_wdat('h');
	lcd_wdat('e');
	lcd_wdat('c');
	lcd_wdat('k');
	lcd_wdat(' ');
	lcd_wdat('O');
	lcd_wdat('K');	
}
 /***********************************************************************
动态显示
*******************************************************************************/
void Display(uint8_t display_Flag)
{
	switch (display_Flag)
	{
		case display_Flag_Jishu_CH1_CH2:
		LCD_DisPlay_Jishulv_CH1_CH2();
		break;
	}
}
 /***********************************************************************
按键子程序
*******************************************************************************/
void Button_Handler()//按键函数
{
	if(display_Mode_or_Set == 0) //设置模式
	{
		if(Key1 == 0)    //当按键1被按下
		{
			if(display_Flag>MIN_Display_flag)
			{
				display_Flag--;
				lcd_wcom(0x01);
				Display(display_Flag);
			}
			while(Key1 == 0);
		}
		if(Key2 == 0)    //当按键2被按下
		{
			if(display_Flag<MAX_Display_flag)
			{
				display_Flag++;
				lcd_wcom(0x01);
				Display(display_Flag);
			}
			while(Key2 == 0);
		}
	}
}
 /***********************************************************************
动态显示处理函数
*******************************************************************************/
void Display_Handler(void)
{
	if(display_Mode_or_Set == 0)
	{
		if(display_sec == 1)
		{
			Display(display_Flag);
			display_sec = 0;
		}
	}
}
/***********************************************************************
计数满30组更换
*******************************************************************************/
void DataHandler(void) //计数率统计
{
	static uint8_t firstTime = 1;//第一组不计算
	uint8_t i = 0;

	uint16_t last_Count = 0;
	uint16_t now_Count = 0;
	if(jishu_sec == 1)	      
	{

		for(i=0;i<30;i++)
		{
			//不满30组填入空白数据
			if(CH_Count_Buffer[i] == 0)	  
			{
				CH_Count_Buffer[i] = Input_1_Count+Input_2_Count;
                now_Count =  Input_1_Count+Input_2_Count;
				
				if(i == 0)
				{
					firstTime = 1;
				}
				else
				{
					last_Count = CH_Count_Buffer[i-1];
					
				}

				break;
			}
		}

		if(i == 30) //计数满30组
		{
			for(i=0;i<29;i++)
			{
				CH_Count_Buffer[i] = CH_Count_Buffer[i+1];
			}
			last_Count = CH_Count_Buffer[28];
			CH_Count_Buffer[29] =  Input_1_Count+Input_2_Count;
			now_Count = Input_1_Count+Input_2_Count;			
		}	
		if(firstTime == 1)
		{
			firstTime = 0;
		}
		else
		{

			if((now_Count>=(last_Count*10))||(last_Count>=(now_Count*10)))
			{				
				LED = 0; 
				for(i = 0;i<30;i++)
					CH_Count_Buffer[i] = 0;
				CH_Count_Buffer[0] = now_Count;
			}
		}
		Input_1_Count = 0;
		
		Input_2_Count = 0;
	
		jishu_sec = 0;
		
	}
}

 /***********************************************************************
进行自检
*******************************************************************************/
uint8_t self_checking() //自检程序
{
	uint16_t self_check_buffer[3];
	unsigned char xdata system_status=0;
	
	u8 JLZ=0;
	u8 JLL=0;
	uint8_t i = 0;
	uint8_t a = 1;
	u8 b=0;
	uint8_t count = 0;
	float v=0.3;
	TR0 = 1; //打开定时器
		while(i<3)
	{
		ReadInput();

		if(jishu_sec ==1) //1S
		{
			jishu_sec = 0;
			self_check_buffer[i] = Input_1_Count+Input_2_Count;
			Input_1_Count = 0;
			Input_2_Count = 0;
			i++;		
		}		
	}
判断自检是否成功
	for(count= 0;count<3;count++)
	{
		if((self_check_buffer[count]<1)||(self_check_buffer[count]>10000))   
		{	
			TR0 = 0;
			return 0;
		}		
	}
    	TR0 = 0;
    	return 1;
}
/***********************************************************************
主函数
*******************************************************************************/
void main()		 
{
	u16	 ad;
	uint8_t i = 0;
	lcd_init(); //LCD初始化
	Timer_Init(); //定时器初始化
	Display_Checking();//开始自检

	if(self_checking() == 1)
		Display_CheckOk();//当自检成功
	else
	{
		Display_CheckFall();
		while(1);//完成之后下一步
	}
	delay_1s(10);	
	  TR0 = 1;  //打开定时器
	while(1)	//
	{
		ReadInput();//读取输入		
		Button_Handler(); //按键函数
		Display_Handler(); //显示函数
		DataHandler(); //数据函数
	delay(10); 
	}
		i++;			
	}
}
定时器函数
void trigger_timer0() interrupt 1
{  
    TH0 = 0xFC;
    TL0 = 0x18;   
   millis++;
   if(millis%1000 == 0) 
   {
   	 display_sec = 1;
   	 jishu_sec = 1;  	 
   } 
}

整体仿真效果图,我这是加了其他模块,使用的话可以自行修改

write by 亦舒斋
交流联系QQ:1464475872

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值