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

📄 menu.s

📁 做点阵式lcd多级菜单开发的一个例子 可以帮助初学者了解 交互式界面简单设计的部分
💻 S
📖 第 1 页 / 共 4 页
字号:
	.byte 15,31
	.byte 31,4
	.byte 2,1
	.byte 0,0
	.byte 0,0
	.dbsym e curflag _curflag A[32:32]kc
	.area data(ram, con, rel)
	.dbfile F:\diy\LedMenu\menu.h
_menu_led::
	.blkw 1
	.area idata
	.word _main_menu
	.area data(ram, con, rel)
	.dbfile F:\diy\LedMenu\menu.h
	.dbstruct 0 9 menu_item
	.dbfield 0 menu_count c
	.dbfield 1 display pkc
	.dbfield 3 subs pfV
	.dbfield 5 children_menus pS[menu_item]
	.dbfield 7 parent_menus pS[menu_item]
	.dbend
	.dbsym e menu_led _menu_led pS[menu_item]
_user_choosen::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile F:\diy\LedMenu\menu.h
	.dbsym e user_choosen _user_choosen c
_max_item::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile F:\diy\LedMenu\menu.h
	.dbsym e max_item _max_item c
_refresh::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile F:\diy\LedMenu\menu.h
	.dbsym e refresh _refresh c
_keyval::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile F:\diy\LedMenu\menu.h
	.dbsym e keyval _keyval c
	.area text(rom, con, rel)
	.dbfile F:\diy\LedMenu\menu.h
	.dbfile F:\diy\LedMenu\delay.h
	.dbfunc e delay_3_us _delay_3_us fV
;              n -> R16,R17
	.even
_delay_3_us::
	.dbline -1
	.dbline 15
; //延时函数.
; //*****************************************************************************************************************
; //***********************************************延时子程序********************************************************
; //************************************** N-us延时,最小3us,最大65.6MS  ********************************************
; 
; //适用机型    :用于AVR系列单片机延时处理,7.3728MHZ晶振下
; //变量定义类型:unsigned int
; //最小延时时间:即N=0时为3us;  
; //增量:		  1us
; //最大延时时间:3us+(65535*1us)=65538us
; //例如:	i=0为3us;i=1为4us;i=2为5us..........................
; 
; //延时间间=3us+N
; void delay_3_us(uint n)       //N us延时函数
; {
	.dbline 16
; 	for(;n>0;n--)					//延时基数为3us加上 n
	xjmp L5
L2:
	.dbline 17
; 	{
	.dbline 18
; 		asm("nop");
	nop
	.dbline 19
; 		asm("nop");
	nop
	.dbline 20
; 	}											
L3:
	.dbline 16
	subi R16,1
	sbci R17,0
L5:
	.dbline 16
	cpi R16,0
	cpc R16,R17
	brne L2
X0:
	.dbline -2
L1:
	.dbline 0 ; func end
	ret
	.dbsym r n 16 i
	.dbend
	.dbfunc e delay_ms _delay_ms fV
;              n -> R20,R21
;              m -> R16,R17
	.even
_delay_ms::
	st -y,R20
	st -y,R21
	.dbline -1
	.dbline 35
; }
; //注意:n为uint
; //*****************************************************************************************************************
; 
; //****************************************** n-ms延时,最小1ms,最大65.5s  *****************************************
; //适用机型    :用于AVR系列单片机延时处理,7.3728MHZ晶振下
; //变量定义类型:unsigned int
; //最小延时时间:即m=1时为1ms;  m不能为0,否则延时时间增长不成比例(注意:m=0时,延时=6.24us的区别)
; 
; //增量:		1ms
; //最大延时时间:65535*1ms=65.535s
; //例如:	m=1/1ms;m=2/2ms..........................
; //延时间间=m*1ms 
; void delay_ms (unsigned int m)						//Nms延时
; {
	.dbline 38
; 	uint n;
; 	extern uchar kk;
; 	for(;m>0;m--)
	xjmp L10
L7:
	.dbline 39
; 		for(n=1229;n>0;n--)
	ldi R20,1229
	ldi R21,4
	xjmp L14
L11:
	.dbline 40
; 		{
	.dbline 41
; 			;
	.dbline 42
; 		}
L12:
	.dbline 39
	subi R20,1
	sbci R21,0
L14:
	.dbline 39
	cpi R20,0
	cpc R20,R21
	brne L11
X1:
L8:
	.dbline 38
	subi R16,1
	sbci R17,0
L10:
	.dbline 38
	cpi R16,0
	cpc R16,R17
	brne L7
X2:
	.dbline -2
L6:
	.dbline 0 ; func end
	ld R21,y+
	ld R20,y+
	ret
	.dbsym r n 20 i
	.dbsym r m 16 i
	.dbend
	.dbfile F:\diy\LedMenu\lcd_12864.h
	.dbfunc e chkbusy _chkbusy fV
	.even
_chkbusy::
	.dbline -1
	.dbline 24
; //lcd头文件.
; 
; #define L_on PORTB&=~(1<<PORTB0)
; #define L_off PORTB|=(1<<PORTB0)
; #define R_on PORTB&=~(1<<PORTB1)
; #define R_off PORTB|=(1<<PORTB1)
; #define Selcom PORTB&=~(1<<PORTB2)
; #define Seldata PORTB|=(1<<PORTB2)
; #define Rw_w PORTB&=~(1<<PORTB3)
; #define Rw_r PORTB|=(1<<PORTB3)
; #define E_on PORTB|=(1<<PORTB4)
; #define E_off PORTB&=~(1<<PORTB4)
; 
; #define iodata PORTA
; 
; #define status_busy 0x80;	//忙状态.
; #define disp_start_set 0xc0	//显示起始行设置.
; #define page_addr_set 0xb8	//页面地址设置.
; #define col_addr_set 0x40	//列地址设置.
; #define disp_on 0x3f		//打开显示.
; 
; /********************分别为读忙信号写指令写数据.******************************************/
; void chkbusy(void)		//检查忙信号.等待LCD内部操作完成.
; {
	.dbline 26
; //	iodata=0xff;		//因为要读状态,所以先使IO口输出高电平.	
; 	E_on;
	sbi 0x18,4
	.dbline 27
; 	Selcom;
	cbi 0x18,2
	.dbline 28
; 	Rw_r;
	sbi 0x18,3
	.dbline -2
L15:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e send_comm _send_comm fV
;        command -> R10
	.even
_send_comm::
	st -y,R10
	mov R10,R16
	.dbline -1
	.dbline 33
; //	while(iodata&status_busy);//读入LCD状态,1=忙,一直等LCD内部操作完成.
; }
; 
; void send_comm(uchar command)	//左右屏在调用函数中处理.
; {
	.dbline 34
; 	chkbusy();
	xcall _chkbusy
	.dbline 35
; 	E_on;	  					//使能LCD
	sbi 0x18,4
	.dbline 36
; 	Selcom;
	cbi 0x18,2
	.dbline 37
; 	Rw_w;
	cbi 0x18,3
	.dbline 38
; 	iodata=command;				//发送命令到数据总线.
	out 0x1b,R10
	.dbline 39
; 	E_on;
	sbi 0x18,4
	.dbline 40
; 	E_off;						//发送完,关闭使能.
	cbi 0x18,4
	.dbline -2
L16:
	.dbline 0 ; func end
	ld R10,y+
	ret
	.dbsym r command 10 c
	.dbend
	.dbfunc e send_data _send_data fV
;            dat -> R10
	.even
_send_data::
	st -y,R10
	mov R10,R16
	.dbline -1
	.dbline 44
; }
; 
; void send_data(uchar dat)
; {
	.dbline 45
; 	chkbusy();
	xcall _chkbusy
	.dbline 46
; 	E_on;
	sbi 0x18,4
	.dbline 47
; 	Seldata;
	sbi 0x18,2
	.dbline 48
; 	Rw_w;
	cbi 0x18,3
	.dbline 49
; 	iodata=dat;					//发送数据到数据总线.
	out 0x1b,R10
	.dbline 50
; 	E_off;
	cbi 0x18,4
	.dbline -2
L17:
	.dbline 0 ; func end
	ld R10,y+
	ret
	.dbsym r dat 10 c
	.dbend
	.dbfunc e lcd_init _lcd_init fV
	.even
_lcd_init::
	.dbline -1
	.dbline 55
; }
; 
; /********************LCD初始化******************************************/
; void lcd_init(void)				//LCD初始化.
; {
	.dbline 56
; 	send_comm(disp_start_set);	//设置显示起始行为第一行.
	ldi R16,192
	xcall _send_comm
	.dbline 57
; 	send_comm(page_addr_set);	//页地址设为0
	ldi R16,184
	xcall _send_comm
	.dbline 58
; 	send_comm(col_addr_set);  	//列地址设为0
	ldi R16,64
	xcall _send_comm
	.dbline 59
; 	send_comm(disp_on);			//打开显示.
	ldi R16,63
	xcall _send_comm
	.dbline -2
L18:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e lcd_clr _lcd_clr fV
;           page -> R20
;            col -> R22
	.even
_lcd_clr::
	st -y,R20
	st -y,R22
	.dbline -1
	.dbline 64
; }
; 
; /********************LCD清屏******************************************/
; void lcd_clr(void)				//LCD清屏.
; {
	.dbline 66
; 	uchar page,col;
; 	L_off;						//对右边控制器操作.
	sbi 0x18,0
	.dbline 67
; 	R_on;
	cbi 0x18,1
	.dbline 68
; 	for (page=0;page<8;page++)
	clr R20
	xjmp L23
L20:
	.dbline 69
; 	{
	.dbline 70
; 		send_comm(page_addr_set | page);
	mov R16,R20
	ori R16,184
	xcall _send_comm
	.dbline 71
; 		send_comm(col_addr_set);
	ldi R16,64
	xcall _send_comm
	.dbline 72
; 		for (col=0;col<64;col++)
	clr R22
	xjmp L27
L24:
	.dbline 73
; 		{
	.dbline 74
; 			send_data(0x00);	//列地址自动加一.
	clr R16
	xcall _send_data
	.dbline 75
; 		}
L25:
	.dbline 72
	inc R22
L27:
	.dbline 72
	cpi R22,64
	brlo L24
X3:
	.dbline 76
; 	}
L21:
	.dbline 68
	inc R20
L23:
	.dbline 68
	cpi R20,8
	brlo L20
X4:
	.dbline 78
; 
; 	L_on;
	cbi 0x18,0
	.dbline 79
; 	R_off;						//对左边控制器进行操作
	sbi 0x18,1
	.dbline 80
; 	for (page=0;page<8;page++)
	clr R20
	xjmp L31
L28:
	.dbline 81
; 	{
	.dbline 82
; 		send_comm(page_addr_set | page);
	mov R16,R20
	ori R16,184
	xcall _send_comm
	.dbline 83
; 		send_comm(col_addr_set);
	ldi R16,64
	xcall _send_comm
	.dbline 84
; 		for (col=0;col<64;col++)
	clr R22
	xjmp L35
L32:
	.dbline 85
; 		{
	.dbline 86
; 			send_data(0x00);	//列地址自动加一.
	clr R16
	xcall _send_data
	.dbline 87
; 		}
L33:
	.dbline 84
	inc R22
L35:
	.dbline 84
	cpi R22,64
	brlo L32
X5:
	.dbline 88
; 	}	 
L29:
	.dbline 80
	inc R20
L31:
	.dbline 80
	cpi R20,8
	brlo L28
X6:
	.dbline -2
L19:
	.dbline 0 ; func end
	ld R22,y+
	ld R20,y+
	ret
	.dbsym r page 20 c
	.dbsym r col 22 c
	.dbend
	.dbfunc e draw_bmp _draw_bmp fV
;        address -> R20
;              p -> R12
;         window -> R22
;              x -> R10
;            bmp -> R14,R15
;            mod -> y+16
;          width -> y+14
;            col -> y+12
;           page -> y+10
	.even
_draw_bmp::
	xcall push_arg4
	xcall push_xgsetF0FC
	ldd R14,y+18
	ldd R15,y+19
	.dbline -1
	.dbline 97
; }
; 
; 
; /********************************************************************************
; 画一个图.页地址是page,列地址是col,图形宽度为width,高固定为16,bmp是图形指针.
; 是否反向标志为mod,mod=0为正常,mod=1表示需要反向显示,一般用在菜单上.取模方式为字节倒序.
; ********************************************************************************/
; void draw_bmp(uchar page,uchar col,uchar width,uchar mod,const uchar *bmp)
; {
	.dbline 99
; 	uchar x,address;
; 	uchar window=0;
	clr R22
	.dbline 100
; 	uchar p=0;			//p表示宽度的索引,即它的值为0到width之间.
	clr R12
	.dbline 102
; 
; 	for(x=col;x<col+width;x++)	//列地址自动加一,但对于x,一个循环后必须加一才能与列地址保持同步.
	ldd R10,y+12
	xjmp L40
L37:
	.dbline 103
; 	{
	.dbline 105
; 						//每一个循环显示同一列的两个字节(连续两页).
; 		if (x>127) return;		//若列坐标大于127,则为无效数据,硬返回,防止显示乱码.
	ldi R24,127
	cp R24,R10
	brsh L41
X7:
	.dbline 105
	xjmp L36
L41:
	.dbline 106
; 		if (x>63)				//若列地址大于63,则表示要显示在右半区.
	ldi R24,63
	cp R24,R10
	brsh L43
X8:
	.dbline 107
; 		{
	.dbline 108
; 			window=1;			//表示在右窗口显示.
	ldi R22,1
	.dbline 109
; 			address=x%64;
	ldi R17,64
	mov R16,R10
	xcall mod8u
	mov R20,R16
	.dbline 110
; 		}
	xjmp L44
L43:
	.dbline 112
; 		else					
; 		{
	.dbline 113
; 			window=0;			//左窗口显示.
	clr R22
	.dbline 114
; 			address=x;
	mov R20,R10
	.dbline 115
; 		}
L44:
	.dbline 117
; 
; 		if(window)		  		//发送是在左屏还是右屏.
	tst R22
	breq L45
X9:
	.dbline 118
; 		{
	.dbline 119
; 			L_on;
	cbi 0x18,0
	.dbline 120
; 			R_off;			
	sbi 0x18,1
	.dbline 121
; 		}
	xjmp L46
L45:
	.dbline 124
; 
; 		else
; 		{
	.dbline 125
; 			L_off;
	sbi 0x18,0
	.dbline 126
; 			R_on;
	cbi 0x18,1
	.dbline 127
; 		}
L46:
	.dbline 128
; 		send_comm(page_addr_set | page);   		//发送页面地址.
	ldd R16,y+10
	ori R16,184
	xcall _send_comm
	.dbline 129
; 		send_comm(col_addr_set | address);		//发送列地址.
	mov R16,R20
	ori R16,64
	xcall _send_comm
	.dbline 131
; 
; 		if (mod) send_data(~bmp[p]);
	ldd R0,y+16
	tst R0
	breq L47
X10:
	.dbline 131
	mov R30,R12
	clr R31
	add R30,R14
	adc R31,R15
	lpm R16,Z
	com R16
	xcall _send_data
	xjmp L48
L47:
	.dbline 132
; 		else send_data(bmp[p]);						//发送数据.
	mov R30,R12
	clr R31
	add R30,R14
	adc R31,R15
	lpm R16,Z
	xcall _send_data
L48:
	.dbline 134
; 
; 		if(window)
	tst R22
	breq L49
X11:
	.dbline 135
; 		{
	.dbline 136
; 			L_on;
	cbi 0x18,0
	.dbline 137
; 			R_off;
	sbi 0x18,1
	.dbline 138
; 		}
	xjmp L50
L49:
	.dbline 141
; 
; 		else
; 		{
	.dbline 142
; 			L_off;
	sbi 0x18,0
	.dbline 143
; 			R_on;
	cbi 0x18,1
	.dbline 144
; 		}
L50:
	.dbline 146
; 
; 		send_comm((page_addr_set | page)+1);	//页地址加一.
	ldd R16,y+10
	ori R16,184
	subi R16,255    ; addi 1
	xcall _send_comm
	.dbline 147
; 		send_comm(col_addr_set | address);		//列地址不变.
	mov R16,R20
	ori R16,64
	xcall _send_comm
	.dbline 149
; 
; 		if (mod) send_data(~bmp[p+width]);
	ldd R0,y+16
	tst R0
	breq L51
X12:
	.dbline 149
	ldd R2,y+14
	clr R3
	mov R30,R12
	clr R31
	add R30,R2
	adc R31,R3
	add R30,R14
	adc R31,R15
	lpm R16,Z
	com R16
	xcall _send_data
	xjmp L52
L51:
	.dbline 150
; 		else send_data(bmp[p+width]);				//第二排数据.
	ldd R2,y+14
	clr R3
	mov R30,R12
	clr R31
	add R30,R2
	adc R31,R3
	add R30,R14
	adc R31,R15
	lpm R16,Z
	xcall _send_data
L52:
	.dbline 152
; 
; 		p++;
	inc R12
	.dbline 153
; 	}
L38:
	.dbline 102
	inc R10
L40:
	.dbline 102
	ldd R2,y+12
	ldd R0,y+14
	add R2,R0
	cp R10,R2
	brsh X14
	xjmp L37
X14:
X13:
	.dbline -2
L36:
	.dbline 0 ; func end
	xcall pop_xgsetF0FC
	adiw R28,4
	ret
	.dbsym r address 20 c
	.dbsym r p 12 c
	.dbsym r window 22 c

⌨️ 快捷键说明

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