📄 lcd1602.s
字号:
.module lcd1602.c
.area text(rom, con, rel)
.dbfile E:\MYWORK~1\开发设计\EasyAVR\程序范例\Mega16程序包\完成整理\LCD1602\lcd1602.c
.dbfunc e delay_1us _delay_1us fV
.even
_delay_1us::
.dbline -1
.dbline 42
; /****************************************Copyright (c)**************************************************
; ** ADEmbed Development Co.,LTD.
; ** http://www.adembed.com
; **--------------File Info-------------------------------------------------------------------------------
; ** File name: lcd1602.c
; ** Last modified Date: 2008-10-13
; ** Last Version: 1.0
; ** Descriptions: lcd1602 test.
; **
; **------------------------------------------------------------------------------------------------------
; ** Created by: zhoufeng
; ** Created date: 2008-10-13
; ** Version: 1.0
; ** Descriptions:
; **
; **------------------------------------------------------------------------------------------------------
; ** Modified by: junbolu
; ** Modified date: 2008-12-13
; ** Version:
; ** Descriptions:
; **
; **------------------------------------------------------------------------------------------------------
; **ICC-AVR application builder : 2008-12-13
; **Target : M16
; **Crystal: 7.3728Mhz
; **
; **
; **描述:这是一个Lcd1602的测试程序。LCD1602型号为JHD162A 使用8位并口数据传输.
; **
; **
; **涉及知识点:
; **
; **
; **
; *******************************************************************************************************/
; #include <iom16v.h>
; #include <macros.h>
; #include"lcd1602.h"
;
; //时钟频率:内部RC振荡8MHz
; void delay_1us(void) //延时1us
; {//ret:4t+call:4t=8t,8MHz时1t为125ns,8t为1000ns=1us
.dbline -2
L1:
.dbline 0 ; func end
ret
.dbend
.dbfunc e delay_nus _delay_nus fV
; n -> R16,R17
.even
_delay_nus::
.dbline -1
.dbline 46
; }
;
; void delay_nus(unsigned int n) //延时n us
; {//(8+(4+4)*(n-1)+3)t=(8+8n-8+3)t=(8n+3)t=n us+0.375us,所以约等于1us,特别n越大越精确
xjmp L4
L3:
.dbline 48
.dbline 49
nop
.dbline 50
nop
.dbline 51
nop
.dbline 52
nop
.dbline 53
L4:
.dbline 47
; while(--n)
movw R24,R16
sbiw R24,1
movw R16,R24
cpi R16,0
cpc R16,R17
brne L3
X0:
.dbline -2
L2:
.dbline 0 ; func end
ret
.dbsym r n 16 i
.dbend
.dbfunc e delay_1ms _delay_1ms fV
.even
_delay_1ms::
.dbline -1
.dbline 56
; {
; asm("nop"); //nop需1t
; asm("nop");
; asm("nop");
; asm("nop");
; }
; }
; void delay_1ms(void) //延时1ms
; {//函数调用本身有8t=1us
.dbline 57
; delay_nus(999); //为999us
ldi R16,999
ldi R17,3
xcall _delay_nus
.dbline -2
L6:
.dbline 0 ; func end
ret
.dbend
.dbfunc e delay_nms _delay_nms fV
; n -> R20,R21
.even
_delay_nms::
xcall push_gset1
movw R20,R16
.dbline -1
.dbline 61
; }
;
; void delay_nms(unsigned int n) //延时nms
; {//(8+4*(n-1)+3)t+delay_nus=(7+4n)t+delay_nus
.dbline 62
; for(;n>0;n--)
xjmp L11
L8:
.dbline 63
.dbline 64
nop
.dbline 65
ldi R16,999
ldi R17,3
xcall _delay_nus
.dbline 69
L9:
.dbline 62
subi R20,1
sbci R21,0
L11:
.dbline 62
cpi R20,0
cpc R20,R21
brne L8
X1:
.dbline -2
L7:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r n 20 i
.dbend
.dbfunc e lcd_wait_enable _lcd_wait_enable fV
.even
_lcd_wait_enable::
.dbline -1
.dbline 73
; {
; asm("nop"); //再补尝,变成了(7+5n)t+delay_nus
; delay_nus(999); /*delay_nus(m)为(8m+3)t所以delay_nus的参数只要999就可以了
; (7+5n)t+((8m+3)*n)t=(7+8n+8mn)t=7t+n us+mn us
; =7t+(m+1)n us,代入m=999约等于1000n us=n ms,误差仅为7t,不到1us
; */
; }
; }
;
; void lcd_wait_enable(void) //LCD等待可写
; {
.dbline 74
; Data_in(); //置为输入
clr R2
out 0x1a,R2
.dbline 75
; clr_rs();
cbi 0x15,3
.dbline 76
; set_rw();
sbi 0x15,4
.dbline 77
; delay_nus(1);
ldi R16,1
ldi R17,0
xcall _delay_nus
.dbline 78
; set_en();
sbi 0x15,5
.dbline 79
; delay_nus(2);
ldi R16,2
ldi R17,0
xcall _delay_nus
L13:
.dbline 80
L14:
.dbline 80
; while((Data_PIN&0x80)>>7);
in R24,0x19
andi R24,128
lsr R24
lsr R24
lsr R24
lsr R24
lsr R24
lsr R24
lsr R24
tst R24
brne L13
.dbline 81
; clr_en();
cbi 0x15,5
.dbline 82
; Data_out();
ldi R24,255
out 0x1a,R24
.dbline -2
L12:
.dbline 0 ; func end
ret
.dbend
.dbfunc e lcd_write_cmd _lcd_write_cmd fV
; attrib -> R22
; cmd -> R20
.even
_lcd_write_cmd::
xcall push_gset2
mov R22,R18
mov R20,R16
.dbline -1
.dbline 86
; }
;
; void lcd_write_cmd(char cmd,char attrib) //写命令,attrib为0不检查忙状态,否则检查忙状态
; {
.dbline 87
; if(attrib) lcd_wait_enable();
tst R22
breq L17
.dbline 87
xcall _lcd_wait_enable
L17:
.dbline 88
; clr_rs();
cbi 0x15,3
.dbline 89
; clr_rw();
cbi 0x15,4
.dbline 90
; delay_nus(1);
ldi R16,1
ldi R17,0
xcall _delay_nus
.dbline 91
; Data_PORT=cmd;
out 0x1b,R20
.dbline 92
; delay_nus(1);
ldi R16,1
ldi R17,0
xcall _delay_nus
.dbline 93
; set_en();
sbi 0x15,5
.dbline 94
; delay_nus(2);
ldi R16,2
ldi R17,0
xcall _delay_nus
.dbline 95
; clr_en();
cbi 0x15,5
.dbline -2
L16:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r attrib 22 c
.dbsym r cmd 20 c
.dbend
.dbfunc e lcd_set_xy _lcd_set_xy fV
; tmp -> R20,R21
; y -> R20,R21
; x -> R22,R23
.even
_lcd_set_xy::
xcall push_gset2
movw R20,R18
movw R22,R16
.dbline -1
.dbline 99
; }
;
; void lcd_set_xy(int x,int y) //设置显示的起始地址,x行,y列
; {
.dbline 101
; int tmp;
; tmp=y&0x0F;
andi R20,15
andi R21,0
.dbline 102
; x&=0x01;
andi R22,1
andi R23,0
.dbline 103
; if(x) //第二行
cpi R22,0
cpc R22,R23
breq L20
X2:
.dbline 104
; tmp|=0x40;
ori R20,64
L20:
.dbline 105
; tmp|=0x80;
ori R20,128
.dbline 106
; lcd_write_cmd(tmp,0);
clr R18
mov R16,R20
xcall _lcd_write_cmd
.dbline -2
L19:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r tmp 20 I
.dbsym r y 20 I
.dbsym r x 22 I
.dbend
.dbfunc e lcd_write_byte _lcd_write_byte fV
; byte -> R20
.even
_lcd_write_byte::
xcall push_gset1
mov R20,R16
.dbline -1
.dbline 110
; }
;
; void lcd_write_byte(char byte) //写字节
; {
.dbline 111
; lcd_wait_enable();
xcall _lcd_wait_enable
.dbline 112
; set_rs();
sbi 0x15,3
.dbline 113
; clr_rw();
cbi 0x15,4
.dbline 114
; delay_nus(1);
ldi R16,1
ldi R17,0
xcall _delay_nus
.dbline 115
; Data_PORT=byte;
out 0x1b,R20
.dbline 116
; set_en();
sbi 0x15,5
.dbline 117
; delay_nus(2);
ldi R16,2
ldi R17,0
xcall _delay_nus
.dbline 118
; clr_en();
cbi 0x15,5
.dbline -2
L22:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r byte 20 c
.dbend
.dbfunc e lcd_disp_char _lcd_disp_char fV
; ch -> y+4
; y -> R22,R23
; x -> R20,R21
.even
_lcd_disp_char::
xcall push_gset2
movw R22,R18
movw R20,R16
.dbline -1
.dbline 122
; }
;
; void lcd_disp_char(int x,int y,char ch) //写字串
; {
.dbline 123
; lcd_set_xy(x,y);
movw R18,R22
movw R16,R20
xcall _lcd_set_xy
.dbline 124
; lcd_write_byte(ch);
ldd R16,y+4
xcall _lcd_write_byte
.dbline -2
L23:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym l ch 4 c
.dbsym r y 22 I
.dbsym r x 20 I
.dbend
.dbfunc e lcd_disp_string _lcd_disp_string fV
; i -> R20
; s -> R22,R23
; y -> R10,R11
; x -> R12,R13
.even
_lcd_disp_string::
xcall push_gset4
movw R10,R18
movw R12,R16
sbiw R28,1
ldd R22,y+9
ldd R23,y+10
.dbline -1
.dbline 128
; }
;
; void lcd_disp_string(int x,int y,char *s) //写字串,支持换行
; {
.dbline 129
; unsigned char i=0;
clr R20
xjmp L26
L25:
.dbline 131
; while (*s)
; {
.dbline 132
; if(y+i<16)
mov R2,R20
clr R3
movw R24,R10
add R24,R2
adc R25,R3
cpi R24,16
ldi R30,0
cpc R25,R30
brge L28
.dbline 133
; {
.dbline 134
; lcd_disp_char(x,y+i,*s);
movw R30,R22
ldd R2,z+0
std y+0,R2
mov R2,R20
clr R3
movw R18,R10
add R18,R2
adc R19,R3
movw R16,R12
xcall _lcd_disp_char
.dbline 135
; s++;
subi R22,255 ; offset = 1
sbci R23,255
.dbline 136
; i++;
inc R20
.dbline 137
; }
xjmp L29
L28:
.dbline 139
; else
; {
.dbline 140
; delay_nus(50); //换行至少延时20us,否则会造成显示不正常
ldi R16,50
ldi R17,0
xcall _delay_nus
.dbline 141
; lcd_disp_char(x^1,y+i-16,*s);
movw R30,R22
ldd R2,z+0
std y+0,R2
mov R2,R20
clr R3
movw R18,R10
add R18,R2
adc R19,R3
subi R18,16
sbci R19,0
ldi R24,1
ldi R25,0
movw R16,R12
eor R16,R24
eor R17,R25
xcall _lcd_disp_char
.dbline 142
; s++;
subi R22,255 ; offset = 1
sbci R23,255
.dbline 143
; i++;
inc R20
.dbline 144
; }
L29:
.dbline 145
L26:
.dbline 130
movw R30,R22
ldd R2,z+0
tst R2
breq X3
xjmp L25
X3:
.dbline -2
L24:
adiw R28,1
xcall pop_gset4
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r s 22 pc
.dbsym r y 10 I
.dbsym r x 12 I
.dbend
.dbfunc e lcd_init _lcd_init fV
.even
_lcd_init::
.dbline -1
.dbline 149
; }
; }
;
; void lcd_init(void) //初始化液晶
; {
.dbline 150
; Open_Ctrl();
ldi R24,184
out 0x14,R24
.dbline 151
; Data_out();
ldi R24,255
out 0x1a,R24
.dbline 152
; lcd_write_cmd(0x38,0); //显示模式设置(不测试忙信号)共三次
clr R18
ldi R16,56
xcall _lcd_write_cmd
.dbline 153
; delay_nms(5);
ldi R16,5
ldi R17,0
xcall _delay_nms
.dbline 154
; lcd_write_cmd(0x38,0);
clr R18
ldi R16,56
xcall _lcd_write_cmd
.dbline 155
; delay_nms(5);
ldi R16,5
ldi R17,0
xcall _delay_nms
.dbline 156
; lcd_write_cmd(0x38,0);
clr R18
ldi R16,56
xcall _lcd_write_cmd
.dbline 157
; delay_nms(5);
ldi R16,5
ldi R17,0
xcall _delay_nms
.dbline 159
;
; lcd_write_cmd(0x38,1); //8位数据口,2行显示,5*7点阵
ldi R18,1
ldi R16,56
xcall _lcd_write_cmd
.dbline 160
; lcd_write_cmd(0x08,1); //显示关
ldi R18,1
ldi R16,8
xcall _lcd_write_cmd
.dbline 161
; lcd_write_cmd(0x01,1); //清屏
ldi R18,1
ldi R16,1
xcall _lcd_write_cmd
.dbline 162
; lcd_write_cmd(0x06,1); //数据读,写后AC自增1,画面不动
ldi R18,1
ldi R16,6
xcall _lcd_write_cmd
.dbline 163
; lcd_write_cmd(0x0C,1); //显示开
ldi R18,1
ldi R16,12
xcall _lcd_write_cmd
.dbline -2
L30:
.dbline 0 ; func end
ret
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -