📄 lcd20x4.lst
字号:
__start:
__text_start:
32 E5CF LDI R28,0x5F
33 E0D2 LDI R29,2
34 BFCD OUT 0x3D,R28
35 BFDE OUT 0x3E,R29
36 51C0 SUBI R28,0x10
37 40D0 SBCI R29,0
38 EA0A LDI R16,0xAA
39 8308 STD Y+0,R16
3A 2400 CLR R0
3B EAE1 LDI R30,0xA1
3C E0F0 LDI R31,0
3D E010 LDI R17,0
3E 3AE1 CPI R30,0xA1
3F 07F1 CPC R31,R17
40 F011 BEQ 0x0043
41 9201 ST R0,Z+
42 CFFB RJMP 0x003E
43 8300 STD Z+0,R16
44 E2E2 LDI R30,0x22
45 E0F0 LDI R31,0
46 E6A0 LDI R26,0x60
47 E0B0 LDI R27,0
48 E010 LDI R17,0
49 E000 LDI R16,0
4A BF0B OUT 0x3B,R16
4B 36E3 CPI R30,0x63
4C 07F1 CPC R31,R17
4D F021 BEQ 0x0052
4E 95C8 LPM
4F 9631 ADIW R30,1
50 920D ST R0,X+
51 CFF9 RJMP 0x004B
52 D077 RCALL _main
_exit:
53 CFFF RJMP _exit
FILE: F:\ouravr\M16LCD~1\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) #include <ioM8515V.h>
(0031) #define RS_H asm("sbi 0x15,5")
(0032) //RS设为高电平0xDF 0X12,5
(0033) #define RS_L asm("cbi 0x15,5")
(0034) //RS设为低电平0x20
(0035) #define RW_H asm("sbi 0x15,6")
(0036) //RW设为高电平0xBF
(0037) #define RW_L asm("cbi 0x15,6")
(0038) //RW设为低电平0x40
(0039) #define E_H asm("sbi 0x15,7")
(0040) //E设为高电平0x7F
(0041) #define E_L asm("cbi 0x15,7")
(0042) //E设为低电平0x80
(0043)
(0044) //=======================================================
(0045) //微秒级延时程序
(0046) void delay_us(int time)
(0047) {
(0048) do
(0049) {
(0050) time--;
_delay_us:
time --> R16
54 5001 SUBI R16,1
55 4010 SBCI R17,0
(0051) }
(0052) while (time > 1);
56 E081 LDI R24,1
57 E090 LDI R25,0
58 1780 CP R24,R16
59 0791 CPC R25,R17
5A F3CC BLT 0x0054
5B 9508 RET
_delay_ms:
time --> R20
5C 934A ST R20,-Y
5D 935A ST R21,-Y
5E 01A8 MOVW R20,R16
(0053) }
(0054) //=======================================================
(0055) //毫秒级延时程序
(0056) void delay_ms(unsigned int time)
(0057) {
5F C005 RJMP 0x0065
(0058) while(time != 0)
(0059) {
(0060) delay_us(1000);
60 EE08 LDI R16,0xE8
61 E013 LDI R17,3
62 DFF1 RCALL _delay_us
(0061) time--;
63 5041 SUBI R20,1
64 4050 SBCI R21,0
65 3040 CPI R20,0
66 0745 CPC R20,R21
67 F7C1 BNE 0x0060
68 9159 LD R21,Y+
69 9149 LD R20,Y+
6A 9508 RET
_Lcd_Busy:
r --> R20
6B 934A ST R20,-Y
(0062) }
(0063) }
(0064)
(0065) //=======================================================
(0066) //读取lcd是否内部操作(忙碌)状态
(0067) char Lcd_Busy()
(0068) {
(0069) char r;
(0070) DDRB = 0x00; //端口B设为输入方式
6C 2422 CLR R2
6D BA27 OUT 0x17,R2
(0071) E_L;RS_L;RW_H; //E=0(致能),RS=0(命令),RW=1(读)
6E 98AF CBI 0x15,7
6F 98AD CBI 0x15,5
70 9AAE SBI 0x15,6
(0072) delay_us(2); //液晶延时子程序
71 E002 LDI R16,2
72 E010 LDI R17,0
73 DFE0 RCALL _delay_us
(0073) E_H;
74 9AAF SBI 0x15,7
(0074) delay_us(2); //液晶延时子程序
75 E002 LDI R16,2
76 E010 LDI R17,0
77 DFDC RCALL _delay_us
(0075) r = PINB & 0x80; //读取lcd_data第八位
78 B346 IN R20,0x16
79 7840 ANDI R20,0x80
(0076) E_L;
7A 98AF CBI 0x15,7
(0077) DDRB=0xff; //端口B设为输出方式
7B EF8F LDI R24,0xFF
7C BB87 OUT 0x17,R24
(0078) return r; //读取结果返回
7D 2F04 MOV R16,R20
7E 9149 LD R20,Y+
7F 9508 RET
_Lcd_Command:
Command --> R10
80 92AA ST R10,-Y
81 2EA0 MOV R10,R16
(0079) }
(0080)
(0081) //=======================================================
(0082) //向Lcd发送命令程序
(0083) void Lcd_Command(unsigned char Command)
(0084) {
(0085) while(Lcd_Busy()); //判断lcd是否内部操作状态
82 DFE8 RCALL _Lcd_Busy
83 2300 TST R16
84 F7E9 BNE 0x0082
(0086) E_L;RS_L;RW_L; //E=0(致能),RS=0(命令),RW=0(写)
85 98AF CBI 0x15,7
86 98AD CBI 0x15,5
87 98AE CBI 0x15,6
(0087) delay_us(2); //液晶延时子程序
88 E002 LDI R16,2
89 E010 LDI R17,0
8A DFC9 RCALL _delay_us
(0088) E_H;
8B 9AAF SBI 0x15,7
(0089) PORTB = Command; //向Lcd发送命令
8C BAA8 OUT 0x18,R10
(0090) delay_us(2); //液晶延时子程序
8D E002 LDI R16,2
8E E010 LDI R17,0
8F DFC4 RCALL _delay_us
(0091) E_L;
90 98AF CBI 0x15,7
91 90A9 LD R10,Y+
92 9508 RET
_Lcd_Write:
Data --> R10
93 92AA ST R10,-Y
94 2EA0 MOV R10,R16
(0092) }
(0093)
(0094) //=======================================================
(0095) //向lcd写入一个字符程序
(0096) void Lcd_Write(unsigned char Data)
(0097) {
(0098) while(Lcd_Busy()); //判断lcd是否内部操作状态
95 DFD5 RCALL _Lcd_Busy
96 2300 TST R16
97 F7E9 BNE 0x0095
(0099) E_L;RS_H;RW_L; //E=0(致能),RS=1(数据),RW=0(写)
98 98AF CBI 0x15,7
99 9AAD SBI 0x15,5
9A 98AE CBI 0x15,6
(0100) delay_us(2); //液晶延时子程序
9B E002 LDI R16,2
9C E010 LDI R17,0
9D DFB6 RCALL _delay_us
(0101) E_H;
9E 9AAF SBI 0x15,7
(0102) PORTB = Data; //向lcd写入一个字符
9F BAA8 OUT 0x18,R10
(0103) delay_us(2); //液晶延时子程序
A0 E002 LDI R16,2
A1 E010 LDI R17,0
A2 DFB1 RCALL _delay_us
(0104) E_L;
A3 98AF CBI 0x15,7
A4 90A9 LD R10,Y+
A5 9508 RET
(0105) }
(0106)
(0107)
(0108) /*=======================================================
(0109) LCD第1行显示地址1~20(0x80~0x93)
(0110) LCD第2行显示地址1~20(0xc0~0xd3)
(0111) LCD第3行显示地址1~20(0x94~0xa7)
(0112) LCD第4行显示地址1~20(0xd4~0xe7)
(0113) =======================================================*/
(0114) //初始化LCD_8位接口,4行x20字符的工作方式
(0115) void Lcd_Init()
(0116) {
(0117) DDRB = 0xff; //端口B设为输出方式
_Lcd_Init:
A6 EF8F LDI R24,0xFF
A7 BB87 OUT 0x17,R24
(0118) DDRD = 0xff; //端口D设为输出方式
A8 BB81 OUT 0x11,R24
(0119) Lcd_Command(0x38); //
A9 E308 LDI R16,0x38
AA DFD5 RCALL _Lcd_Command
(0120) Lcd_Command(0x38); //
AB E308 LDI R16,0x38
AC DFD3 RCALL _Lcd_Command
(0121) Lcd_Command(0x38); //
AD E308 LDI R16,0x38
AE DFD1 RCALL _Lcd_Command
(0122) Lcd_Command(0x38); //
AF E308 LDI R16,0x38
B0 DFCF RCALL _Lcd_Command
(0123) Lcd_Command(0x08); //令显示器off
B1 E008 LDI R16,0x8
B2 DFCD RCALL _Lcd_Command
(0124) Lcd_Command(0x01); //清除显示器
B3 E001 LDI R16,1
B4 DFCB RCALL _Lcd_Command
(0125) Lcd_Command(0x06); //令LCD每接收到1Byte数据后,AC自动加1
B5 E006 LDI R16,6
B6 DFC9 RCALL _Lcd_Command
(0126) Lcd_Command(0x0C); //令光标,0x0c=不显示,0x0d=显示闪动.
B7 E00C LDI R16,0xC
B8 DFC7 RCALL _Lcd_Command
B9 9508 RET
_asc_tran:
asc --> R20
BA 934A ST R20,-Y
BB 935A ST R21,-Y
BC 01A8 MOVW R20,R16
(0127) }
(0128)
(0129) //=======================================================
(0130) //写ASCII字符串程序
(0131) void asc_tran(unsigned char *asc)
(0132) {
BD C005 RJMP 0x00C3
(0133) while((*asc) != 0) //判断字是否结束
(0134) {
(0135) Lcd_Write(*asc); //向lcd写入字符串
BE 01FA MOVW R30,R20
BF 8100 LDD R16,Z+0
C0 DFD2 RCALL _Lcd_Write
(0136) asc++; //移下一个字符
C1 5F4F SUBI R20,0xFF
C2 4F5F SBCI R21,0xFF
C3 01FA MOVW R30,R20
C4 8020 LDD R2,Z+0
C5 2022 TST R2
C6 F7B9 BNE 0x00BE
C7 9159 LD R21,Y+
C8 9149 LD R20,Y+
C9 9508 RET
(0137) }
(0138) }
(0139)
(0140) //=======================================================
(0141) //测试主LCD主程序
(0142) void main()
(0143) {
(0144) Lcd_Init(); //初始化LCD
_main:
CA DFDB RCALL _Lcd_Init
CB C01E RJMP 0x00EA
(0145) while(1)
(0146) {
(0147) Lcd_Command(0x83); //设置显示位址
CC E803 LDI R16,0x83
CD DFB2 RCALL _Lcd_Command
(0148) asc_tran("-----@_@------"); //显示字符串
CE E902 LDI R16,0x92
CF E010 LDI R17,0
D0 DFE9 RCALL _asc_tran
(0149) Lcd_Command(0x97); //设置显示位址
D1 E907 LDI R16,0x97
D2 DFAD RCALL _Lcd_Command
(0150) asc_tran("www.ouravr.com"); //显示字符串
D3 E803 LDI R16,0x83
D4 E010 LDI R17,0
D5 DFE4 RCALL _asc_tran
(0151) delay_ms(1000); //延迟1秒
D6 EE08 LDI R16,0xE8
D7 E013 LDI R17,3
D8 DF83 RCALL _delay_ms
(0152) Lcd_Command(0x01); //清除显示器
D9 E001 LDI R16,1
DA DFA5 RCALL _Lcd_Command
(0153)
(0154) Lcd_Command(0x83); //设置显示位址
DB E803 LDI R16,0x83
DC DFA3 RCALL _Lcd_Command
(0155) asc_tran("-----^_^------"); //显示字符串
DD E704 LDI R16,0x74
DE E010 LDI R17,0
DF DFDA RCALL _asc_tran
(0156) Lcd_Command(0x94); //设置显示位址
E0 E904 LDI R16,0x94
E1 DF9E RCALL _Lcd_Command
(0157) asc_tran("http://59.36.96.196"); //显示字符串
E2 E600 LDI R16,0x60
E3 E010 LDI R17,0
E4 DFD5 RCALL _asc_tran
(0158) delay_ms(1000); //延迟
E5 EE08 LDI R16,0xE8
E6 E013 LDI R17,3
E7 DF74 RCALL _delay_ms
(0159) Lcd_Command(0x01); //清除显示器
FILE: <library>
E8 E001 LDI R16,1
E9 DF96 RCALL _Lcd_Command
EA CFE1 RJMP 0x00CC
EB 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -