⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 一个基本的平安钟控制程序
💻 C
字号:

/**********************************************************************
prjname:
author: 
version:0.2
控制过程分析说明:
系统进入后就不停的查询P3.2和P1.0,
由此分开P3.2程序和P1.0程序

P3.2程序:负责检测呼入情况
                  没有呼入就进入P1.0程序
                  有呼入,需要进入检测对方取消和本地取消
                  检测到本地取消就进入本地取消处理然后退到主循环
                  检测到对方取消就进入对方取消处理然后退到主循环

P1.0程序:负责检测本地呼叫情况
                  没有本地呼叫情况进入P3.2程序
                  检测呼叫结果
                  本次呼叫不成功,进入下次呼叫,直到结束退到主循环
                  本次呼叫成功,进入成功处理
                  检测本地取消和对方取消
                  检测到本地取消就进入本地取消处理然后退到主循环
                  检测到对方取消就进入对方取消处理然后退到主循环
*********************************************************************/
#include "micro.h"

void InitSystem(void);
void Singal_Scan(void);
void PLOW_Scan(void);
void TimerCounterJudge(void);
void PinCtr(uchar pinS,uchar delays,uchar Seconds,uchar PinST);
void Low_Scan(void);
void Reset_Check(void);

main()
{

	InitSystem();
   	  
	while(1)
	{

	/*****************************************************/
		if(Flag_10ms)
		{//这是一个系统运行的核心程序,单独独立出来
			Flag_10ms = 0;
			Singal_Scan();
			Low_Scan();
			PLOW_Scan();
		}
		if(Flag_100ms)
		{//这也是一个系统运行的核心程序,单独独立出来
			Flag_100ms = 0;
			TimerCounterJudge();
		}
	/********************系统的P32程序块**********************/
		if(FlagP32)
		{
			if((SYSPINSTA & Check_Signal)==Signal_En)		//检测到有对方取消
			{
				if((SYSPINSTA & Check_type)==Busy_Tone)	//确认有对方取消
				{
					PinCtr(1,0,HOLDON,Low);
					PinCtr(7,0,HOLDON,Hight);
					Reset_Check();				//所有信号标志复位
					continue;					//P32程序完成退出循环
				}
			}  
			if(SYSPINSTA & Line_Close)				//检查p3.5脚低脉冲
			{
				PinCtr(0,0,HOLDON,Low);
				PinCtr(7,0,HOLDON,Hight);	
				Reset_Check();					//所有信号标志复位
				continue;						//P32程序完成退出循环
			}  			
			continue;		//P32程序未完成,直接退出到主循环等待事件发生
		}
	/**********************系统的P10程序块**********************/	
		if(FlagP10)
		{
			if((SYSPINSTA & Check_Signal)==Signal_En)		//检测到有对方无确认
			{
				if((SYSPINSTA & Check_type)==Ring_respond)	//确认有对方无确认
				{
					Dailtimes++;				//系统只进行5次尝试
					if(Dailtimes>=5)
					{
						PinCtr(1,0,HOLDON,Low);
						PinCtr(7,0,HOLDON,Hight);
						Reset_Check();				//所有信号标志复位
						continue;					//P10程序完成退出循环						
					}
					pinnop11 = 0;				//P11先送低
					PinCtr(1,20,HOLDON,Hight);		//P11在2S后保持高
					PinCtr(2+Dailtimes,30,2,Hight);	//P1(2+Dailtimes)在3S后送200ms高
					Reset_Check();				//所有信号标志复位
					FlagP10 = 1;				//保证下次还是进入P10程序块
					continue;					//P32程序完成退出循环
				}
			}
			if((SYSPINSTA & Check_Signal)==Signal_En)		//检测到有对方取消
			{
				if((SYSPINSTA & Check_type)==Busy_Tone)	//确认有对方取消
				{
					PinCtr(1,0,HOLDON,Low);
					PinCtr(7,0,HOLDON,Hight);
					Reset_Check();				//所有信号标志复位
					continue;					//P32程序完成退出循环
				}
			}  			
			if(SYSPINSTA & H_F)				//P10程序块检测到免提就退出P10程序块
			{
				PinCtr(1,0,HOLDON,Low);
				PinCtr(7,0,HOLDON,Hight);
				Reset_Check();
				Dailtimes=0;
				continue;			//确认进入P10程序块,需要立即进入下一次
			}  
			continue;		//P10程序未完成,直接退出到主循环等待事件发生
		}
	/********************检查p3.2脚低脉冲*******************/		
		if(SYSPINSTA & Ring_In)
		{
			PinCtr(1,0,HOLDON,Hight);			//P1.1->H
			PinCtr(7,0,HOLDON,Low);			//P1.7->L
			PinCtr(0,5,20,Hight);				//将P3.7延时500ms,置高2s(200*10ms)钟
			Reset_Check();
			FlagP32 = 1;					//要求系统下次进入P32程序
			continue;			//确认进入P32程序块,需要立即进入下一次
		} 
	/********************检查免提低脉冲*******************/ 			
		if(SYSPINSTA & H_F)
		{
			PinCtr(1,0,HOLDON,Hight);		//P11保持高
			PinCtr(7,0,HOLDON,Low);		//P17保持低
			PinCtr(2,10,2,Hight);			//P12在1S后送200ms高
			Reset_Check();
			Dailtimes=0;
			FlagP10 = 1;					//要求系统下次进入P10程序
			continue;			//确认进入P10程序块,需要立即进入下一次
		}  
	}  
}

/***********************************************************************
subroutine name: initsystem
input variable:       /
output variable:    /
description: initialize the system variable,for interrupt\timer\uart\
***********************************************************************/
void InitSystem(void)
{

	uchar i;

	IE = 0;                	
	TMOD = 0x21;  			
	PCON = 0x80;  			
	SCON = 0x50;  		
	IP = 0x02;       		
	ET0 = 1;           		
	TCON = 0;        		
	LOAD_TIMER0(TimerH_1ms, TimerL_1ms);
	TI = 0;
	RI = 0;
	for(i=0;i<TrkTal;i++)
	{
		CHECK_Reg[i] = 0;
		TimerCount[i] = 0;
	}

	SYSPINSTA = 0;
	FlagP10 = 0;
	FlagP32 = 0;

	Counter1ms = 0;
	Flag_10ms = 0;
	Counter10ms = 0;
	Flag_100ms = 0;

	Read_LowST = 0;
	Read_SingalST = 0;
	Read_PlowST = 0;
	Dailtimes = 0;

	pinnop11 = 0;
	pinnop12 = 0;
	pinnop13 = 0;
	pinnop14 = 0;
	pinnop15 = 0;	
	pinnop16 = 0;
	pinnop17 = 1;
	pinnop37 = 0;
	
	TR0 = 1;
	EA = 1;
}

void Reset_Check(void)
{
	uchar i;
	
	for(i=0;i<TrkTal;i++)
	{
		CHECK_Reg[i] = 0;
		TimerCount[i] = 0;
	}
	FlagP32 = 0;
	FlagP10 = 0;
	SYSPINSTA = 0;
}
/************************************************************************
subroutine name: Singal_Scan
input variable:  P3口为信号音电平输入口,共2路信号
output variable: SYSPINSTA
description: 主要扫描信号忙音和回铃  
*************************************************************************/
void Singal_Scan(void)
{
uchar i;
uint temp;
uchar GROUP_ST_ANAL,GROUP_ST_NEW;

	GROUP_ST_NEW = P3>>3;
	GROUP_ST_ANAL=GROUP_ST_NEW^Read_SingalST;
	Read_SingalST = GROUP_ST_NEW;
	
	for(i=0;i<2;i++)
	{
		temp = CHECK_Reg[i];					//为了节省时间使用内部变量
		if( GROUP_ST_ANAL & 0x01 )
		{
			if(temp>(EXT_SCAN_ON+ResRingTone_ContinueC))	 //表示接收到4秒电平
			{
				if((TimerCount[i]&0xf0)==0x20)			//mode =2
				{
					TimerCount[i]++;
					TimerCount[i]+= 0x10;				//mode =3
					if((TimerCount[i]&0x0f)>ResRingperiod)
					{
						SYSPINSTA |= 3<<(2*i);	//表示接收到回铃
						CHECK_Reg[i]=0;
						TimerCount[i] = 0;
						continue;					//检测到后直接退出
					}
				}
				else
				{
					TimerCount[i] = 0x30;
				}
			}
			else if(temp>(EXT_SCAN_ON+ResRingTone_ContinueO))
			{
				if((TimerCount[i]&0xf0)==0x30)			//mode = 3
				{
					TimerCount[i]&= 0x0f;
					TimerCount[i]+= 0x20;				//mode =2
				}
				else
				{
					TimerCount[i] = 0x20;
				}
			}
			else if(temp>(EXT_SCAN_ON+BusyTone_Continue))
			{
				if((TimerCount[i]&0xf0)==0x10)
				{
					TimerCount[i]++;
					if((TimerCount[i]&0x0f)>Busyperiod*2)
					{
						SYSPINSTA |= 2<<(2*i);	//表示接收到信号
						TimerCount[i] = 0;
						CHECK_Reg[i] = 0;
						continue;					//检测到后直接退出
					}
				}
				else
				{
					TimerCount[i] = 0x10;
				}
			}
			else
			{
				TimerCount[i] = 0;
			}
			CHECK_Reg[i] = EXT_SCAN_ON;					//重新启动检测计数	
		}
		else
		{
			if( CHECK_Reg[i] >=EXT_SCAN_ON)
				CHECK_Reg[i]++;
		}		
		GROUP_ST_ANAL = GROUP_ST_ANAL >>1;
	}
}

/*********************************************************************************
subroutine name: PLOW_Scan
input variable:       /
output variable:   SYSPINSTA
description: 主要判断脚P32是否到达预定的周期数         
*********************************************************************************/
void PLOW_Scan(void)
{
uchar GROUP_ST_ANAL,GROUP_ST_NEW;

	GROUP_ST_NEW = P3&0x04;
	GROUP_ST_NEW >>= 2;
	GROUP_ST_ANAL=GROUP_ST_NEW^Read_PlowST;
	Read_PlowST = GROUP_ST_NEW;
	
	if( GROUP_ST_ANAL & 0x01 )
	{
		CHECK_Reg[2] = EXT_SCAN_ON;
		if( EXT_SCAN_PRI )
			CHECK_Reg[2]++;
		else
			goto NO_PRI;
	}
	else
	{
		if( CHECK_Reg[2] >EXT_SCAN_ON)
		{
			if( CHECK_Reg[2] >EXT_SCAN_LEN )
			{
NO_PRI: 		if( (GROUP_ST_NEW&0X01)==0)
				{
					TimerCount[2]++;
					GROUP_ST_NEW =P3;
					GROUP_ST_NEW = ~GROUP_ST_NEW;
					GROUP_ST_NEW &=0x03;
					GROUP_ST_NEW++;
					if(TimerCount[2]>=GROUP_ST_NEW)	//如果P32收到低,查看是否收到P3031个数字
					{
						SYSPINSTA |=0x40; 			//收到就第5位为1
						TimerCount[2]= 0;
					}
				}
				CHECK_Reg[2] = EXT_SCAN_OFF;
			}
			else
			{
				CHECK_Reg[2]++;
			}
		}
		else
		{
			CHECK_Reg[2] = EXT_SCAN_OFF;
		}
	}
}

/********************************************************************************
subroutine name: Low_Scan
input variable:       /
output variable:   SYSPINSTA
description: 主要判断脚P35,P10电平          
********************************************************************************/
void Low_Scan(void)
{
uchar i;
uchar GROUP_ST_ANAL,GROUP_ST_NEW;

	GROUP_ST_NEW = P3>>4;							//取P3.5的数据,放置到比较数据的第2位
	GROUP_ST_NEW &=0X02;
	GROUP_ST_NEW += P1&0x01;						//取P1.0的数据,放置到比较数据的第1位
	GROUP_ST_ANAL=GROUP_ST_NEW^Read_LowST;
	Read_LowST = GROUP_ST_NEW;
	
	for(i=3;i<5;i++) 								//i=3,表示P1.0,                i=4,表示P3.5
	{												//数据的第4位             数据的第5位
		if( GROUP_ST_ANAL & 0x01 )
		{
			CHECK_Reg[i] = EXT_SCAN_ON;
			if( EXT_SCAN_PRI )
				CHECK_Reg[i]++;
			else
				goto NO_PRI;
		}
		else
		{
			if( CHECK_Reg[i] >EXT_SCAN_ON)
			{
				if( CHECK_Reg[i] >EXT_SCAN_LEN )
				{
NO_PRI: 			if( (GROUP_ST_NEW&0X01)==0)
						SYSPINSTA |=1<<(i+1); 		//由移i位后构成新数据
					CHECK_Reg[i] = EXT_SCAN_OFF;
				}
				else
				{
					CHECK_Reg[i]++;
				}
			}
			else
			{
				CHECK_Reg[i] = EXT_SCAN_OFF;
			}
		}
		GROUP_ST_ANAL = GROUP_ST_ANAL >>1;
		GROUP_ST_NEW = GROUP_ST_NEW >>1;
	}
}

/******************************************************************************
subroutine name: TimerCounterJudge
input variable:       /
output variable:    /
description: 系统的定时器函数          
******************************************************************************/
void TimerCounterJudge(void)
{
uchar pinNO;

	for(pinNO=0;pinNO<8;pinNO++)
	{
		if(SYSpin[pinNO].delay==0)
		{
			if((SYSpin[pinNO].counter<250)&&(SYSpin[pinNO].counter>1))
			{
				SYSpin[pinNO].counter--;
			}
			else if(SYSpin[pinNO].counter==1)
			{
				SYSpin[pinNO].counter--;
				SYSpin[pinNO].st =~SYSpin[pinNO].st;
				SYSpin[pinNO].st &=0X01;
			}
			else if(SYSpin[pinNO].counter==0)
			{
				continue;
			}
			switch(pinNO)
			{
				case 1:
					if(SYSpin[pinNO].st&0x01)
						pinnop11 = 1;
					else
						pinnop11 = 0;
					break;
				case 2:
					if(SYSpin[pinNO].st&0x01)
						pinnop12 = 1;
					else
						pinnop12 = 0;
					break;
				case 3:
					if(SYSpin[pinNO].st&0x01)
						pinnop13 = 1;
					else
						pinnop13 = 0;
					break;
				case 4:
					if(SYSpin[pinNO].st&0x01)
						pinnop14 = 1;
					else
						pinnop14 = 0;
					break;
				case 5:
					if(SYSpin[pinNO].st&0x01)
						pinnop15 = 1;
					else
						pinnop15 = 0;
				break;
				case 6:
					if(SYSpin[pinNO].st&0x01)
						pinnop16 = 1;
					else
						pinnop16 = 0;
					break;
				case 7:
					if(SYSpin[pinNO].st&0x01)
						pinnop17 = 1;
					else
						pinnop17 = 0;
					break;
				case 0:
					if(SYSpin[pinNO].st&0x01)
						pinnop37 = 1;
					else
						pinnop37 = 0;
					break;
				default:
					break;
			}
		}
		else
		{
			SYSpin[pinNO].delay--;
		}
	}
}

/*****************************************************************************
subroutine name: PinCtr
input variable: 	  /
output variable:	/
description:将pinS脚置PinST持续时间为Seconds*10ms		   
****************************************************************************/
void PinCtr(uchar pinS,uchar delays,uchar Seconds,uchar PinST)
{
	SYSpin[pinS].delay = delays;	
	SYSpin[pinS].counter = Seconds;
	SYSpin[pinS].st = PinST;
}

/****************************************************************************
subroutine name: Timer0Int
input variable:       /
output variable:    /
description:           
***************************************************************************/
void Timer0Int(void) interrupt 1
{

	LOAD_TIMER0(TimerH_1ms, TimerL_1ms);
	Counter1ms++;
	if(Counter1ms <10)
		return;
	Counter1ms = 0;
	Counter10ms++;
	Flag_10ms = 1;
	if(Counter10ms <10)
		return;
	Counter10ms = 0;
	Flag_100ms = 1;	
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -