📄 lcd20x4.lst
字号:
__start:
__text_start:
004B E5CF LDI R28,0x5F
004C E0D4 LDI R29,4
004D BFCD OUT 0x3D,R28
004E BFDE OUT 0x3E,R29
004F 51C0 SUBI R28,0x10
0050 40D0 SBCI R29,0
0051 EA0A LDI R16,0xAA
0052 8308 STD Y+0,R16
0053 2400 CLR R0
0054 EAE1 LDI R30,0xA1
0055 E0F0 LDI R31,0
0056 E010 LDI R17,0
0057 3AE1 CPI R30,0xA1
0058 07F1 CPC R31,R17
0059 F011 BEQ 0x005C
005A 9201 ST R0,Z+
005B CFFB RJMP 0x0057
005C 8300 STD Z+0,R16
005D E5E4 LDI R30,0x54
005E E0F0 LDI R31,0
005F E6A0 LDI R26,0x60
0060 E0B0 LDI R27,0
0061 E010 LDI R17,0
0062 39E5 CPI R30,0x95
0063 07F1 CPC R31,R17
0064 F021 BEQ 0x0069
0065 95C8 LPM
0066 9631 ADIW R30,1
0067 920D ST R0,X+
0068 CFF9 RJMP 0x0062
0069 940E00E8 CALL _main
_exit:
006B CFFF RJMP _exit
FILE: E:\AVR应用实例\LCD20x4\LCD20x4.c
(0001) /*=======================================================
(0002) 20x4字符液晶主程序,编译软件(ICCAVR_6.31)
(0003) CPU内部晶振8M
(0004) 数据线B0~B7接PORTB, E=D7 RW=D6 RS=D5
(0005) =========================================================
(0006) 接线图如下:
(0007) _______________ ______________
(0008) | --1|GND |
(0009) | --2|+5V |
(0010) | --3|V0 |
(0011) | | |
(0012) PD5|--------4|RS |
(0013) PD6|--------5|RW |
(0014) PD7|--------6|E |
(0015) CPU | | |
(0016) ATmmega16L PB0|--------7|D0 LCD20x4 |
(0017) PB1|--------8|D1 |
(0018) PB2|--------9|D2 |
(0019) PB3|-------10|D3 |
(0020) PB4|-------11|D4 |
(0021) PB5|-------12|D5 |
(0022) PB6|-------13|D6 |
(0023) PB7|-------14|D7 |
(0024) | | |
(0025) | --15|+LED |
(0026) | --16|-LED |
(0027) _______________| |______________|
(0028) ========================================================*/
(0029) #include<ioM16V.h> //CPU_ATmmega16L
(0030) #define RS_H asm("sbi 0x12,5") //RS设为高电平
(0031) #define RS_L asm("cbi 0x12,5") //RS设为低电平
(0032) #define RW_H asm("sbi 0x12,6") //RW设为高电平
(0033) #define RW_L asm("cbi 0x12,6") //RW设为低电平
(0034) #define E_H asm("sbi 0x12,7") //E设为高电平
(0035) #define E_L asm("cbi 0x12,7") //E设为低电平
(0036)
(0037) //=======================================================
(0038) //微秒级延时程序
(0039) void delay_us(int time)
(0040) {
(0041) do
(0042) {
(0043) time--;
_delay_us:
time --> R16
006C 5001 SUBI R16,1
006D 4010 SBCI R17,0
(0044) }
(0045) while (time > 1);
006E E081 LDI R24,1
006F E090 LDI R25,0
0070 1780 CP R24,R16
0071 0791 CPC R25,R17
0072 F3CC BLT 0x006C
0073 9508 RET
_delay_ms:
time --> R20
0074 940E0112 CALL push_gset1
0076 01A8 MOVW R20,R16
(0046) }
(0047) //=======================================================
(0048) //毫秒级延时程序
(0049) void delay_ms(unsigned int time)
(0050) {
0077 C005 RJMP 0x007D
(0051) while(time != 0)
(0052) {
(0053) delay_us(1000);
0078 EE08 LDI R16,0xE8
0079 E013 LDI R17,3
007A DFF1 RCALL _delay_us
(0054) time--;
007B 5041 SUBI R20,1
007C 4050 SBCI R21,0
007D 3040 CPI R20,0
007E 0745 CPC R20,R21
007F F7C1 BNE 0x0078
0080 940E0115 CALL pop_gset1
0082 9508 RET
_Lcd_Busy:
r --> R20
0083 940E0112 CALL push_gset1
(0055) }
(0056) }
(0057)
(0058) //=======================================================
(0059) //读取lcd是否内部操作(忙碌)状态
(0060) char Lcd_Busy()
(0061) {
(0062) char r;
(0063) DDRB = 0x00; //端口B设为输入方式
0085 2422 CLR R2
0086 BA27 OUT 0x17,R2
(0064) E_L;RS_L;RW_H; //E=0(致能),RS=0(命令),RW=1(读)
0087 9897 CBI 0x12,7
0088 9895 CBI 0x12,5
0089 9A96 SBI 0x12,6
(0065) delay_us(2); //液晶延时子程序
008A E002 LDI R16,2
008B E010 LDI R17,0
008C DFDF RCALL _delay_us
(0066) E_H;
008D 9A97 SBI 0x12,7
(0067) delay_us(2); //液晶延时子程序
008E E002 LDI R16,2
008F E010 LDI R17,0
0090 DFDB RCALL _delay_us
(0068) r = PINB & 0x80; //读取lcd_data第八位
0091 B346 IN R20,0x16
0092 7840 ANDI R20,0x80
(0069) E_L;
0093 9897 CBI 0x12,7
(0070) DDRB=0xff; //端口B设为输出方式
0094 EF8F LDI R24,0xFF
0095 BB87 OUT 0x17,R24
(0071) return r; //读取结果返回
0096 2F04 MOV R16,R20
0097 940E0115 CALL pop_gset1
0099 9508 RET
_Lcd_Command:
Command --> R20
009A 940E0112 CALL push_gset1
009C 2F40 MOV R20,R16
(0072) }
(0073)
(0074) //=======================================================
(0075) //向Lcd发送命令程序
(0076) void Lcd_Command(unsigned char Command)
(0077) {
(0078) while(Lcd_Busy()); //判断lcd是否内部操作状态
009D DFE5 RCALL _Lcd_Busy
009E 2300 TST R16
009F F7E9 BNE 0x009D
(0079) E_L;RS_L;RW_L; //E=0(致能),RS=0(命令),RW=0(写)
00A0 9897 CBI 0x12,7
00A1 9895 CBI 0x12,5
00A2 9896 CBI 0x12,6
(0080) delay_us(2); //液晶延时子程序
00A3 E002 LDI R16,2
00A4 E010 LDI R17,0
00A5 DFC6 RCALL _delay_us
(0081) E_H;
00A6 9A97 SBI 0x12,7
(0082) PORTB = Command; //向Lcd发送命令
00A7 BB48 OUT 0x18,R20
(0083) delay_us(2); //液晶延时子程序
00A8 E002 LDI R16,2
00A9 E010 LDI R17,0
00AA DFC1 RCALL _delay_us
(0084) E_L;
00AB 9897 CBI 0x12,7
00AC 940E0115 CALL pop_gset1
00AE 9508 RET
_Lcd_Write:
Data --> R20
00AF 940E0112 CALL push_gset1
00B1 2F40 MOV R20,R16
(0085) }
(0086)
(0087) //=======================================================
(0088) //向lcd写入一个字符程序
(0089) void Lcd_Write(unsigned char Data)
(0090) {
(0091) while(Lcd_Busy()); //判断lcd是否内部操作状态
00B2 DFD0 RCALL _Lcd_Busy
00B3 2300 TST R16
00B4 F7E9 BNE 0x00B2
(0092) E_L;RS_H;RW_L; //E=0(致能),RS=1(数据),RW=0(写)
00B5 9897 CBI 0x12,7
00B6 9A95 SBI 0x12,5
00B7 9896 CBI 0x12,6
(0093) delay_us(2); //液晶延时子程序
00B8 E002 LDI R16,2
00B9 E010 LDI R17,0
00BA DFB1 RCALL _delay_us
(0094) E_H;
00BB 9A97 SBI 0x12,7
(0095) PORTB = Data; //向lcd写入一个字符
00BC BB48 OUT 0x18,R20
(0096) delay_us(2); //液晶延时子程序
00BD E002 LDI R16,2
00BE E010 LDI R17,0
00BF DFAC RCALL _delay_us
(0097) E_L;
00C0 9897 CBI 0x12,7
00C1 940E0115 CALL pop_gset1
00C3 9508 RET
(0098) }
(0099)
(0100)
(0101) /*=======================================================
(0102) LCD第1行显示地址1~20(0x80~0x93)
(0103) LCD第2行显示地址1~20(0xc0~0xd3)
(0104) LCD第3行显示地址1~20(0x94~0xa7)
(0105) LCD第4行显示地址1~20(0xd4~0xe7)
(0106) =======================================================*/
(0107) //初始化LCD_8位接口,4行x20字符的工作方式
(0108) void Lcd_Init()
(0109) {
(0110) DDRB = 0xff; //端口B设为输出方式
_Lcd_Init:
00C4 EF8F LDI R24,0xFF
00C5 BB87 OUT 0x17,R24
(0111) DDRD = 0xff; //端口D设为输出方式
00C6 BB81 OUT 0x11,R24
(0112) Lcd_Command(0x38); //
00C7 E308 LDI R16,0x38
00C8 DFD1 RCALL _Lcd_Command
(0113) Lcd_Command(0x38); //
00C9 E308 LDI R16,0x38
00CA DFCF RCALL _Lcd_Command
(0114) Lcd_Command(0x38); //
00CB E308 LDI R16,0x38
00CC DFCD RCALL _Lcd_Command
(0115) Lcd_Command(0x38); //
00CD E308 LDI R16,0x38
00CE DFCB RCALL _Lcd_Command
(0116) Lcd_Command(0x08); //令显示器off
00CF E008 LDI R16,0x8
00D0 DFC9 RCALL _Lcd_Command
(0117) Lcd_Command(0x01); //清除显示器
00D1 E001 LDI R16,1
00D2 DFC7 RCALL _Lcd_Command
(0118) Lcd_Command(0x06); //令LCD每接收到1Byte数据后,AC自动加1
00D3 E006 LDI R16,6
00D4 DFC5 RCALL _Lcd_Command
(0119) Lcd_Command(0x0C); //令光标,0x0c=不显示,0x0d=显示闪动.
00D5 E00C LDI R16,0xC
00D6 DFC3 RCALL _Lcd_Command
00D7 9508 RET
_asc_tran:
asc --> R20
00D8 940E0112 CALL push_gset1
00DA 01A8 MOVW R20,R16
(0120) }
(0121)
(0122) //=======================================================
(0123) //写ASCII字符串程序
(0124) void asc_tran(unsigned char *asc)
(0125) {
00DB C005 RJMP 0x00E1
(0126) while((*asc) != 0) //判断字是否结束
(0127) {
(0128) Lcd_Write(*asc); //向lcd写入字符串
00DC 01FA MOVW R30,R20
00DD 8100 LDD R16,Z+0
00DE DFD0 RCALL _Lcd_Write
(0129) asc++; //移下一个字符
00DF 5F4F SUBI R20,0xFF
00E0 4F5F SBCI R21,0xFF
00E1 01FA MOVW R30,R20
00E2 8020 LDD R2,Z+0
00E3 2022 TST R2
00E4 F7B9 BNE 0x00DC
00E5 940E0115 CALL pop_gset1
00E7 9508 RET
(0130) }
(0131) }
(0132)
(0133) //=======================================================
(0134) //测试主LCD主程序
(0135) void main()
(0136) {
(0137) Lcd_Init(); //初始化LCD
_main:
00E8 DFDB RCALL _Lcd_Init
00E9 C01E RJMP 0x0108
(0138) while(1)
(0139) {
(0140) Lcd_Command(0x83); //设置显示位址
00EA E803 LDI R16,0x83
00EB DFAE RCALL _Lcd_Command
(0141) asc_tran("-----@_@------"); //显示字符串
00EC E902 LDI R16,0x92
00ED E010 LDI R17,0
00EE DFE9 RCALL _asc_tran
(0142) Lcd_Command(0x97); //设置显示位址
00EF E907 LDI R16,0x97
00F0 DFA9 RCALL _Lcd_Command
(0143) asc_tran("www.ouravr.com"); //显示字符串
00F1 E803 LDI R16,0x83
00F2 E010 LDI R17,0
00F3 DFE4 RCALL _asc_tran
(0144) delay_ms(1000); //延迟1秒
00F4 EE08 LDI R16,0xE8
00F5 E013 LDI R17,3
00F6 DF7D RCALL _delay_ms
(0145) Lcd_Command(0x01); //清除显示器
00F7 E001 LDI R16,1
00F8 DFA1 RCALL _Lcd_Command
(0146)
(0147) Lcd_Command(0x83); //设置显示位址
00F9 E803 LDI R16,0x83
00FA DF9F RCALL _Lcd_Command
(0148) asc_tran("-----^_^------"); //显示字符串
00FB E704 LDI R16,0x74
00FC E010 LDI R17,0
00FD DFDA RCALL _asc_tran
(0149) Lcd_Command(0x94); //设置显示位址
00FE E904 LDI R16,0x94
00FF DF9A RCALL _Lcd_Command
(0150) asc_tran("http://59.36.96.196"); //显示字符串
0100 E600 LDI R16,0x60
0101 E010 LDI R17,0
0102 DFD5 RCALL _asc_tran
(0151) delay_ms(1000); //延迟
0103 EE08 LDI R16,0xE8
0104 E013 LDI R17,3
0105 DF6E RCALL _delay_ms
(0152) Lcd_Command(0x01); //清除显示器
FILE: <library>
0106 E001 LDI R16,1
0107 DF92 RCALL _Lcd_Command
0108 CFE1 RJMP 0x00EA
0109 9508 RET
push_gset5:
010A 92FA ST R15,-Y
010B 92EA ST R14,-Y
push_gset4:
010C 92DA ST R13,-Y
010D 92CA ST R12,-Y
push_gset3:
010E 92BA ST R11,-Y
010F 92AA ST R10,-Y
push_gset2:
0110 937A ST R23,-Y
0111 936A ST R22,-Y
push_gset1:
0112 935A ST R21,-Y
0113 934A ST R20,-Y
0114 9508 RET
pop_gset1:
0115 E0E1 LDI R30,1
pop:
0116 9149 LD R20,Y+
0117 9159 LD R21,Y+
0118 FDE0 SBRC R30,0
0119 9508 RET
011A 9169 LD R22,Y+
011B 9179 LD R23,Y+
011C FDE1 SBRC R30,1
011D 9508 RET
011E 90A9 LD R10,Y+
011F 90B9 LD R11,Y+
0120 FDE2 SBRC R30,2
0121 9508 RET
0122 90C9 LD R12,Y+
0123 90D9 LD R13,Y+
0124 FDE3 SBRC R30,3
0125 9508 RET
0126 90E9 LD R14,Y+
0127 90F9 LD R15,Y+
0128 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -