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

📄 hzmmimain18.c

📁 ATMEL的ATMEGA128驱动160×80液晶调试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
#define __main__
#include "hzmmi18.h"

//--------------  CONSTANTS  -----------------------//
#define ALM_NUMBER 3		//与CPU板通讯失败告警前失败的次数
#define TOTAL_CPU_NUMBER 6	//最大cpu个数

#define MAX_LON_BUF 7		//LON网输入缓冲区大小,必须是2的n次方减1
#define MAX_NV_O 27			//LON网络输出变量数据区长度
#define MAX_NV_I 26			//LON网络输入变量数据区长度

#define COM_TIMEOUT  1200	//与CPU板通讯时限
#define LON_WAITTIME 2000	//等待LON网应答时限

#define POLL_PERIOD 500;	//每500ms轮巡各CPU板
#define PC_DETECT 180;		//与pc机通讯状态空置时间
#define CYCLE_PERIOD 3;		//每3s报告滚屏
//--------------- FUNCTION PROTOTYPES ----------------//
byte EEPROMread(word location);
byte EEPROMwrite(word location,byte byte);
byte net_send(byte,byte,byte,byte,byte,byte,byte *);
void event_routine(void);
void comm_with_lon(void);
void reset_routine(void);
void trigger_routine(void);
void poll_timer_routine(void);
void nv_update_routine(void);
void key_routine(void);
void clock_timer_routine(void);
void cycle_timer_routine(void);
byte get_clock_setting(byte item,byte *tm_str,byte);
byte lb_set(void);
void set_time(void);
byte display_menu(const byte*);
void rpt_ram_clr(void);
void ram_save(byte,byte);
void eep_save(byte,byte);
void alarm (void);
void send_time (void);
void init_disp(void);
void set_cursor_position(byte,byte,const byte *);
byte get_key (void);
void poll_rcv(byte);
word com_rcv(byte);
void disp_prt(byte rol);
void disp_wait(byte rol);
void set_quit(void);
void net_rst(void);

void LCD_display(byte,byte);
byte fun_key_idx(byte);
byte sel_idx(byte,byte);
byte sel_idx2(byte,byte,byte,byte);
byte sel_data_idx(byte,byte);
byte sel_setting_idx(byte,byte);
byte setting_process(byte *,word);
byte send_setting(byte*,word);
void net_out(byte);
byte cpu_nmb(void);
byte select_menu(const byte*);
byte sf_hidden_code(void);
byte ts_hidden_code(void);
byte hidden_code(void);
byte rmtc_op(byte,byte);
void ans_nva(byte);
byte anx_menu(byte*,byte,byte);
void press_rst_key(void);
void out_rst24(void);
void poll_clr(void);
byte net_wait(void);
byte pointer1(void);
byte pointer3(byte);
void report_time_lock(void);
void eep_ram(void);
int  FindString(const DaiMa *,char *);
void DZBchinese(char *,byte,byte); 
void deskchinese(byte);
void floatchinese(char *,byte,byte);
byte reportchinese(byte,byte);
void prt_set(void);
void tran_rpt(void);
void clr_CYCLE_FLAG(void);

byte WORK_SETTING_AREA;       //当前定值区标记数(标记符)
byte TOTAL_SETTING_AREA;      //最大定值区号
word work_mode;		//工作模式。不同装置的不同处理,由此区分。
byte clz_order;		//零漂刻度新命令下达标志
word clz_old;		//零漂刻度当前指针  
word clz_di;		//零漂刻度开入指针,其后的刻度选项特别处理
word clz_bzd;		//零漂刻度对点指针,UP,DOWN键选择时越过去
word clz_prt;		//零漂刻度打印指针,UP,DOWN键选择时越过去
word clz_total;		//零漂刻度总数指针
word clz_total_num;	//零漂刻度总数
byte sampleCPU;		//装置启动后,主动上送采样值的CPU板号
byte CPU_ID;		//cpu点名标示位
byte poll_seq;		//cpu点名序号
byte cpu_name;		//菜单选择的cpu板序号
byte cpu_set_flag;	//cpu定值修改标志
byte STATUS_WORD;	//桌面显示所处的状态:0,循环显示;1,零漂刻度;2,对点;3,4,准备接收报告
byte PC_QUIT;		//KEY_QUIT标记,PC通讯标记
word waiting;		//关注时的等待时间
word rcv_cnt;		//收到的字符长度
word s_count;
byte ram_ptr,eep_ptr,cycle_ptr,head_line,frist_line;//与报告相关的指针
byte RPT_TIME[18];	//报告时间暂存
byte Q_KEY[7];		//各cpu板响应KEY_QUIT的纪录
byte ATTENTION,PT_RST,CYCLE_FLAG;//关注标志,不应期标志,循环标志
int S_EEP;			//当前显示的报告位于EEPROM中的位置
byte rpt_ram_buf[MAX_REPORT_RAM+16];//ram报告缓冲区
byte NV_ram_buf[MAX_NV_O+4];		//网络数据缓冲区
byte yb_bgn;		//各cpu板软压板名在数组中的位置
byte GPS_en;		//GPS的工作方式及当前状态
byte net_err;		//LON网芯片状态

extern byte time_str[];		//当前时间串
extern word mstimer2;		//时间串后的毫秒数值
extern word ms_val;			//GPS脉宽

typedef struct {
		byte lenth;				//长度
		byte o_node_addr;		//目标地址
		byte s_node_addr;		//源地址
		byte code;				//代码
		byte data[MAX_NV_O];	//数据
		}NV_def1;
typedef struct {
		byte lenth;
		byte o_node_addr;
		byte s_node_addr;
		byte code;
		byte data[MAX_NV_I];
		byte asfdjk1;			//防治出错附加的预留
		byte asfdjk2;			//防治出错附加的预留
		}NV_def2;

byte ALM_WORD_att;	//告警状态字
byte menu_in;		//进入主菜单标记
byte time_setting;	//正在修改时间标记
NV_def2 nv_c;
NV_def2 nv_cb[MAX_LON_BUF+1];	//临时网络缓冲区
byte endpoint;		//临时网络缓冲区尾指针
byte bgnpoint;		//临时网络缓冲区头指针

#define eep_sbxh			0x0000		//0x0000,设备选型
#define eep_GPS				0x0001		//0x0001,GPS工作方式
#define eep_test			0x0002		//0x0002,面板测试设定
#define eep_node_id			0x0003		//0x0003,装置地址
#define eep_CPU_NUB			0x0004		//0x0004--0x000b//[8],CPU板投退
#define eep_COMERR_CNT		0x000c		//0x000c--0x0013//[7],与CPU通讯出错次数纪录
#define eep_lb_r			0x0014		//0x0014,录波报告出处
#define eep_lb_d			0x0015		//0x0015,录波报告数据类型
#define eep_lb_u			0x0016		//0x0016,录波报告电压比例
#define eep_lb_i			0x0017		//0x0017,录波报告电流比例
#define eep_rpt_buf			0x0020		//0x0020--0x0fff//[MAX_REPORT_EEP=4064]

#define eep_rpt_inc(x)		{if((x)>=(MAX_REPORT_EEP/17-1))x=0;else x++;}
#define eep_rpt_dec(x)		{if((x)==0)x=(MAX_REPORT_EEP/17-1);else x--;}
#define value_inc(value,min,max) {if((value)<(max))value++;else value=min;}
#define value_dec(value,min,max) {if((value)>(min))value--;else value=max;}
void ram_ptr_inc(void);

byte trigger;			//100
word poll_timer;		//500
byte cycle_timer;		//3
byte trigger_t;			//100
word poll_timer_t;		//500
byte cycle_timer_t;		//3
byte trigger_f;
byte poll_timer_f;
byte clock_timer_f;
byte cycle_timer_f;

word wait_synch_timer;			//250,1700
word synch_timer;				//250,1700
word comm_timer;				//6000
word detect_timer;				//180
byte lamp_last_timer;			//200
byte key_timer;					//30
byte ATTENTION_timer;			//60
byte keep_timer;				//36,18
byte desk_pause;				//10

void disp_face(void);
void test_face(void);
//主程序调用了上电复位进程,键盘进程,事件进程;
void main(void)
{
	reset_routine();
	if(EEPROMread(eep_test)=='t')
		test_face();
	else
		disp_face();
	for(;;)
	{
		key_routine();
		event_routine();
	}
}
//MMI程序校验子程序
word chk_prg_sum(void)
{
	byte tmp;
	word sum,j;

	sum=0;				//sum=r16r17
	tmp=RAMPZ;
	asm("push R0");
	asm("mov R30,R16");	//sum=R16R17,z=sum
	asm("mov R31,R17");
	for(j=0x8000;j!=0;j--)//前64KROM
	{
	asm("lpm");			//r0=(z)
	asm("eor R16,R0");	//sum=sum^(j)
	asm("subi R30,255");//z=z+1
	asm("sbci R31,255");
	asm("lpm");			//r0=(z)
	asm("eor R17,R0");	//sum=sum^(j)
	asm("subi R30,255");//z=z+1
	asm("sbci R31,255");
	}
	RAMPZ=1;
	for(j=0x8000;j!=0;j--)//后64KROM
	{
	asm("elpm");		//r0=(z)
	asm("eor R16,R0");	//sum=sum^(j)
	asm("subi R30,255");//z=z+1
	asm("sbci R31,255");
	asm("elpm");		//r0=(z)
	asm("eor R17,R0");	//sum=sum^(j)
	asm("subi R30,255");//z=z+1
	asm("sbci R31,255");
	}
	asm("pop R0");//恢复R0
	RAMPZ=tmp;
	return sum;
}
//事件进程中包含了时钟进程,poll事件进程,trigger事件进程,网络处理事件进程
//报告滚屏显示进程;
void event_routine(void)
{
	{
		comm_with_lon();
		if(cycle_timer_f!=FALSE)		//每3s钟滚屏显示从MMI或cpu来的报告;
		{
			cycle_timer_f=FALSE;
			cycle_timer_routine();
		}
		if(clock_timer_f!=FALSE)		//1秒钟刷新一次时间
		{
			clock_timer_f=FALSE;
			clock_timer_routine();
		}
		if(poll_timer_f!=FALSE)		//500ms轮巡一次主cpu送上来的数据;
		if(poll_com!=1)
		{
			poll_timer_f=FALSE;
			poll_timer_routine();
		}
		if(trigger_f!=FALSE)			//100ms钟查循一次主cpu送上来的故障信息;
		{
			trigger_f=FALSE;
			trigger_routine();
		}
		if(nv_update!=FALSE)			//网络发来数据
		{
			nv_update=FALSE;
			nv_update_routine();
		}
	}
}
void init(void);
void init_disp(void);
void init_net(void);
void disp_time(byte);
void dlyms(word);
char *cstrcpy(char *dst,const char *src);
void memcpy_e(byte *d,byte *s,byte num);
void time_str_wr(char *tm_str);
void com_byte(char );
void application_restart(void);
void cls(void);
void disp_GPS(void);
void mediacy_hz(byte,byte*);
void str_hz(byte,byte,byte*);
void str_sasc(byte,byte,byte*);
void com_snd(byte *,word);
int csprintf(char *buf, const char *fmt,...);
void sscanf(char *,char *,unsigned short *);
void LCD_display(byte,byte);
void net_bgn(void);
void net_end(void);
byte net_read(void);
void net_handshake(void);
void net_write(byte);
const char* cstrchr(const char *str,char chr);
void cmemcpy(char *der,const char *ser,unsigned short len);
byte time_sec_rd(void);
extern word ms_val;
const byte *face_str;

//开始运行时的脸面
void disp_face(void)
{
	byte i;

	menu_in=TRUE;
rebgn:
	cstrcpy(disp_buffer,"欢迎您使用");
	cls();
	mediacy_hz(0,disp_buffer);
	if(face_str[0]&&face_str)
		cstrcpy(disp_buffer,face_str);
	else
		cstrcpy(disp_buffer,"四方装置汉化面板");
	mediacy_hz(24,disp_buffer);
	cstrcpy(disp_buffer,"装置:");
	cstrcpy(disp_buffer+strlen(disp_buffer),sbxh[EEPROMread(eep_sbxh)].AscCode);
	mediacy_hz(48,disp_buffer);
	key_timer=3;
	i=get_key();//按任意键退出
	cls();
	menu_in=FALSE;
	GPS_en=EEPROMread(eep_GPS);
	return;
}
/*面板的烤机测试
要求硬件作如下配合:连接+5V,+12V,+24V电源;UPTX与UPRX相连;TXD与RXD相连;
/RST-SIGNALS与/ATTENTION、DZ1、DZ2相连;/ALARM2与DZ3、DN1、DN2相连。*/
const CSTR err_str[]=
	{"net ","com ","txd ","rst ","dz1 ","dz2 ","dz3 ","dn1 ","dn2 ","att "};
void test_face(void)
{
	byte i;
	word tmp;
	word err_code,err_sum;
	word net_tm;

	if((time_str[5]==0)&&(time_str[4]==0x12)&&(time_str[3]<10))
	if(EEPROMread(eep_test)!='t')
		EEPROMwrite(eep_test,'t');
	PORTD&=~(RUN_LAMP|ALARM2);
	PORTD|=RST_SIGN;
	err_sum=0;
	net_tm=s_count;
	cls();
	i=0;
	for(;;)
	{
		if((time_str[5]==0)&&(time_str[4]==0x12)&&(time_str[3]<10))
		;
		else
		{
			EEPROMwrite(eep_test,0xff);
			application_restart();
		}
		Q_KEY[1]=0;
		CYCLE_FLAG=TRUE;
		key_routine();
		if(Q_KEY[1]==0xaa)
		{
			PORTD&=~(RUN_LAMP|ALARM2);
			PORTD|=RST_SIGN;
			key_timer=10;
			menu_in=TRUE;
			time_setting=TRUE;
			if(ts_hidden_code()!=FALSE)
			{
				EEPROMwrite(eep_test,0xff);
				application_restart();
			}
			cls();
			time_setting=FALSE;
			menu_in=FALSE;
			err_sum=0;
		}
		GPS_en=0;
		comm_with_lon();
		if(nv_update!=FALSE)
		{			//网络发来数据
			nv_update=FALSE;
			net_tm=s_count;
			if(nv_c.code==0x3f)
				err_code=err_sum=0;
			else
			if(nv_c.code==0x3d)
				nv_update_routine();
		}
		i++;
		if(clock_timer_f!=FALSE)		//1秒钟刷新一次时间
		{
			PORTD^=RUN_LAMP;
			cstrcpy(disp_buffer,"欢迎您测试");
			mediacy_hz(1*16,disp_buffer);
			if(face_str[0]&&face_str)
				cstrcpy(disp_buffer,face_str);
			else
				cstrcpy(disp_buffer,"四方装置汉化面板");
			mediacy_hz(2*16,disp_buffer);

			err_code=0;
			if((s_count-net_tm)>200)//网络通讯检测
				err_code|=0x0200;
			if(i==0xff)
				i=0;
			if((com_rcv(i)==0)||((i|CPU_ID)!=commu_buf[0]))//串口通讯检测
				err_code|=0x0100;
			PORTB^=TXD1;
			dlyms(5);
			if((!(PINB&RXD1))!=(!(PORTB&TXD1)))
				err_code|=0x080;
			PORTD^=RST_SIGN;
			dlyms(5);
			if((!(PINF&ATTN))!=(!(PORTD&RST_SIGN)))
				err_code|=0x040;
			if((!(PINF&RST_24))!=(!(PORTD&RST_SIGN)))
				err_code|=0x020;
			if((!(PIND&DZ1))!=(!(PORTD&RST_SIGN)))
				err_code|=0x010;
			if((!(PIND&DZ2))!=(!(PORTD&RST_SIGN)))
				err_code|=0x008;
			PORTD^=ALARM2;
			dlyms(5);
			if((!(PIND&DZ3))!=(!(PORTD&ALARM2)))
				err_code|=0x004;
			if((!(PIND&DN1))!=(!(PORTD&ALARM2)))
				err_code|=0x002;
			if((!(PIND&DN2))!=(!(PORTD&ALARM2)))
				err_code|=0x001;

			if(((EEPROMread(eep_node_id)&0xf0)>0x50)
			 ||((EEPROMread(eep_node_id)&0x0f)>0x09))
				EEPROMwrite(eep_node_id,time_str[0]);
			err_sum|=err_code;
			ctl_data^=LCD_LED;
			if(err_sum==0)
			{
				cstrcpy(disp_buffer,"本面板工作正常");
				mediacy_hz(3*16,disp_buffer);
				memset(disp_buffer,' ',40);
				disp_buffer[40]=0;
				str_sasc(4*16,0,disp_buffer);
			}
			else
			{
				cstrcpy(disp_buffer,"本面板有错误:");
				mediacy_hz(3*16,disp_buffer);
				disp_buffer[0]=0;
				tmp=err_sum;
				for(i=0;i<10;i++)
				{
					if(tmp&0x0200)
					{
						cstrcpy(disp_buffer1,err_str[i].str);
						strcat(disp_buffer,disp_buffer1);
					}
					tmp<<=1;
				}
				memset(disp_buffer1,' ',40);
				disp_buffer1[40]=0;
				strcat(disp_buffer,disp_buffer1);
				disp_buffer[40]=0;
				str_sasc(4*16,0,disp_buffer);
			}
			clock_timer_f=FALSE;
			clock_timer_routine();
			if(time_str[0]==EEPROMread(eep_node_id))
			if((time_str[1]^EEPROMread(eep_node_id))&1)
			{
				NV_ram_buf[0]=0x09;
				NV_ram_buf[1]=0x0f;
				NV_ram_buf[2]=EEPROMread(eep_node_id);
				NV_ram_buf[3]=0x30;
				NV_ram_buf[4]=0x07;
				NV_ram_buf[5]=0x01;
				NV_ram_buf[6]=err_code;
				NV_ram_buf[7]=err_code/256;
				NV_ram_buf[8]=err_sum;
				NV_ram_buf[9]=err_sum/256;
				net_out(1);
			}
			else
			{
				NV_ram_buf[0]=0x0a;
				NV_ram_buf[1]=0x0f;
				NV_ram_buf[2]=EEPROMread(eep_node_id);
				NV_ram_buf[3]=0x30;
				NV_ram_buf[4]=0x07;
				NV_ram_buf[5]=0x01;
				NV_ram_buf[6]=err_code;
				NV_ram_buf[7]=err_code/256;
				NV_ram_buf[8]=err_sum;
				NV_ram_buf[9]=err_sum/256;
				NV_ram_buf[10]=0xff;
				net_out(2);
			}
		}
	}
	return;
}
//初始化进程,完成液晶,网络的初始化,修正eeprom中不合理的数值
void reset_routine(void)
{
	byte i;

	init();				//对控制输出口的初始化;
	PORTD&=~RUN_LAMP;
	ctl_data|=LCD_LED;
	menu_in=TRUE;
	init_disp();		//对液晶显示的初始化;
	menu_in=FALSE;
	init_net();			//对网络的初始化

	bgnpoint=0;
	endpoint=0;
	time_setting=FALSE;
	ATTENTION=FALSE;
	PT_RST=CYCLE_FLAG=FALSE;
	S_EEP=0;
	rpt_ram_clr();
	poll_timer=POLL_PERIOD;
	cycle_timer=CYCLE_PERIOD;
	cpu_set_flag=FALSE;
	trigger=100;
	GPS_en=0;

	if(EEPROMread(eep_GPS)>2)
		EEPROMwrite(eep_GPS,2);

	for(i=0;i<TOTAL_SB_NUMBER;i++)
		if(sbxh[i].AscCode==0)
			break;
	if(EEPROMread(eep_sbxh)>=i)
		EEPROMwrite(eep_sbxh,0);

⌨️ 快捷键说明

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