📄 ledmenu_icc.lst
字号:
__start:
__text_start:
2EC E5CF LDI R28,0x5F
2ED E0D4 LDI R29,4
2EE BFCD OUT 0x3D,R28
2EF BFDE OUT 0x3E,R29
2F0 51CE SUBI R28,0x1E
2F1 40D0 SBCI R29,0
2F2 EA0A LDI R16,0xAA
2F3 8308 STD Y+0,R16
2F4 2400 CLR R0
2F5 E6E9 LDI R30,0x69
2F6 E0F0 LDI R31,0
2F7 E010 LDI R17,0
2F8 3BE3 CPI R30,0xB3
2F9 07F1 CPC R31,R17
2FA F011 BEQ 0x02FD
2FB 9201 ST R0,Z+
2FC CFFB RJMP 0x02F8
2FD 8300 STD Z+0,R16
2FE ECEE LDI R30,0xCE
2FF E0F5 LDI R31,5
300 E6A0 LDI R26,0x60
301 E0B0 LDI R27,0
302 E015 LDI R17,5
303 E000 LDI R16,0
304 BF0B OUT 0x3B,R16
305 3DE7 CPI R30,0xD7
306 07F1 CPC R31,R17
307 F021 BEQ 0x030C
308 95C8 LPM
309 9631 ADIW R30,1
30A 920D ST R0,X+
30B CFF9 RJMP 0x0305
30C 940E 0682 CALL _main
_exit:
30E CFFF RJMP _exit
FILE: F:\diy\LedMenu\delay.h
(0001) //延时函数.
(0002) //*****************************************************************************************************************
(0003) //***********************************************延时子程序********************************************************
(0004) //************************************** N-us延时,最小3us,最大65.6MS ********************************************
(0005)
(0006) //适用机型 :用于AVR系列单片机延时处理,7.3728MHZ晶振下
(0007) //变量定义类型:unsigned int
(0008) //最小延时时间:即N=0时为3us;
(0009) //增量: 1us
(0010) //最大延时时间:3us+(65535*1us)=65538us
(0011) //例如: i=0为3us;i=1为4us;i=2为5us..........................
(0012)
(0013) //延时间间=3us+N
(0014) void delay_3_us(uint n) //N us延时函数
(0015) {
(0016) for(;n>0;n--) //延时基数为3us加上 n
_delay_3_us:
n --> R16
30F C004 RJMP 0x0314
(0017) {
(0018) asm("nop");
310 0000 NOP
(0019) asm("nop");
311 0000 NOP
312 5001 SUBI R16,1
313 4010 SBCI R17,0
314 3000 CPI R16,0
315 0701 CPC R16,R17
316 F7C9 BNE 0x0310
317 9508 RET
_delay_ms:
n --> R20
m --> R16
318 934A ST R20,-Y
319 935A ST R21,-Y
(0020) }
(0021) }
(0022) //注意:n为uint
(0023) //*****************************************************************************************************************
(0024)
(0025) //****************************************** n-ms延时,最小1ms,最大65.5s *****************************************
(0026) //适用机型 :用于AVR系列单片机延时处理,7.3728MHZ晶振下
(0027) //变量定义类型:unsigned int
(0028) //最小延时时间:即m=1时为1ms; m不能为0,否则延时时间增长不成比例(注意:m=0时,延时=6.24us的区别)
(0029)
(0030) //增量: 1ms
(0031) //最大延时时间:65535*1ms=65.535s
(0032) //例如: m=1/1ms;m=2/2ms..........................
(0033) //延时间间=m*1ms
(0034) void delay_ms (unsigned int m) //Nms延时
(0035) {
(0036) uint n;
(0037) extern uchar kk;
(0038) for(;m>0;m--)
31A C00A RJMP 0x0325
(0039) for(n=1229;n>0;n--)
31B EC4D LDI R20,0xCD
31C E054 LDI R21,4
31D C002 RJMP 0x0320
31E 5041 SUBI R20,1
31F 4050 SBCI R21,0
320 3040 CPI R20,0
321 0745 CPC R20,R21
322 F7D9 BNE 0x031E
323 5001 SUBI R16,1
324 4010 SBCI R17,0
325 3000 CPI R16,0
326 0701 CPC R16,R17
327 F799 BNE 0x031B
328 9159 LD R21,Y+
329 9149 LD R20,Y+
32A 9508 RET
FILE: F:\diy\LedMenu\lcd_12864.h
(0001) //lcd头文件.
(0002)
(0003) #define L_on PORTB&=~(1<<PORTB0)
(0004) #define L_off PORTB|=(1<<PORTB0)
(0005) #define R_on PORTB&=~(1<<PORTB1)
(0006) #define R_off PORTB|=(1<<PORTB1)
(0007) #define Selcom PORTB&=~(1<<PORTB2)
(0008) #define Seldata PORTB|=(1<<PORTB2)
(0009) #define Rw_w PORTB&=~(1<<PORTB3)
(0010) #define Rw_r PORTB|=(1<<PORTB3)
(0011) #define E_on PORTB|=(1<<PORTB4)
(0012) #define E_off PORTB&=~(1<<PORTB4)
(0013)
(0014) #define iodata PORTA
(0015)
(0016) #define status_busy 0x80; //忙状态.
(0017) #define disp_start_set 0xc0 //显示起始行设置.
(0018) #define page_addr_set 0xb8 //页面地址设置.
(0019) #define col_addr_set 0x40 //列地址设置.
(0020) #define disp_on 0x3f //打开显示.
(0021)
(0022) /********************分别为读忙信号写指令写数据.******************************************/
(0023) void chkbusy(void) //检查忙信号.等待LCD内部操作完成.
(0024) {
(0025) // iodata=0xff; //因为要读状态,所以先使IO口输出高电平.
(0026) E_on;
_chkbusy:
32B 9AC4 SBI 0x18,4
(0027) Selcom;
32C 98C2 CBI 0x18,2
(0028) Rw_r;
32D 9AC3 SBI 0x18,3
32E 9508 RET
_send_comm:
command --> R10
32F 92AA ST R10,-Y
330 2EA0 MOV R10,R16
(0029) // while(iodata&status_busy);//读入LCD状态,1=忙,一直等LCD内部操作完成.
(0030) }
(0031)
(0032) void send_comm(uchar command) //左右屏在调用函数中处理.
(0033) {
(0034) chkbusy();
331 DFF9 RCALL _chkbusy
(0035) E_on; //使能LCD
332 9AC4 SBI 0x18,4
(0036) Selcom;
333 98C2 CBI 0x18,2
(0037) Rw_w;
334 98C3 CBI 0x18,3
(0038) iodata=command; //发送命令到数据总线.
335 BAAB OUT 0x1B,R10
(0039) E_on;
336 9AC4 SBI 0x18,4
(0040) E_off; //发送完,关闭使能.
337 98C4 CBI 0x18,4
338 90A9 LD R10,Y+
339 9508 RET
_send_data:
dat --> R10
33A 92AA ST R10,-Y
33B 2EA0 MOV R10,R16
(0041) }
(0042)
(0043) void send_data(uchar dat)
(0044) {
(0045) chkbusy();
33C DFEE RCALL _chkbusy
(0046) E_on;
33D 9AC4 SBI 0x18,4
(0047) Seldata;
33E 9AC2 SBI 0x18,2
(0048) Rw_w;
33F 98C3 CBI 0x18,3
(0049) iodata=dat; //发送数据到数据总线.
340 BAAB OUT 0x1B,R10
(0050) E_off;
341 98C4 CBI 0x18,4
342 90A9 LD R10,Y+
343 9508 RET
(0051) }
(0052)
(0053) /********************LCD初始化******************************************/
(0054) void lcd_init(void) //LCD初始化.
(0055) {
(0056) send_comm(disp_start_set); //设置显示起始行为第一行.
_lcd_init:
344 EC00 LDI R16,0xC0
345 DFE9 RCALL _send_comm
(0057) send_comm(page_addr_set); //页地址设为0
346 EB08 LDI R16,0xB8
347 DFE7 RCALL _send_comm
(0058) send_comm(col_addr_set); //列地址设为0
348 E400 LDI R16,0x40
349 DFE5 RCALL _send_comm
(0059) send_comm(disp_on); //打开显示.
34A E30F LDI R16,0x3F
34B DFE3 RCALL _send_comm
34C 9508 RET
_lcd_clr:
page --> R20
col --> R22
34D 934A ST R20,-Y
34E 936A ST R22,-Y
(0060) }
(0061)
(0062) /********************LCD清屏******************************************/
(0063) void lcd_clr(void) //LCD清屏.
(0064) {
(0065) uchar page,col;
(0066) L_off; //对右边控制器操作.
34F 9AC0 SBI 0x18,0
(0067) R_on;
350 98C1 CBI 0x18,1
(0068) for (page=0;page<8;page++)
351 2744 CLR R20
352 C00D RJMP 0x0360
(0069) {
(0070) send_comm(page_addr_set | page);
353 2F04 MOV R16,R20
354 6B08 ORI R16,0xB8
355 DFD9 RCALL _send_comm
(0071) send_comm(col_addr_set);
356 E400 LDI R16,0x40
357 DFD7 RCALL _send_comm
(0072) for (col=0;col<64;col++)
358 2766 CLR R22
359 C003 RJMP 0x035D
(0073) {
(0074) send_data(0x00); //列地址自动加一.
35A 2700 CLR R16
35B DFDE RCALL _send_data
35C 9563 INC R22
35D 3460 CPI R22,0x40
35E F3D8 BCS 0x035A
35F 9543 INC R20
360 3048 CPI R20,0x8
361 F388 BCS 0x0353
(0075) }
(0076) }
(0077)
(0078) L_on;
362 98C0 CBI 0x18,0
(0079) R_off; //对左边控制器进行操作
363 9AC1 SBI 0x18,1
(0080) for (page=0;page<8;page++)
364 2744 CLR R20
365 C00D RJMP 0x0373
(0081) {
(0082) send_comm(page_addr_set | page);
366 2F04 MOV R16,R20
367 6B08 ORI R16,0xB8
368 DFC6 RCALL _send_comm
(0083) send_comm(col_addr_set);
369 E400 LDI R16,0x40
36A DFC4 RCALL _send_comm
(0084) for (col=0;col<64;col++)
36B 2766 CLR R22
36C C003 RJMP 0x0370
(0085) {
(0086) send_data(0x00); //列地址自动加一.
36D 2700 CLR R16
36E DFCB RCALL _send_data
36F 9563 INC R22
370 3460 CPI R22,0x40
371 F3D8 BCS 0x036D
372 9543 INC R20
373 3048 CPI R20,0x8
374 F388 BCS 0x0366
375 9169 LD R22,Y+
376 9149 LD R20,Y+
377 9508 RET
_draw_bmp:
address --> R20
p --> R12
window --> R22
x --> R10
bmp --> R14
mod --> Y,+16
width --> Y,+14
col --> Y,+12
page --> Y,+10
378 940E 06BC CALL push_arg4
37A 940E 06E4 CALL push_xgsetF0FC
37C 88EA LDD R14,Y+18
37D 88FB LDD R15,Y+19
(0087) }
(0088) }
(0089) }
(0090)
(0091)
(0092) /********************************************************************************
(0093) 画一个图.页地址是page,列地址是col,图形宽度为width,高固定为16,bmp是图形指针.
(0094) 是否反向标志为mod,mod=0为正常,mod=1表示需要反向显示,一般用在菜单上.取模方式为字节倒序.
(0095) ********************************************************************************/
(0096) void draw_bmp(uchar page,uchar col,uchar width,uchar mod,const uchar *bmp)
(0097) {
(0098) uchar x,address;
(0099) uchar window=0;
37E 2766 CLR R22
(0100) uchar p=0; //p表示宽度的索引,即它的值为0到width之间.
37F 24CC CLR R12
(0101)
(0102) for(x=col;x<col+width;x++) //列地址自动加一,但对于x,一个循环后必须加一才能与列地址保持同步.
380 84AC LDD R10,Y+12
381 C057 RJMP 0x03D9
(0103) {
(0104) //每一个循环显示同一列的两个字节(连续两页).
(0105) if (x>127) return; //若列坐标大于127,则为无效数据,硬返回,防止显示乱码.
382 E78F LDI R24,0x7F
383 158A CP R24,R10
384 F408 BCC 0x0386
385 C059 RJMP 0x03DF
(0106) if (x>63) //若列地址大于63,则表示要显示在右半区.
386 E38F LDI R24,0x3F
387 158A CP R24,R10
388 F438 BCC 0x0390
(0107) {
(0108) window=1; //表示在右窗口显示.
389 E061 LDI R22,1
(0109) address=x%64;
38A E410 LDI R17,0x40
38B 2D0A MOV R16,R10
38C 940E 06C1 CALL mod8u
38E 2F40 MOV R20,R16
(0110) }
38F C002 RJMP 0x0392
(0111) else
(0112) {
(0113) window=0; //左窗口显示.
390 2766 CLR R22
(0114) address=x;
391 2D4A MOV R20,R10
(0115) }
(0116)
(0117) if(window) //发送是在左屏还是右屏.
392 2366 TST R22
393 F019 BEQ 0x0397
(0118) {
(0119) L_on;
394 98C0 CBI 0x18,0
(0120) R_off;
395 9AC1 SBI 0x18,1
(0121) }
396 C002 RJMP 0x0399
(0122)
(0123) else
(0124) {
(0125) L_off;
397 9AC0 SBI 0x18,0
(0126) R_on;
398 98C1 CBI 0x18,1
(0127) }
(0128) send_comm(page_addr_set | page); //发送页面地址.
399 850A LDD R16,Y+10
39A 6B08 ORI R16,0xB8
39B DF93 RCALL _send_comm
(0129) send_comm(col_addr_set | address); //发送列地址.
39C 2F04 MOV R16,R20
39D 6400 ORI R16,0x40
39E DF90 RCALL _send_comm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -