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

📄 simpleplcfunc.c

📁 AVR典型实例.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
void INIT_TIMER(void)
{
    unsigned char i;
	for(i=0;i<MAX_TIMER;i++)  // 停止所有定时器的运行
	{
	    TimerMutex[i] = NORUN;
		TimerAddMutex[i] = NORUN;
		TimerSubMutex[i] = NORUN;
	}

}
// 自动调整系统时钟
void AutoTime(void)
{
	if(now.second > 59)
	{
		now.second = 0;
		now.minute ++;
	}
	if(now.minute>59)
	{
		now.minute = 0;
		now.hour++;
	}
	if(now.hour>23)
	{
		now.hour = 0;
		now.day++;
	}
	if(now.day>30)
	{
		now.month++;
		now.day = 1;
	}
	if(now.day == 0)
	   now.day = 1;
    if(now.month == 0)
	   now.month = 1;
	if(now.month>12)
	{
		now.year++;
		now.month = 1;
	}

}
// 比较定时器日期和当前日期
// 如果当前时间大于指定定时器日期,返回0,相等返回1,小于返回2
unsigned char CompDate(unsigned char id)
{
	if(now.year < Timer[id].year)
	   return 2;	    
	if((now.year == Timer[id].year)&&(now.month < Timer[id].month))
	   return 2;
	if((now.year == Timer[id].year)&&(now.month == Timer[id].month))
	{
	   if(now.day == Timer[id].day)
	       return 1;
       else if(now.day < Timer[id].day)
	       return 2;
	   return 0;
     }
	 return 0;
}
// 比较定时器小时、分钟和秒是否大于当前时间
// 如果当前时间大于指定定时器时间,返回0,相等返回1,小于返回2
unsigned char CompHour(unsigned char id)
{
	if(now.hour < Timer[id].hour)
	   return 2;	    
	if((now.hour == Timer[id].hour)&&(now.minute < Timer[id].minute))
	   return 2;
	if((now.hour == Timer[id].hour)&&(now.minute == Timer[id].minute))
	{
	   if(now.second == Timer[id].second)
	       return 1;
       else if(now.second < Timer[id].second)
	       return 2;
	   return 0;
     }
	 return 0;
}
// 比较定时器滴答是否大于当前时间
// 如果当前滴答大于指定定时器滴答,返回0,相等返回1,小于返回2
unsigned char CompTick(unsigned char id)
{
	if(now.count < Timer[id].count)
	    return 2;
    if(now.count == Timer[id].count)
	    return 1;
    return 0;
}
// 比较当前全部时间是否大于定时器时间
// 如果当前全部时间大于指定定时器时间,返回0,相等返回1,小于返回2
unsigned char CompTime(unsigned char id)
{
	switch(CompDate(id))
	{
	case 0: // 大于
	    return 0;
    case 1: // 相等
	    switch(CompHour(id))
		{
		case 0:
		     return 0;
        case 1:  // 相等
		     switch(CompTick(id))
			 {
			 case 0:
			      return 0;
             case 1:  // 相等
			      return 1;
             case 2:   // 小于
			      return 2;
			 }
        case 2:
		     return 2;
		}
   case 2: // 小于
        return 2;
	}
  return 0;
}
// 设置定时器

// 可以设置在多少小时、多少分钟、多少秒和多少百分之一秒内触发
void SetTimer(unsigned char id,unsigned char Hour,unsigned char minute,unsigned char second,unsigned char tick)
{
	Timer[id].year = now.year;
	Timer[id].month = now.month;
	Timer[id].day = now.day;
	Timer[id].minute = now.minute + minute;
	Timer[id].second = now.second + second;
	Timer[id].count = now.count + tick;

    // 调整时间为合法时间
	if(Timer[id].count > 99)
	{
		Timer[id].count = Timer[id].count-100;
		Timer[id].second++;
	}
	if(Timer[id].second > 59)
	{
		Timer[id].second = Timer[id].second-60;
		Timer[id].minute++;
	}
	if(Timer[id].minute > 59)
	{
		Timer[id].minute = 0;
		Timer[id].hour++;
	}
	if(Timer[id].hour > 23)
	{
		Timer[id].hour = 0;
		Timer[id].day++;
	}
	if(Timer[id].day > 30)
	{
		Timer[id].day = 1;
		Timer[id].month++;
	}
	if(Timer[id].month > 12)
	{
		Timer[id].month = 1;
		Timer[id].year++;
	}
}
// 启动指定的定时器
void StartTimer(unsigned char id)
{
	TimerMutex[id] = RUN;
}
// 停止指定的定时器
void StopTimer(unsigned char id)
{
    TimerMutex[id] = NORUN;
}
// 定时器动作函数
void TCMP(unsigned char id ,unsigned char hour,
    unsigned char minute, unsigned char second,unsigned char tick,unsigned char out_less,
	unsigned char out_equ,unsigned char out_great)
{
	unsigned char tmpPORT1;
	tmpPORT1 = tmpPORT[cur_tmp_p]; // 得到前一个元件连接电路输出是有信号还是没信号
	wdt_reset();  // 喂狗,表示程序在正常运行
	if(tmpPORT1) // 如果有信号
	{
    	if(TimerMutex[id] == NORUN)   // 如果定时器还没开始运行
		{
			SetTimer(id,hour,minute,second,tick);  // 装订定时器延迟时间
        	StartTimer(id);  // 启动定时器
		}
        switch(CompTime(id)) // 比较延迟时间是否到达
		{
		case 0:  // 当前时间大于定时器定时时间
			OUT(out_great);
			break;
		case 1:  // 当前时间等于定时器定时时间
            OUT(out_equ);
			break;
		case 2:  // 当前时间小于定时器定时时间
		    OUT(out_less);
			break;
		}

    }else{  // 如果无信号输入
	    StopTimer(id);   // 停止定时器
	    PUSH_STACK();
		tmpPORT[cur_tmp_p]=0;
	    OUT(out_less);
		OUT(out_equ);
		OUT(out_great);
        tmpPORT[cur_tmp_p] = pop_stack();
    }

}
// 定时器时间增加函数
void TADD(unsigned char id ,unsigned char hour,
    unsigned char minute, unsigned char second,unsigned char tick)
{
	unsigned char tmpPORT1;
	struct STime time;
	tmpPORT1 = tmpPORT[cur_tmp_p]; // 得到前一个元件连接电路输出是有信号还是没信号
	if(tmpPORT1) // 如果有信号
	{
	    if(TimerAddMutex[id] == NORUN)
		{
			TimerAddMutex[id] = RUN;
            time.hour = Timer[id].hour+hour;
            time.minute = Timer[id].minute+minute;
            time.second = Timer[id].second+second;
            time.count = Timer[id].count+tick;

			SetTimer(id,time.hour,time.minute,time.second,time.count);  // 装订增加后的定时器延迟时间
		}
	}else{
		TimerAddMutex[id] = NORUN;

	}
}
// 定时器时间增加函数
void TSUB(unsigned char id ,unsigned char hour,
    unsigned char minute, unsigned char second,unsigned char tick)
{
	unsigned char tmpPORT1;
    unsigned char subMutex[6];  // 借位数组,从0开始是:秒、分钟、小时、日期、月、年(6)
	unsigned char i;  
	struct STime time;
	tmpPORT1 = tmpPORT[cur_tmp_p]; // 得到前一个元件连接电路输出是有信号还是没信号
	if(tmpPORT1) // 如果有信号
	{
	    if(TimerSubMutex[id] == NORUN)
		{
			TimerSubMutex[id] = RUN;
		    for(i=0;i<7;i++)
			    subMutex[i] = 0;
            // 做时间减法
			if(Timer[id].count >= tick)
			{
				time.count = Timer[id].count - tick;	
			}else{
				time.count = Timer[id].count+100-tick;
				subMutex[0] = 1; // 产生了秒借位
			}
			if(subMutex[0])  // 处理带秒借位的减法
			{
			    if(Timer[id].second >=(second+subMutex[0]))  // 如果借位以后还够减
				{
				    time.second = Timer[id].second - second - subMutex[0];
				}else{  // 如果借位后不够减
					subMutex[1]++; //  分钟借位
					time.second = Timer[id].second + 60 - second - subMutex[0];
				}
			}else{  // 处理不带秒借位的减法
			    if(Timer[id].second >=second)  // 如果够减
				{
				    time.second = Timer[id].second - second;
				}else{  // 如果不够减
					subMutex[1]++; //  分钟借位
					time.second = Timer[id].second + 60 - second;
				}
			}
			if(subMutex[1])  // 处理带分钟借位的减法
			{
			    if(Timer[id].minute >=(minute+subMutex[1]))  // 如果借位以后还够减
				{
				    time.minute = Timer[id].minute - minute - subMutex[1];
				}else{  // 如果借位后不够减
					subMutex[2]++; //  小时借位
					time.minute = Timer[id].minute + 60 - minute - subMutex[1];
				}
			}else{  // 处理不带分钟借位的减法
			    if(Timer[id].minute >= minute)  // 如果够减
				{
				    time.minute = Timer[id].minute - minute;
				}else{  // 如果不够减
					subMutex[2]++; //  小时借位
					time.minute = Timer[id].minute + 60 - minute;
				}
			}
			if(subMutex[2])  // 处理带小时借位的减法
			{
			    if(Timer[id].hour >=(hour+subMutex[2]))  // 如果借位以后还够减
				{
				    time.hour = Timer[id].hour - hour - subMutex[2];
				}else{  // 如果借位后不够减
					subMutex[3]++; //  日期借位
					time.hour = Timer[id].hour + 24 - hour - subMutex[2];
				}
			}else{  // 处理不带小时借位的减法
			    if(Timer[id].hour >= hour)  // 如果够减
				{
				    time.hour = Timer[id].hour - hour;
				}else{  // 如果不够减
					subMutex[3]++; //  日期借位
					time.hour = Timer[id].hour + 24 - hour;
				}
			}
			// 处理日期
			if(subMutex[3])  // 处理带日期借位的减法
			{
			    if(Timer[id].day >=subMutex[3])  // 如果借位以后还够减
				{
				    time.day = Timer[id].day - subMutex[3];
				}else{  // 如果借位后不够减
					subMutex[4]++; //  日期借位
					time.day = Timer[id].day + 30 - subMutex[3];
				}
			}
			// 处理月份
			if(subMutex[4])  // 处理带月份借位的减法
			{
			    if(Timer[id].month >=subMutex[4])  // 如果借位以后还够减
				{
				    time.month = Timer[id].month - subMutex[4];
				}else{  // 如果借位后不够减
					subMutex[5]++; //  日期借位
					time.month = Timer[id].month + 12 - subMutex[4];
				}
			}
			// 处理年
			if(subMutex[5])  // 处理带年借位的减法
			{
			    if(Timer[id].year >=subMutex[5])  // 如果借位以后还够减
				{
				    time.year = Timer[id].year - subMutex[5];
				}else{  // 如果借位后不够减
					year_err++; //  年产生借位,借无可借,置出错位
					time.year = Timer[id].year; // 既然借无可借,干脆算今年
				}
			}


			SetTimer(id,time.hour,time.minute,time.second,time.count);  // 装订增加后的定时器延迟时间
		}
	}else{
		TimerSubMutex[id] = NORUN;

	}
}
// 系统变量初始化
void INIT(void)
{
	unsigned char i;
	for(i=0;i<MAX_TMPPORT;i++)  // 清空上次的虚拟电路组的状态
		tmpPORT[i] = 1;
	for(i=0;i<MAX_APUT;i++) // 清除中间继电器的状态
        APORT[i] = 0;
#ifdef _PLC_USE_C_
    for(i=0;i<MAX_COUNTER;i++)
	{
		Counter[i] = 0;
		CounterOut[i] = 0;
		CounterNowValue[i] = 0;
	}
#endif
    OUTPORT = 0;  // 清空上次的输出状态
	wdt_enable(WDTO_500MS); 
}

// 计数器函数
#ifdef _PLC_USE_C_
// 复位计数器
void RESETC(unsigned char id)
{
   if(tmpPORT[cur_tmp_p])
   		Counter[id] = 0;
}
// 计数器计数函数
// 入口参数:计数器号,计数器最大值
void COUNTER(unsigned id,unsigned topval)
{
    unsigned char tmp = tmpPORT[cur_tmp_p];
	unsigned char nowValue = CounterNowValue[id];
	wdt_reset();  // 喂狗,表示程序在正常运行
	if(tmp)  // 如果有电
	{
	    if(nowValue == 0)  // 来了一个计数脉冲
		{
		    nowValue = 1;
			if(Counter[id]<topval)
			    Counter[id]++;  // 计数值加一
            if(Counter[id]>=topval)
			{
			    CounterOut[id] = 1;  // 如果到达设定值,计数器输出高电平
			}            
            
		}
	}else{  // 如果是低电平,则将当前计数电平置低电平
	    nowValue = 0;
	}
	CounterNowValue[id] = nowValue;
}

#endif

⌨️ 快捷键说明

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