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

📄 hzmmimain18.c

📁 ATMEL的ATMEGA128驱动160×80液晶调试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		if(nv_c.code==0x23)
		{//召唤MMI数据命令
			if(nv_c.data[0]==0x06)
			{//召唤MMI版本号
				NV_ram_buf[1]=nv_c.s_node_addr & 0x0f;
				NV_ram_buf[2]=EEPROMread(eep_node_id);
				NV_ram_buf[3]=0x32;
				csprintf(&NV_ram_buf[4],VERSION2,TYPE_CODE);
				i=strlen(&NV_ram_buf[4]);
				NV_ram_buf[0]=i+4+2;
				NV_ram_buf[5+i]=0x0d;
				NV_ram_buf[6+i]=0x0a;
				net_out(1);
			}
			else
			if(nv_c.data[0]==0x05)
			{//调取MMI中报告
				if(pointer1()==FALSE)
				{//MMI没有报告
					ans_nva(0x16);
					return;
				}
				temp1=eep_ptr;//结尾
				if(pointer3(1)==FALSE)
				{//MMI没有报告
					ans_nva(0x16);
					return;
				}
				temp2=eep_ptr;//最老的报告起点
				eep_ptr=temp1;
				if(pointer3(0)==FALSE)
				{//MMI没有报告
					ans_nva(0x16);
					return;
				}
				temp3=eep_ptr;//最新的报告起点
				
				if(temp1>temp2)
					temp3=temp1-temp2;
				else
					temp3=(MAX_REPORT_EEP/17)-temp2+temp1;
				if(temp3==1)
				{//MMI只有一个报告
					memcpy_e(disp_buffer1,(byte*)(0x4000+eep_rpt_buf+eep_ptr*17),16);
					disp_buffer1[16]=0;
					tran_rpt();
					net_send(1,strlen(disp_buffer1),(nv_c.s_node_addr&0x0f),
							0x32,2|0x80,0,disp_buffer1);
					return;
				}
RX_A:
				disp_buffer1[0]=0;
				eep_ptr=temp2;
				temp1=(nv_c.s_node_addr&0x0f);
				for(k=1;k<=temp3;k++)
				{//从eeprom里取数据拷贝到网络缓冲区
					memcpy_e(disp_buffer,(byte*)(0x4000+eep_rpt_buf+eep_ptr*17),16);
					disp_buffer[16]=0;
					strcat(disp_buffer1,disp_buffer);

					if((EEPROMread(eep_rpt_buf+eep_ptr*17+16)==0x0a)
					 ||(strlen(disp_buffer1)>=32)||(k==temp3))
					{
						key=(k==temp3)?0x32:0xb2;
						tran_rpt();
						net_send(1,strlen(disp_buffer1),temp1,key,2|0x80,0,disp_buffer1);
						if(k==temp3)
						{
							net_send(0,0,0,0,0,0,0);
							return;
						}
						disp_buffer1[0]=0;
						key=net_wait();
						if(key==0x03)
							goto RX_A;
						else
						if(key!=0x02)
						{
							net_send(0,0,0,0,0,0,0);
							return;
						}
					}
					eep_rpt_inc(eep_ptr);
				}
				return;
			}
		}
	}
}
void set_quit_key(void)
{
	cstrcpy(disp_buffer,"按SET键确认\r  按QUIT键退出");
	str_hz(3*16,2,disp_buffer);
}
//串口接收数据有效性判断
byte poll_good(void)
{
	rcv_cnt=com_i;

	if(rcv_cnt==0)
		goto CPU_alm;
	if(rcv_cnt==1)	//只收到一个数
		goto RECV;
	if(chk_sum(rcv_cnt)!=0)
	{//校验和不对
		comm_timer=COM_TIMEOUT/6;//要求短时间内重发
		rcv_cnt=com_rcv(0x03);
		if(rcv_cnt==0)
			goto CPU_alm;
		if(rcv_cnt==1)
			goto RECV;
		if(chk_sum(rcv_cnt)!=0)
			goto CPU_alm;
	}
RECV://接收成功
	if(EEPROMread(eep_COMERR_CNT+poll_seq)!=0)
	{
		if(EEPROMread(eep_COMERR_CNT+poll_seq)>=ALM_NUMBER)
			init_disp();
		EEPROMwrite(eep_COMERR_CNT+poll_seq,0);
	}
	return TRUE;
//没收到或两次接受的校验和都不对,则cpu板出错的次数加1,
//当所有的CPU板通讯出错次数达到最大次数时复位
CPU_alm:
	if(EEPROMread(eep_COMERR_CNT+poll_seq)<ALM_NUMBER)
	{
		byte i;
		EEPROMwrite(eep_COMERR_CNT+poll_seq,EEPROMread(eep_COMERR_CNT+poll_seq)+1);
		for(i=1;i<=TOTAL_CPU_NUMBER;i++)
			if((EEPROMread(eep_CPU_NUB+i))&&
			   (EEPROMread(eep_COMERR_CNT+i)<ALM_NUMBER))
				break;
		if(i>TOTAL_CPU_NUMBER)
			application_restart();//所有的CPU板通讯出错次数达到最大次数时复位
		return FALSE;
	}
	else
	if(menu_in==FALSE)
	{//如果cpu板通讯出错的次数大于允许值时则告警
		csprintf(disp_buffer,"与CPU%d通信出错!",poll_seq);
		mediacy_hz(2*16,disp_buffer);
	}
	alarm();
	return FALSE;
}
void poll_out(void)
{
	if(EEPROMread(eep_COMERR_CNT+poll_seq)>=ALM_NUMBER)
		comm_timer=COM_TIMEOUT/3;//cpu板多次通讯不正常,则简短测试
	else
		comm_timer=COM_TIMEOUT;

	poll_rcv(0x00);
	return;
}
void poll_clr()
{
	for(;poll_com==1;)
		comm_with_lon();
	poll_com=0;
}
//轮巡cpu板,对送上来的报文,根据报文的第一个字节决定是否显示、是否向网络转发
void poll_timer_routine (void)
{
	byte i,j,key;

	if((ctl_data&COM_SEL)!=COM_SEL)//如果与PC通讯则不轮巡
		return;

	if(poll_com==1)
		return;
	if(poll_com==2)
	{
		poll_com=0;
		if(poll_good()!=FALSE)
			goto deal_com;
		else
			return;
	}
	for(i=1,j=0;i<=TOTAL_CPU_NUMBER;i++)
		if(EEPROMread(eep_CPU_NUB+i))
			j++;
	if(j==0)
	{//如果cpu板的个数为0,返回;
		if(menu_in==FALSE)
		{
			cstrcpy(disp_buffer,"请设置CPU!");
			cls();
			mediacy_hz(2*16,disp_buffer);
		}
		rcv_cnt=0;
		return;
	}

	if(keep_timer)
	{//在不应期内
		if((keep_timer==2)&&(sampleCPU!=0))
		{//装置启动后,采样CPU板有采样值送上来,第一次送上来的值存于0x400处
		 //在不应期结束前不轮巡采样CPU板
		 //在不应期即将结束时将其输出打印,并将以后的轮巡锁定在采样CPU板上
			i=menu_in;
			menu_in=TRUE;
			cls();//彻底清屏
			menu_in=i;
			
			STATUS_WORD=5;//打印期间避免键盘干扰
			cstrcpy(disp_buffer,"正在打印..");
			disp_prt(1*16+8);
			net_send(1,commu_buf[1+400]-5,commu_buf[3+400],
				commu_buf[5+400],2,0,&commu_buf[6+400]);
			poll_seq=sampleCPU-1;
			keep_timer=1;
		}
		else
		if((keep_timer==1)&&(sampleCPU!=0))
			poll_seq=sampleCPU-1;//将轮巡锁定在采样CPU板上,直至sampleCPU被清0
		else
		{
			keep_timer--;
			if(keep_timer==0)
				if(STATUS_WORD==5)
				{
					STATUS_WORD=0;
					cls();
				}
		}
	}
	if((STATUS_WORD==1)||(STATUS_WORD==2))
		poll_seq=(clz_prt&0x0e0)>>5;
	else
	if(EEPROMread(eep_CPU_NUB+0)==0)
	{//含有非CPU1板则逐一点名
		for(;;)
		{
			if(poll_seq<TOTAL_CPU_NUMBER)
				poll_seq++;
			else
				poll_seq=1;
			if((keep_timer>1)&&(sampleCPU==poll_seq)&&(j>1))
				continue;//不应期结束前,不对采样CPU点名
			if(EEPROMread(eep_CPU_NUB+poll_seq))
				break;
		}
	}
	else
		poll_seq=1;
	CPU_ID=poll_seq<<5;
	
	poll_out();
	poll_timer_f=TRUE;
	return;
deal_com:
//	disp_comm(rcv_cnt);//调试用
	i=8;//case 0x91:和case 0xB1:用
	switch(commu_buf[0])
	{//用第一个字节判断功能
		case 0x80://无报文
			if(Q_KEY[poll_seq]==0xaa)
			{
				if((word)CTL_DOT_CPU[poll_seq].str==0x0001)//录波CPU
					com_byte(CPU_ID|0x04);//请求结束
				if((STATUS_WORD!=1)||(CPU_ID!=(clz_old&0x0e0)))
					Q_KEY[poll_seq]=0;
			}
			if((keep_timer==1)&&(sampleCPU==poll_seq))
			{
				static cnt=0;
				cnt++;
				if(cnt>4)
				{
					sampleCPU=0;//采样CPU板已停止送采样,则sampleCPU清0
					if(STATUS_WORD==5)
						STATUS_WORD=0;
					cnt=0;
				}
			}
			break;

		case 0x81://送当地显示
			if(Q_KEY[poll_seq]==0xaa)
			{//请求退出状态
				com_byte(CPU_ID|0x04);//请求结束
				if(STATUS_WORD==1)
				{
					if(CPU_ID==(clz_old&0x0e0))
					{
						STATUS_WORD=0;
						Q_KEY[poll_seq]=0;
					}
				}
				else
				{
					STATUS_WORD=0;
					Q_KEY[poll_seq]=0;
				}
				return;
			}
			if((menu_in!=FALSE)&&(commu_buf[2]==0x09)&&(PT_RST!=FALSE))
			{//请求退出状态
				com_byte(CPU_ID|0x04);//请求结束
				return;
			}

			com_byte(CPU_ID | 0x02);//接收成功确认
			j=commu_buf[1]-2;

			for(;;)
			{//分析是否属于查看模拟量的报文
				char DzStrBuf[20];
				byte *iindex;
				const byte *cpp;
					
				if((STATUS_WORD!=1)&&(STATUS_WORD!=2))
					break;
				if((commu_buf[2]&0x01)==0)
					break;
				if((STATUS_WORD==2)&&(commu_buf[1]!=0x0d))
					return;
				if(clz_order!=FALSE)
				{//调取新模拟量时,第一次来的数不要
					clz_order=FALSE;
					return;
				}
				if(STATUS_WORD==1)
				{
					memcpy(disp_buffer,&commu_buf[3],j);
					disp_buffer[j]=0;
					memcpy(DzStrBuf,&commu_buf[3],3);
					DzStrBuf[3]=0;
					cstrcpy(DzStrBuf+10,"ON:");			//判是否是开入查看
					i=strcmp(DzStrBuf,DzStrBuf+10);
					if(i!=0)
					{
						cstrcpy(DzStrBuf+10,"DI:");		//判是否是开入查看
						i=strcmp(DzStrBuf,DzStrBuf+10);
					}
					if(i==0)
					{//是开入查看
						commu_buf[j+3]=0;
						commu_buf[j+4]=0;
						iindex=strchr(commu_buf+6,'T');//判是否含跳位
						{//先显示开入端子号,接着显示跳位,然后把后面的数据接上来显示
							if((iindex!=0)&&(*(iindex+1)=='W'))
							{
								*iindex=0;
								csprintf(disp_buffer,"开入端子号:\r %s跳位%s",commu_buf+6,iindex+2);//On:
							}
							else
							if((iindex!=0)&&(*(iindex+1)=='Y'))
							{
								*iindex=0;
								csprintf(disp_buffer,"开入端子号:\r %s停用%s",commu_buf+6,iindex+2);//On:
							}
							else
								csprintf(disp_buffer,"开入端子号:\r %s",commu_buf+6);//On:
						}
						LCD_display(16,0);
						return;
					}
					if(clz_old<clz_di)
					{//一般的零漂刻度都是0x09,只有开入以后的项目是0x01
						if((commu_buf[2]!=0x0d)
						 &&(commu_buf[2]!=0x09)
						 &&(commu_buf[2]!=0x08))
							break;
					}
				}
				{
					cls();
					disp_buffer[0]=0;
					if(EEPROMread(eep_CPU_NUB+0)==0)
						csprintf(disp_buffer,"CPU%d的",(clz_old&0x0e0)>>5);
					if(STATUS_WORD==2)
						cpp="对点:";
					else
					if((clz_old&0x1f)==0x11)
						cpp="零漂:";
					else
					if((clz_old&0x1f)==0x10)
						cpp="刻度:";
					else
					if((clz_old&0x1f)==0x12)
						cpp="阻抗:";
					cstrcpy(disp_buffer1,cpp);
					strcat(disp_buffer,disp_buffer1);
					mediacy_hz(16,disp_buffer);

					memcpy(disp_buffer,&commu_buf[3],j);
					disp_buffer[j]=0;
					if(STATUS_WORD==2)
						DZBchinese(disp_buffer,j,2);
					else
						floatchinese(disp_buffer,j,32);
				}
				return;
			}

			if(j>32)
				j=32;

			if(commu_buf[2] & 0x10)		//点亮运行灯
				PORTD|=RUN_LAMP;
			else
				PORTD&=~RUN_LAMP;

			if(commu_buf[2] & 0x04)		//告警
				alarm();

			if(commu_buf[2] &0x08)		//保存在ram中
			{
				if(RPT_TIME[0]==0xa5)
				{
					rpt_ram_clr();
					memcpy(rpt_ram_buf,&RPT_TIME[2],15);
					rpt_ram_buf[15]=' ';
					ram_ptr++;
					RPT_TIME[0]=0xa0;
					CYCLE_FLAG=TRUE;
					STATUS_WORD=0;
				}
				ram_save(j,0x81);
			}

			if(RPT_TIME[0]!=0xb5)
			if(commu_buf[2] & 0x02)		//保存在eeprom中
			{
				pointer1();
				eep_save(j,0x81);
			}
			if((commu_buf[2] & 0x01)&&(CYCLE_FLAG==FALSE)&&(ATTENTION==FALSE)
			 &&(STATUS_WORD==0)&&(menu_in==FALSE))
			{//滚屏显示0x81报文
				memcpy(disp_buffer,&commu_buf[3],j);
				disp_buffer[j]=0;
				if(desk_pause==0)//不暂停
				{
					deskchinese(j);//翻屏(桌面)文字
					for(j=0;j<50;j++)
					{
						out_rst24();
						if(has_key&0x80)
							break;
						dlyms(10);
					}
					if(has_key==(KEY_UP|0x80))
					{
						has_key&=0x7f;
						desk_pause=10;
					}
				}
			}

			break;

		case 0x91://要求MMI以NVA转发报文
			i=0;
		case 0xB1://以NVB转发报文
			if(i==0)
				i=1;//以NVA转发报文
			else
				i=2;//以NVB转发报文
			com_byte(CPU_ID | 0x02);//向cpu板发确认命令

			if(commu_buf[4]==0x33)
			{
				j=2;//0x33报文,多帧发送时有两字节为头
				if(commu_buf[5]==0x09)
					j=1;
			}
			else
			if(commu_buf[4]==0x30)
				j=1;//0x30报文,多帧发送时有一字节为头
			else
				j=0;//其它报文
			net_send(i,commu_buf[1]-4,commu_buf[2],commu_buf[4],0,j,&commu_buf[5]);

			break;

		case 0xA1:
			com_byte(CPU_ID | 0x02);
				return;
			break;

		case 0xC1://送当地显示,同时以NVA向网络转发
			if(Q_KEY[poll_seq]==0xaa)
			{//请求停止发送
				com_byte(CPU_ID | 0x04);//发送请求停止命令
				if(STATUS_WORD==1)
				{
					if(CPU_ID==(clz_old&0x0e0))
					{
						STATUS_WORD=0;
						Q_KEY[poll_seq]=0;
					}
				}
				else
				{
					STATUS_WORD=0;
					Q_KEY[poll_seq]=0;
				}
				return;
			}

			com_byte(CPU_ID | 0x02);//确认收齐一帧数据

			rcv_cnt=commu_buf[1]-5;
			if(rcv_cnt>32)
				rcv_cnt=32;

			if(keep_timer!=1)
			if(PT_RST!=FALSE)
			{//如果在不应期内,延长不应期,为每个CPU读六次的时间
				keep_timer=0;
				for(i=1;i<=TOTAL_CPU_NUMBER;i++)
				{
					if(EEPROMread(eep_CPU_NUB+i))
						keep_timer++;
				}
				keep_timer*=6;
			}
			if(RPT_TIME[0]!=0xb5)
			if(commu_buf[2]&0x02)	
			{//数据要求存EEPROM
				pointer1();

				if((ATTENTION==FALSE)&&(PT_RST==FALSE))
				{//没有关注且在不应期之外
					report_time_lock();//取当前时间
					sampleCPU=0;
					if((STATUS_WORD==3)||(STATUS_WORD==4))
					{//如果是测试时产生的报文
						STATUS_WORD=0;

⌨️ 快捷键说明

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