📄 lcd1602.lst
字号:
__text_start:
__start:
0050 E5CF LDI R28,0x5F
0051 E0D4 LDI R29,4
0052 BFCD OUT 0x3D,R28
0053 BFDE OUT 0x3E,R29
0054 51C0 SUBI R28,0x10
0055 40D0 SBCI R29,0
0056 EA0A LDI R16,0xAA
0057 8308 STD Y+0,R16
0058 2400 CLR R0
0059 E6E0 LDI R30,0x60
005A E0F0 LDI R31,0
005B E010 LDI R17,0
005C 36E0 CPI R30,0x60
005D 07F1 CPC R31,R17
005E F011 BEQ 0x0061
005F 9201 ST R0,Z+
0060 CFFB RJMP 0x005C
0061 8300 STD Z+0,R16
0062 E9EF LDI R30,0x9F
0063 E0F0 LDI R31,0
0064 E6A0 LDI R26,0x60
0065 E0B0 LDI R27,0
0066 E010 LDI R17,0
0067 39EF CPI R30,0x9F
0068 07F1 CPC R31,R17
0069 F021 BEQ 0x006E
006A 95C8 LPM
006B 9631 ADIW R30,1
006C 920D ST R0,X+
006D CFF9 RJMP 0x0067
006E 940E015A CALL _main
_exit:
0070 CFFF RJMP _exit
FILE: E:\MYWORK~1\开发设计\EasyAVR\程序范例\Mega16程序包\完成整理\LCD1602\lcd1602.c
(0001) /****************************************Copyright (c)**************************************************
(0002) ** ADEmbed Development Co.,LTD.
(0003) ** http://www.adembed.com
(0004) **--------------File Info-------------------------------------------------------------------------------
(0005) ** File name: lcd1602.c
(0006) ** Last modified Date: 2008-10-13
(0007) ** Last Version: 1.0
(0008) ** Descriptions: lcd1602 test.
(0009) **
(0010) **------------------------------------------------------------------------------------------------------
(0011) ** Created by: zhoufeng
(0012) ** Created date: 2008-10-13
(0013) ** Version: 1.0
(0014) ** Descriptions:
(0015) **
(0016) **------------------------------------------------------------------------------------------------------
(0017) ** Modified by: junbolu
(0018) ** Modified date: 2008-12-13
(0019) ** Version:
(0020) ** Descriptions:
(0021) **
(0022) **------------------------------------------------------------------------------------------------------
(0023) **ICC-AVR application builder : 2008-12-13
(0024) **Target : M16
(0025) **Crystal: 7.3728Mhz
(0026) **
(0027) **
(0028) **描述:这是一个Lcd1602的测试程序。LCD1602型号为JHD162A 使用8位并口数据传输.
(0029) **
(0030) **
(0031) **涉及知识点:
(0032) **
(0033) **
(0034) **
(0035) *******************************************************************************************************/
(0036) #include <iom16v.h>
(0037) #include <macros.h>
(0038) #include"lcd1602.h"
(0039)
(0040) //时钟频率:内部RC振荡8MHz
(0041) void delay_1us(void) //延时1us
(0042) {//ret:4t+call:4t=8t,8MHz时1t为125ns,8t为1000ns=1us
_delay_1us:
0071 9508 RET
(0043) }
(0044)
(0045) void delay_nus(unsigned int n) //延时n us
(0046) {//(8+(4+4)*(n-1)+3)t=(8+8n-8+3)t=(8n+3)t=n us+0.375us,所以约等于1us,特别n越大越精确
_delay_nus:
n --> R16
0072 C004 RJMP 0x0077
(0047) while(--n)
(0048) {
(0049) asm("nop"); //nop需1t
0073 0000 NOP
(0050) asm("nop");
0074 0000 NOP
(0051) asm("nop");
0075 0000 NOP
(0052) asm("nop");
0076 0000 NOP
0077 01C8 MOVW R24,R16
0078 9701 SBIW R24,1
0079 018C MOVW R16,R24
007A 3000 CPI R16,0
007B 0701 CPC R16,R17
007C F7B1 BNE 0x0073
007D 9508 RET
(0053) }
(0054) }
(0055) void delay_1ms(void) //延时1ms
(0056) {//函数调用本身有8t=1us
(0057) delay_nus(999); //为999us
_delay_1ms:
007E EE07 LDI R16,0xE7
007F E013 LDI R17,3
0080 DFF1 RCALL _delay_nus
0081 9508 RET
_delay_nms:
n --> R20
0082 940E0202 CALL push_gset1
0084 01A8 MOVW R20,R16
(0058) }
(0059)
(0060) void delay_nms(unsigned int n) //延时nms
(0061) {//(8+4*(n-1)+3)t+delay_nus=(7+4n)t+delay_nus
(0062) for(;n>0;n--)
0085 C006 RJMP 0x008C
(0063) {
(0064) asm("nop"); //再补尝,变成了(7+5n)t+delay_nus
0086 0000 NOP
(0065) delay_nus(999); /*delay_nus(m)为(8m+3)t所以delay_nus的参数只要999就可以了
0087 EE07 LDI R16,0xE7
0088 E013 LDI R17,3
0089 DFE8 RCALL _delay_nus
008A 5041 SUBI R20,1
008B 4050 SBCI R21,0
008C 3040 CPI R20,0
008D 0745 CPC R20,R21
008E F7B9 BNE 0x0086
008F 940E0205 CALL pop_gset1
0091 9508 RET
(0066) (7+5n)t+((8m+3)*n)t=(7+8n+8mn)t=7t+n us+mn us
(0067) =7t+(m+1)n us,代入m=999约等于1000n us=n ms,误差仅为7t,不到1us
(0068) */
(0069) }
(0070) }
(0071)
(0072) void lcd_wait_enable(void) //LCD等待可写
(0073) {
(0074) Data_in(); //置为输入
_lcd_wait_enable:
0092 2422 CLR R2
0093 BA2A OUT 0x1A,R2
(0075) clr_rs();
0094 98AB CBI 0x15,3
(0076) set_rw();
0095 9AAC SBI 0x15,4
(0077) delay_nus(1);
0096 E001 LDI R16,1
0097 E010 LDI R17,0
0098 DFD9 RCALL _delay_nus
(0078) set_en();
0099 9AAD SBI 0x15,5
(0079) delay_nus(2);
009A E002 LDI R16,2
009B E010 LDI R17,0
009C DFD5 RCALL _delay_nus
(0080) while((Data_PIN&0x80)>>7);
009D B389 IN R24,0x19
009E 7880 ANDI R24,0x80
009F 9586 LSR R24
00A0 9586 LSR R24
00A1 9586 LSR R24
00A2 9586 LSR R24
00A3 9586 LSR R24
00A4 9586 LSR R24
00A5 9586 LSR R24
00A6 2388 TST R24
00A7 F7A9 BNE 0x009D
(0081) clr_en();
00A8 98AD CBI 0x15,5
(0082) Data_out();
00A9 EF8F LDI R24,0xFF
00AA BB8A OUT 0x1A,R24
00AB 9508 RET
_lcd_write_cmd:
attrib --> R22
cmd --> R20
00AC 940E0200 CALL push_gset2
00AE 2F62 MOV R22,R18
00AF 2F40 MOV R20,R16
(0083) }
(0084)
(0085) void lcd_write_cmd(char cmd,char attrib) //写命令,attrib为0不检查忙状态,否则检查忙状态
(0086) {
(0087) if(attrib) lcd_wait_enable();
00B0 2366 TST R22
00B1 F009 BEQ 0x00B3
00B2 DFDF RCALL _lcd_wait_enable
(0088) clr_rs();
00B3 98AB CBI 0x15,3
(0089) clr_rw();
00B4 98AC CBI 0x15,4
(0090) delay_nus(1);
00B5 E001 LDI R16,1
00B6 E010 LDI R17,0
00B7 DFBA RCALL _delay_nus
(0091) Data_PORT=cmd;
00B8 BB4B OUT 0x1B,R20
(0092) delay_nus(1);
00B9 E001 LDI R16,1
00BA E010 LDI R17,0
00BB DFB6 RCALL _delay_nus
(0093) set_en();
00BC 9AAD SBI 0x15,5
(0094) delay_nus(2);
00BD E002 LDI R16,2
00BE E010 LDI R17,0
00BF DFB2 RCALL _delay_nus
(0095) clr_en();
00C0 98AD CBI 0x15,5
00C1 940E01F4 CALL pop_gset2
00C3 9508 RET
_lcd_set_xy:
tmp --> R20
y --> R20
x --> R22
00C4 940E0200 CALL push_gset2
00C6 01A9 MOVW R20,R18
00C7 01B8 MOVW R22,R16
(0096) }
(0097)
(0098) void lcd_set_xy(int x,int y) //设置显示的起始地址,x行,y列
(0099) {
(0100) int tmp;
(0101) tmp=y&0x0F;
00C8 704F ANDI R20,0xF
00C9 7050 ANDI R21,0
(0102) x&=0x01;
00CA 7061 ANDI R22,1
00CB 7070 ANDI R23,0
(0103) if(x) //第二行
00CC 3060 CPI R22,0
00CD 0767 CPC R22,R23
00CE F009 BEQ 0x00D0
(0104) tmp|=0x40;
00CF 6440 ORI R20,0x40
(0105) tmp|=0x80;
00D0 6840 ORI R20,0x80
(0106) lcd_write_cmd(tmp,0);
00D1 2722 CLR R18
00D2 2F04 MOV R16,R20
00D3 DFD8 RCALL _lcd_write_cmd
00D4 940E01F4 CALL pop_gset2
00D6 9508 RET
_lcd_write_byte:
byte --> R20
00D7 940E0202 CALL push_gset1
00D9 2F40 MOV R20,R16
(0107) }
(0108)
(0109) void lcd_write_byte(char byte) //写字节
(0110) {
(0111) lcd_wait_enable();
00DA DFB7 RCALL _lcd_wait_enable
(0112) set_rs();
00DB 9AAB SBI 0x15,3
(0113) clr_rw();
00DC 98AC CBI 0x15,4
(0114) delay_nus(1);
00DD E001 LDI R16,1
00DE E010 LDI R17,0
00DF DF92 RCALL _delay_nus
(0115) Data_PORT=byte;
00E0 BB4B OUT 0x1B,R20
(0116) set_en();
00E1 9AAD SBI 0x15,5
(0117) delay_nus(2);
00E2 E002 LDI R16,2
00E3 E010 LDI R17,0
00E4 DF8D RCALL _delay_nus
(0118) clr_en();
00E5 98AD CBI 0x15,5
00E6 940E0205 CALL pop_gset1
00E8 9508 RET
_lcd_disp_char:
ch --> Y+4
y --> R22
x --> R20
00E9 940E0200 CALL push_gset2
00EB 01B9 MOVW R22,R18
00EC 01A8 MOVW R20,R16
(0119) }
(0120)
(0121) void lcd_disp_char(int x,int y,char ch) //写字串
(0122) {
(0123) lcd_set_xy(x,y);
00ED 019B MOVW R18,R22
00EE 018A MOVW R16,R20
00EF DFD4 RCALL _lcd_set_xy
(0124) lcd_write_byte(ch);
00F0 810C LDD R16,Y+4
00F1 DFE5 RCALL _lcd_write_byte
00F2 940E01F4 CALL pop_gset2
00F4 9508 RET
_lcd_disp_string:
i --> R20
s --> R22
y --> R10
x --> R12
00F5 940E01FC CALL push_gset4
00F7 0159 MOVW R10,R18
00F8 0168 MOVW R12,R16
00F9 9721 SBIW R28,1
00FA 8569 LDD R22,Y+9
00FB 857A LDD R23,Y+10
(0125) }
(0126)
(0127) void lcd_disp_string(int x,int y,char *s) //写字串,支持换行
(0128) {
(0129) unsigned char i=0;
00FC 2744 CLR R20
00FD C02D RJMP 0x012B
(0130) while (*s)
(0131) {
(0132) if(y+i<16)
00FE 2E24 MOV R2,R20
00FF 2433 CLR R3
0100 01C5 MOVW R24,R10
0101 0D82 ADD R24,R2
0102 1D93 ADC R25,R3
0103 3180 CPI R24,0x10
0104 E0E0 LDI R30,0
0105 079E CPC R25,R30
0106 F474 BGE 0x0115
(0133) {
(0134) lcd_disp_char(x,y+i,*s);
0107 01FB MOVW R30,R22
0108 8020 LDD R2,Z+0
0109 8228 STD Y+0,R2
010A 2E24 MOV R2,R20
010B 2433 CLR R3
010C 0195 MOVW R18,R10
010D 0D22 ADD R18,R2
010E 1D33 ADC R19,R3
010F 0186 MOVW R16,R12
0110 DFD8 RCALL _lcd_disp_char
(0135) s++;
0111 5F6F SUBI R22,0xFF
0112 4F7F SBCI R23,0xFF
(0136) i++;
0113 9543 INC R20
(0137) }
0114 C016 RJMP 0x012B
(0138) else
(0139) {
(0140) delay_nus(50); //换行至少延时20us,否则会造成显示不正常
0115 E302 LDI R16,0x32
0116 E010 LDI R17,0
0117 DF5A RCALL _delay_nus
(0141) lcd_disp_char(x^1,y+i-16,*s);
0118 01FB MOVW R30,R22
0119 8020 LDD R2,Z+0
011A 8228 STD Y+0,R2
011B 2E24 MOV R2,R20
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -