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

📄 control.c

📁 公司实习的时候做的路灯控制程序
💻 C
字号:



/*
*********************************************************************************************************
* 	
* 包含头文件	
* 	
*********************************************************************************************************
*/

#include <pic16f716.h>
#include "control.h"

#define	__PIC16F716_H


//__CONFIG(XT & WDTDIS & PWRTDIS & PROTECT & BORDIS); 


/*
*********************************************************************************************************
* 	
* 全局变量定义	
* 	
*********************************************************************************************************
*/

UBYTE 	SUNFLAG;
UBYTE	SUNFLAG0;
UBYTE	SUNFLAG1;		//阳光检测标志位
UBYTE 	BATTERRYVOLTAGE;	//电池电压检测值
UBYTE 	OCVOTLAGE;		//过流电压检测值
UBYTE	bOldState;		//老状态
UBYTE	bNowState;		//新状态
UBYTE 	sec;			//秒
UWORD 	min;			//分
UBYTE   hour;			//时 	

/*
*********************************************************************************************************
* 
* 函数名称:void interrupt  isr(void)
*	
* 输入变量:无
* 
* 输出变量:无
* 
* 功能描述:中断服务函数
*	
*********************************************************************************************************
*/
void interrupt isr(void) //@ 0x10		
{
//	unsigned char x;
	if(TMR1IF) 
	{
  	Timer1Counter++;
	if (Timer1Counter >= ONESECOND) 
		{
		sec++;
		if (sec >= 56) {	// 56
			min++;	
			if (min >= 910) {
//				regTimer.hour++;
				min = 0;
			}
			sec = 0;
		}
		Timer1Counter = 0;
		}
		TMR1H = 0x0b;	//0x3c;			
		TMR1L = 0xdb;	//0xaf;			//预设时间寄存器初值
		TMR1IF = 0;
	}
//	if(ADIF)
//	{
//		ADIF = 0;  
//   	}
}
/*
*********************************************************************************************************
* 
* 函数名称:void DelayTime(UWORD wTimer, UBYTE ucTimes)
*	
* 输入变量:延时时间长短数据
* 
* 输出变量:无
* 
* 功能描述:不精确延时
*********************************************************************************************************
*/

void DelayTime(UWORD wTimer, UWORD ucTimes)
{
	UWORD i;
	for (i = ucTimes;i>0;i--);
	for (i = wTimer;i>0;i--);
	
} 
/*
*********************************************************************************************************
* 
* 函数名称:void InitVariable(void)
*	
* 输入变量:无
* 
* 输出变量:无
* 
* 功能描述:初始化变量
*********************************************************************************************************
*/

void InitVariable(void)
{
	sec = 0;
	min = 0;
	hour = 0;
	SUNFLAG		=	0;
	SUNFLAG0	=	0;
	SUNFLAG1	=	0;
//	bOldState	= 	1;
	bNowState	=	0;
	CHARGEOUT	=	0;	//RB6输出低电平3843输出触发脉宽最窄,充电电流为零。 
	LOADOUT	=	1;		//RB4输出高电平导走负载触发电压,负载切断。
	Timer1Counter = 0;
	TMR1H = 0x0b;	////0x3c;			
	TMR1L = 0xdb;	//0xaf;			//预设时间寄存器初值
		
} 

/*
*********************************************************************************************************
* 
* 函数名称:void BatterryCharge(void)
*	
* 输入变量:无
* 
* 输出变量:无
* 
* 功能描述:充电控制
*********************************************************************************************************
*/

//void BatterryCharge(void)
//{
//} 

/*
*********************************************************************************************************
* 
* 函数名称:UWORD TimeCheck(void)
*	
* 输入变量:无
* 
* 输出变量:时间参数(以分钟计)
* 
* 功能描述:读取RB3~RB0的预制时间值后返回
*********************************************************************************************************
*/
UWORD TimeCheck(void)
{
	UBYTE PortValue;	//定义端口变量
	PortValue = 0x00;
	PortValue = PORTB;
	PortValue = PortValue&0x0f;	//确认低四位有效
	if(PortValue == ONEHOUR)
	{
		return	BACKONEHOUR;	//定时1小时
	}
	else if (PortValue == TWOHOUR)
	{
		return	BACKTWOHOUR;	//定时2小时
	}
	else if (PortValue == THREEHOUR)
	{
		return	BACKTHREEHOUR;	//定时3小时
	}	
	else if (PortValue == FOURHOUR)
	{
		return	BACKFOURHOUR;	//定时4小时
	}	
	else if (PortValue == FIVEHOUR)
	{
		return	BACKFIVEHOUR;	//定时5小时
	}
	else if (PortValue == SIXHOUR)
	{
		return	BACKSIXHOUR;	//定时6小时
	}
	else if (PortValue == SEVENHOUR)
	{
		return	BACKSEVENHOUR;	//定时7小时
	}
	else if (PortValue == EGIHTHOUR)
	{
		return	BACKEGIHTHOUR;	//定时8小时
	}	
	else if (PortValue == NINEHOUR)
	{
		return	BACKNINEHOUR;	//定时9小时
	}
	else if (PortValue == TENHOUR)
	{
		return	BACKTENHOUR;	//定时10小时
	}	
	else if (PortValue == ELEVENHOUR)
	{
		return	BACKELEVENHOUR;	//定时11小时
	}	
	else if (PortValue == TWELVEHOUR)
	{
		return	BACKTWELVEHOUR;	//定时12小时
	}	
	else if (PortValue == THIRTHHOUR)
	{
		return	BACKTHIRTHHOUR;	//定时13小时
	}	
	else if (PortValue == FOURTHHOUR)
	{
		return	BACKFOURTHHOUR;	//定时14小时
	}	
	else if (PortValue == FIFTHHOUR)
	{
		return	BACKFIFTHHOUR;	//定时15小时
	}	
//	return	0x00;

}
/*
*********************************************************************************************************
* 
* 函数名称:void AdConvertResult(UBYTE channel)
*	
* 输入变量:需要采样的模拟量的通道 
* 
* 输出变量:无
* 
* 功能描述:获得需要采样的模拟量的数据
*	
*********************************************************************************************************
*/
void AdConvertResult(UBYTE channel)
{
	UBYTE i;			//定义临时循环变量
	if(channel)			//通道值为真
	{
		CHS0 = 1;		//选择通道1(充电电压值判定)采样
		CHS1 = 0;		//第一位通道选择位置零
		CHS2 = 0;		//第二位通道选择位置零
	}
	else	//通道值为零通道
	{
		CHS0 = 0;		//选择通道0(过流判定)采样
		CHS1 = 0;		//第一位通道选择位置零
		CHS2 = 0;		//第二位通道选择位置零
	}
	for (i = 0x00;i<0x10;i++)	//采样16次用作数字简单滤波以求消除毛刺
	{
		GODONE = 1;				//启动转换
		while(GODONE);			//等待转换结束
		AdResult[i] = ADRES;	//存储结果
	}
}
/*
*********************************************************************************************************
* 
* 函数名称:UBYTE SortAdConResult(void)
*	
* 输入变量:采样的模拟量的数据 
* 
* 输出变量:滤波后实际使用的模拟量
* 
* 功能描述:模拟量的数据软件滤波获得使用为判据的模拟量的数据(中值滤波)
*	
*********************************************************************************************************
*/
UBYTE SortAdConResult(void)
{
	UBYTE i,iflag;			//定义临时循环变量
	UBYTE AdSort,AdVer;		//定义临时变量
	UWORD	AdVer1;

	for (i=0;i<0x10;i++)		//排序
	{
		for(iflag=i+1;iflag<0x10;iflag++)
	  	{
	 		if (AdResult[i] >= AdResult[iflag])	
	 		{
				AdSort = AdResult[i];
				AdResult[i] = AdResult[iflag];
				AdResult[iflag] = AdSort;
			} 
		} 
	 }
		
	AdVer1 = 0;
	for(i=2;i<0x0d;i++)
    	{
    		AdVer1 += AdResult[i];	
    	}
       	AdVer  =    AdVer1/0x0b;		//结束排序取平均值
       	return	AdVer;			//返回平均值
}
/*
*********************************************************************************************************
* 
* 函数名称:UBYTE DetectState(void)
*	
* 输入变量:无
* 
* 输出变量:各个不同的充放电状态
* 
* 功能描述:充电控制--参考附带的说明文件表
*********************************************************************************************************
*/

UBYTE DetectState(void)
{
	UBYTE bState;				//定义状态变量
	bState = 0;				//初始状态变量
	AdConvertResult(BATTCHECKCHANNEL);			//电池电压采样
	BATTERRYVOLTAGE = SortAdConResult();	//取最终电池电压	
	if(BATTERRYVOLTAGE > BATTCHARGEHIGH)	//电池电压大于充电保护值28
	{
		bState |= 0x02;			//状态位置位
	}
	else					//电池电压小于充电保护值
	{
		bState &= 0xfd;			//状态位清零
	}

	if(BATTERRYVOLTAGE > BATTCHARGELOW)	//电池电压大于放电保护值22
	{
		bState &= 0xfb;			//状态位清零
	}
	else					//电池电压小于放电保护值
	{
		bState |= 0x04;			//状态位置位
		bOldState = 0x00;		//第二天
	}	
	AdConvertResult(OVERCURRENTCHANNEL);	//过流电压采样
	OCVOTLAGE = SortAdConResult();		//取最终过流电压	
	if(OCVOTLAGE > OVERCURRENTHIGH)		//过流电压大于过流保护值(10A)
	{
		bState |= 0x08;			//状态位置位
	}
	else					//过流电压小于过流保护值(10A)
	{
		bState &= 0xf7;			//状态位清零
	}	

//	CHARGEOUT	=	0;		//RB6输出低电平3843输出触发脉宽最窄,充电电流为零。 
	SUNFLAG0	= RB5;			//读取阳光检测电平信号
	DelayTime(0xFFff,0xFFff);
	DelayTime(0xFFff,0xFFff);
	DelayTime(0xFFff,0xFFff);
	DelayTime(0xFFff,0xFFff);
	SUNFLAG1	= RB5;			//读取阳光检测电平信号
	SUNFLAG 	= 	SUNFLAG0&SUNFLAG1;	//获得阳光检测电平信号
	if(!SUNFLAG)
	{
		bState |= 0x01;			//状态位置位
		bOldState = 0x01;		//第二天
	}
	else
	{
		bState &= 0xfe;			//状态位清零
	}	
	if(min >= TimeCheck())		//负载通电定时判别
	{
		bState |= 0x10;			//状态位置位	
		bOldState = 0x00;		//第二天
	}
	else
	{
		bState &= 0xef;			//状态位清零
	}
	
	return bState;
}
/*
*********************************************************************************************************
* 
* 函数名称:void main(void)
*	
* 输入变量:无
* 
* 输出变量:无
* 
* 功能描述:主函数
*	
*********************************************************************************************************
*/
void main(void)
{
//	CLRWDT();			//禁止看门狗	
//	FOSC1 =	1;			//振荡器模式选择位
//	FOSC0 =	0;				
//	CONFIG_ADDR	=	0x82;	//HS振荡器>=4MHz 
/////////////timer0 init//////////////////////////////////////
	PSA = 0;			//TIMER0预分频 1/256
	PS2 = 1;
	PS1 = 1;
	PS0 = 1;
	T0CS = 0;			//选择内部指令周期时钟
   	TMR0 = 0x00;			//选择TMR0寄存器清零
//	TMR0IE=0;			//TMR0 溢出使能关闭
	T0IE = 0;			//禁止TIMER0溢出中断
	T0IF = 0;			//TIMER0中断标志清零
/////////////timer1 init//////////////////////////////////////
	T1CKPS1	= 1;			//TIMER1预分频 1/8
	T1CKPS0	= 1;
	TMR1CS = 0;			//使用内部时钟(FOSC/4)
	TMR1H = 0x0b;	//0x3c;			
	TMR1L = 0xdb;	//0xaf;			//预设时间寄存器初值
	TMR1ON = 1;			//TMR1 溢出使能	
	T1OSCEN = 0;			//关闭振荡器
	TMR1IE = 0;			//允许TIMER1溢出中断
	TMR1IF = 0;			//TIMER1中断标志清零
/////////////timer2 init//////////////////////////////////////	
	T2CKPS1 = 1;			//TIMER2预分频 1/16
	T2CKPS0 = 1;
	TMR2ON = 0;			//TMR2关闭
	TMR2IE = 0;			//禁止中断
	TMR2IF = 0;			//TIMER2中断标志清零
////////////external init//////////////////////////////////////		
	INTE = 0;			//不允许外部中断
//   	TXIE = 0; 	        	//发送中断屏蔽 
//   	RCIE = 0;              		//接收中断屏蔽
   	RBIE = 0;			//RB口电平中断屏蔽
   	CCP1IE = 0;			//禁止CCP1 中断
   	INTF = 0;			//外部中断标志清零
   	RBIF = 0;			//RB口电平中断标志清零	
   	CCP1IF = 0;			//CCP1中断标志清零
/////////////ad convert init////////////////////////////////////
	OVERCURRENT = INPUTDIRECT;    	//负载过流输入模拟量端口
	BATTCHECK = INPUTDIRECT;    	//电池充电电压输入模拟量端口
	ADCON1 = 0x00;			//配置模拟引脚/ 参考电压
					//PCFG2:PCFG0 AN3/RA3 AN2/RA2 AN1/RA1 AN0/RA0 VREF
					//    0x0       A        A       A       A    VDD
	ADCS1 = 0;
	ADCS0 = 0;			//A/D 转换时钟选择位FOSC/2
	ADON = 1;			//A/D 开启	
	ADIE = 0;			//不允许AD转换中断
	ADIF = 0;			//AD转换中断标志清零
/////////////I/O PORT init////////////////////////////////////
	LOADCONTROL = OUTPUTDIRECT;	//负载控制输出
	SUNCHECK = INPUTDIRECT;		//阳光检测输入
	CHARGECONTROL = OUTPUTDIRECT;	//充电控制输出
	CLKPRE0 = INPUTDIRECT;		//时钟预定义第0位输入		
	CLKPRE1 = INPUTDIRECT;		//时钟预定义第1位输入		
	CLKPRE2 = INPUTDIRECT;		//时钟预定义第2位输入	
	CLKPRE3 = INPUTDIRECT;		//时钟预定义第3位输入
////////////////////////////////////////////////////////////////////////////////
	InitVariable();			//初始化变量
	bOldState	= 	1;	//第二天
	PEIE = 1;			//开放所有未被屏蔽的外设中断
  	GIE = 1;			//使能所有未被屏蔽的中断
////////////////////////////////////////////////////////////////////////////////
while(1)
	{
		bNowState	=	DetectState();		//检测状态
		switch(bNowState)
		{
			case	0x00:
			case	0x02:
				if(bOldState)
				{
				TMR1IE = 1;			//启动定时
				CHARGEOUT	=	0;	//RB6输出低电平3843输出触发脉宽最窄,充电电流为零。 
				LOADOUT		=	0;	//RB4输出低电平抬起负载触发电压,负载开通。					
				}
				break;
			case	0x01:
			case	0x05:
			case	0x0d:
			case	0x11:
			case	0x15:
			case	0x19:
			case	0x1b:
			case	0x1d:
				TMR1IE = 0;			//关闭定时
				LOADOUT		=	1;	//RB4输出高电平导走负载触发电压,负载切断。		
				sec = 0;
				min = 0;
				hour = 0;		
				CHARGEOUT	=	1;	//RB6输出高电平3843输出触发脉宽最宽,充电电流最大。 
				//CHARGEOUT	=	0;
				break;
			case	0x08:
			case	0x0a:
			case	0x0c:
			case	0x18:
			case	0x1a:
			case	0x1c:
				TMR1IE = 0;			
				InitVariable();			
				break;
			case	0x03:
			case	0x04:
			case	0x13:
			case	0x14:
				TMR1IE	= 0;			
				InitVariable();			
				break;
			default:
				TMR1IE	= 0;			
				InitVariable();			
				break;				
		}
		
	}
}

⌨️ 快捷键说明

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