📄 lcd1602.s
字号:
.module LCD1602.c
.area text(rom, con, rel)
.dbfile C:\DOCUME~1\Administrator\桌面\1602\LCD1602.c
.dbfunc e lcd_init_portDB _lcd_init_portDB fV
.even
_lcd_init_portDB::
.dbline -1
.dbline 15
; #include <iom8v.h>
; #include <macros.h>
; #include "LCD1602.h"
; /**********************************************************
; 光标命令
; lcd_write_command(0x0e,0);//光标开
; lcd_write_command(0x0d,0);//光标所在字符闪烁
; lcd_write_command(0x0c,0); //光标关
; lcd_write_command(0x07,0); //屏幕左移
;
; **********************************************************/
;
; /*------------------------------------液晶驱动函数-------------------------------------*/
; void lcd_init_portDB(void)
; {
.dbline 16
; lcd_data_port=0xff;
ldi R24,255
out 0x18,R24
.dbline 17
; lcd_data_ddr=0xff;
out 0x17,R24
.dbline 18
; lcd_control_port=0x07;
ldi R24,7
out 0x15,R24
.dbline 19
; lcd_control_ddr=0x07;
out 0x14,R24
.dbline -2
L1:
.dbline 0 ; func end
ret
.dbend
.dbfunc e lcd_init _lcd_init fV
.even
_lcd_init::
.dbline -1
.dbline 24
; }
;
; //液晶初始化
; void lcd_init(void)
; {
.dbline 25
; delay_nms(15);
ldi R16,15
ldi R17,0
rcall _delay_nms
.dbline 26
; lcd_write_command(0x38,0);//显示模式设置三次(此时不管lcd空闲与否)
clr R18
ldi R16,56
rcall _lcd_write_command
.dbline 27
; delay_nms(5);
ldi R16,5
ldi R17,0
rcall _delay_nms
.dbline 28
; lcd_write_command(0x38,0);
clr R18
ldi R16,56
rcall _lcd_write_command
.dbline 29
; delay_nms(5);
ldi R16,5
ldi R17,0
rcall _delay_nms
.dbline 30
; lcd_write_command(0x38,0);
clr R18
ldi R16,56
rcall _lcd_write_command
.dbline 31
; delay_nms(5);
ldi R16,5
ldi R17,0
rcall _delay_nms
.dbline 33
;
; lcd_write_command(0x38,1);//显示模式设置(从此之后均需lcd空闲)
ldi R18,1
ldi R16,56
rcall _lcd_write_command
.dbline 34
; lcd_write_command(0x08,1);//显示关闭
ldi R18,1
ldi R16,8
rcall _lcd_write_command
.dbline 35
; lcd_write_command(0x01,1);//显示清屏
ldi R18,1
ldi R16,1
rcall _lcd_write_command
.dbline 36
; lcd_write_command(0x06,1);//显示光标移动设置
ldi R18,1
ldi R16,6
rcall _lcd_write_command
.dbline 37
; lcd_write_command(0x0c,1);//显示开及光标设置
ldi R18,1
ldi R16,12
rcall _lcd_write_command
.dbline -2
L2:
.dbline 0 ; func end
ret
.dbend
.dbfunc e lcd_write_command _lcd_write_command fV
; wait_en -> R22
; command -> R20
.even
_lcd_write_command::
rcall push_gset2
mov R22,R18
mov R20,R16
.dbline -1
.dbline 42
; }
;
; //写指令函数: E=高脉冲 RS=0 RW=0
; void lcd_write_command(unsigned char command,unsigned char wait_en)//command为指令,wait_en指定是否要检测LCD忙信号
; {
.dbline 43
; if(wait_en)wait_enable();//若wait_en为1,则要检测LCD忙信号,等待其空闲
tst R22
breq L4
.dbline 43
rcall _wait_enable
L4:
.dbline 44
; lcd_control_port&=~lcd_RS;//RS=0
cbi 0x15,0
.dbline 45
; lcd_control_port&=~lcd_RW;//RW=0
cbi 0x15,1
.dbline 46
; lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
cbi 0x15,2
.dbline 47
; NOP();
nop
.dbline 48
; lcd_control_port|=lcd_EN;//E=1
sbi 0x15,2
.dbline 49
; lcd_data_port=command;
out 0x18,R20
.dbline 50
; lcd_control_port&=~lcd_EN;//重设E=0
cbi 0x15,2
.dbline -2
L3:
rcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r wait_en 22 c
.dbsym r command 20 c
.dbend
.dbfunc e lcd_write_data _lcd_write_data fV
; char_data -> R20
.even
_lcd_write_data::
rcall push_gset1
mov R20,R16
.dbline -1
.dbline 55
; }
;
; //写数据函数: E =高脉冲 RS=1 RW=0
; void lcd_write_data(unsigned char char_data)
; {
.dbline 56
; wait_enable();//等待LCD空闲
rcall _wait_enable
.dbline 57
; lcd_control_port|=lcd_RS;//RS=1
sbi 0x15,0
.dbline 58
; lcd_control_port&=~lcd_RW;//RW=0
cbi 0x15,1
.dbline 59
; lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
cbi 0x15,2
.dbline 60
; NOP();
nop
.dbline 61
; lcd_control_port|=lcd_EN;//E=1
sbi 0x15,2
.dbline 62
; lcd_data_port=char_data;
out 0x18,R20
.dbline 63
; lcd_control_port&=~lcd_EN;//重设E=0
cbi 0x15,2
.dbline -2
L6:
rcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r char_data 20 c
.dbend
.dbfunc e wait_enable _wait_enable fV
.even
_wait_enable::
.dbline -1
.dbline 69
; }
;
; //正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;DB7: 0 LCD控制器空闲,1 LCD控制器忙。
; //检测忙信号,等待LCD空闲函数
; void wait_enable(void)
; {
.dbline 70
; lcd_busy_ddr&=~busy;//设置busy口为输入
cbi 0x17,7
.dbline 71
; lcd_control_port&=~lcd_RS;//RS=0
cbi 0x15,0
.dbline 72
; lcd_control_port|=lcd_RW;//RW=1
sbi 0x15,1
.dbline 73
; NOP();
nop
.dbline 74
; lcd_control_port|=lcd_EN;//E=1
sbi 0x15,2
L8:
.dbline 75
L9:
.dbline 75
; while(lcd_busy_pin&busy);//等待LCD_DB7为0
sbic 0x16,7
rjmp L8
.dbline 76
; lcd_control_port&=~lcd_EN;//重设E=0
cbi 0x15,2
.dbline 77
; lcd_busy_ddr|=busy;//设置busy口为输出
sbi 0x17,7
.dbline -2
L7:
.dbline 0 ; func end
ret
.dbend
.dbfunc e lcd_set_xy _lcd_set_xy fV
; address -> R20
; y -> R20
; x -> R22
.even
_lcd_set_xy::
rcall push_gset2
mov R20,R18
mov R22,R16
.dbline -1
.dbline 84
; }
; /**LCD_set_xy:设置LCD显示的起始位置输入参数:x、y :
; 显示字符串的位置,X:0-15,Y:0-1
; LCD第一行显示寄存器地址:0X80-0X8F
; LCD第一行显示寄存器地址:0XC0-0XCF ***/
; void lcd_set_xy( unsigned char x, unsigned char y )
; {
.dbline 86
; unsigned char address;
; if (y == 0)
tst R20
brne L12
.dbline 87
; address = 0x80 + x;
mov R20,R22
subi R20,128 ; addi 128
rjmp L13
L12:
.dbline 89
; else
; address = 0xc0 + x;
mov R20,R22
subi R20,64 ; addi 192
L13:
.dbline 90
; lcd_write_command(address,1);//一定需要检查忙信号,所以为1
ldi R18,1
mov R16,R20
rcall _lcd_write_command
.dbline -2
L11:
rcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r address 20 c
.dbsym r y 20 c
.dbsym r x 22 c
.dbend
.dbfunc e display_a_char _display_a_char fV
; char_data -> y+4
; y -> R22
; x -> R20
.even
_display_a_char::
rcall push_gset2
mov R22,R18
mov R20,R16
.dbline -1
.dbline 94
; }
; //显示一个字符函数
; void display_a_char(unsigned char x,unsigned char y,unsigned char char_data)//char_data为要显示的字符
; {
.dbline 95
; lcd_set_xy(x,y);
mov R18,R22
mov R16,R20
rcall _lcd_set_xy
.dbline 96
; lcd_write_data(char_data);
ldd R16,y+4
rcall _lcd_write_data
.dbline -2
L14:
rcall pop_gset2
.dbline 0 ; func end
ret
.dbsym l char_data 4 c
.dbsym r y 22 c
.dbsym r x 20 c
.dbend
.dbfunc e display_a_string _display_a_string fV
; ptr -> R20,R21
; y -> R10
; x -> R22
.even
_display_a_string::
rcall push_gset3
mov R10,R18
mov R22,R16
ldd R20,y+6
ldd R21,y+7
.dbline -1
.dbline 103
; }
;
; //指定一行显示连续字符串:0显示在第一行,1显示在第二行,注字符串不能长于16个字符
; //显示一行连续字符串函数
;
; void display_a_string(unsigned char x,unsigned char y,unsigned char *ptr)
; {
.dbline 105
; //ptr:指向无符号字符型变量的指针变量,指针也就是地址,指字符串数组的首指针
; lcd_set_xy(x,y);
mov R18,R10
mov R16,R22
rcall _lcd_set_xy
rjmp L17
L16:
.dbline 107
.dbline 108
movw R30,R20
ldd R16,z+0
rcall _lcd_write_data
.dbline 109
subi R20,255 ; offset = 1
sbci R21,255
.dbline 110
L17:
.dbline 106
; while(*ptr)//当ptr='\0'(空指针null)跳出循环
movw R30,R20
ldd R2,z+0
tst R2
brne L16
.dbline -2
L15:
rcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r ptr 20 pc
.dbsym r y 10 c
.dbsym r x 22 c
.dbend
.dbfunc e display_a_fluid _display_a_fluid fV
; ptr -> R20,R21
; y -> R10
; x -> R22
.even
_display_a_fluid::
rcall push_gset3
mov R10,R18
mov R22,R16
ldd R20,y+6
ldd R21,y+7
.dbline -1
.dbline 114
; {
; lcd_write_data(*ptr);//*ptr,指向该地址的内容
; ptr++;
; }
; }
; /*********************流动字幕***********************/
; void display_a_fluid(unsigned char x,unsigned char y,unsigned char *ptr)
; { lcd_write_command(0x07,1);//流动字幕
.dbline 114
ldi R18,1
ldi R16,7
rcall _lcd_write_command
.dbline 115
; lcd_set_xy(x,y);
mov R18,R10
mov R16,R22
rcall _lcd_set_xy
rjmp L21
L20:
.dbline 117
.dbline 118
movw R30,R20
ldd R16,z+0
rcall _lcd_write_data
.dbline 119
ldi R16,200
ldi R17,0
rcall _delay_nms
.dbline 120
subi R20,255 ; offset = 1
sbci R21,255
.dbline 121
L21:
.dbline 116
; while(*ptr)
movw R30,R20
ldd R2,z+0
tst R2
brne L20
.dbline -2
L19:
rcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r ptr 20 pc
.dbsym r y 10 c
.dbsym r x 22 c
.dbend
.dbfunc e delay_1ms _delay_1ms fV
; xtal -> R16
; i -> R18,R19
.even
_delay_1ms::
.dbline -1
.dbline 126
; {
; lcd_write_data(*ptr);
; delay_nms(200);
; ptr++;
; }
; }
;
;
; void delay_1ms(void ) //延时1ms
; {
.dbline 129
; unsigned int i ;
; unsigned char xtal;
; xtal=4;
ldi R16,4
.dbline 130
; for (i=1;i<(xtal*143-2);i++)
ldi R18,1
ldi R19,0
rjmp L27
L24:
.dbline 131
.dbline 132
.dbline 133
L25:
.dbline 130
subi R18,255 ; offset = 1
sbci R19,255
L27:
.dbline 130
ldi R24,143
mul R24,R16
movw R24,R0
sbiw R24,2
cp R18,R24
cpc R19,R25
brlo L24
.dbline -2
L23:
.dbline 0 ; func end
ret
.dbsym r xtal 16 c
.dbsym r i 18 i
.dbend
.dbfunc e delay_nms _delay_nms fV
; i -> R20,R21
; n -> R22,R23
.even
_delay_nms::
rcall push_gset2
movw R22,R16
.dbline -1
.dbline 137
; {
; ;
; }
; }
;
; void delay_nms(unsigned int n) //延时nms
; {
.dbline 138
; unsigned int i=0 ;
clr R20
clr R21
.dbline 139
; for(i=0;i<n;i++)
rjmp L32
L29:
.dbline 140
.dbline 141
rcall _delay_1ms
.dbline 142
L30:
.dbline 139
subi R20,255 ; offset = 1
sbci R21,255
L32:
.dbline 139
cp R20,R22
cpc R21,R23
brlo L29
.dbline -2
L28:
rcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 i
.dbsym r n 22 i
.dbend
.dbfunc e keyboard _keyboard fV
.even
_keyboard::
.dbline 0 ; func end
ret
.dbend
.dbfunc e display_a_fluid _display_a_fluid fV
; ptr -> R2,R3
; y -> R1
; x -> R0
.even
_display_a_fluid::
.dbline 0 ; func end
ret
.dbsym l ptr 4 pc
.dbsym l y 2 c
.dbsym l x 0 c
.dbend
.dbfunc e copy _copy fV
; i -> R2
; y -> R1,R2
; x -> R0,R1
.even
_copy::
.dbline 0 ; func end
ret
.dbsym l i 4 c
.dbsym l y 2 pc
.dbsym l x 0 pc
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -