📄 1602.lst
字号:
__start:
__text_start:
3A E5CF LDI R28,0x5F
3B E0D4 LDI R29,4
3C BFCD OUT 0x3D,R28
3D BFDE OUT 0x3E,R29
3E 51C0 SUBI R28,0x10
3F 40D0 SBCI R29,0
40 EA0A LDI R16,0xAA
41 8308 STD Y+0,R16
42 2400 CLR R0
43 E7E4 LDI R30,0x74
44 E0F0 LDI R31,0
45 E010 LDI R17,0
46 37EA CPI R30,0x7A
47 07F1 CPC R31,R17
48 F011 BEQ 0x004B
49 9201 ST R0,Z+
4A CFFB RJMP 0x0046
4B 8300 STD Z+0,R16
4C E5EF LDI R30,0x5F
4D E0F0 LDI R31,0
4E E6A0 LDI R26,0x60
4F E0B0 LDI R27,0
50 E010 LDI R17,0
51 E000 LDI R16,0
52 BF0B OUT 0x3B,R16
53 37E3 CPI R30,0x73
54 07F1 CPC R31,R17
55 F021 BEQ 0x005A
56 95C8 LPM
57 9631 ADIW R30,1
58 920D ST R0,X+
59 CFF9 RJMP 0x0053
5A 940E 0201 CALL _main
_exit:
5C CFFF RJMP _exit
_WriteDataLCM:
WDLCM --> R10
5D 92AA ST R10,-Y
5E 2EA0 MOV R10,R16
FILE: D:\学习工具\单片机程序\1602液晶\1602.c
(0001) //把明浩的1602的程序移植到了ATMEGA8上,共享一下。
(0002) /*============================================================
(0003) 使用1602液晶显示的实验例子 明浩 2004/2/27
(0004) ==============================================================
(0005)
(0006) SMC1602A(16*2)模拟口线接线方式
(0007) 连接线图:
(0008) ---------------------------------------------------
(0009) |LCM-----51 | LCM-----51 | LCM------51 |
(0010) --------------------------------------------------|
(0011) |DB0-----P1.0 | DB4-----P1.4 | RW-------P2.0 |
(0012) |DB1-----P1.1 | DB5-----P1.5 | RS-------P2.1 |
(0013) |DB2-----P1.2 | DB6-----P1.6 | E--------P2.2 |
(0014) |DB3-----P1.3 | DB7-----P1.7 | VLCD接1K电阻到GND|
(0015) ---------------------------------------------------
(0016)
(0017) SMC1602A(16*2)模拟口线接线方式
(0018) 连接线图:
(0019) ---------------------------------------------------
(0020) |LCM-----M8 | LCM-----M8 | LCM------M8 |
(0021) ----------------------------------------------|
(0022) |DB0-----PB0 | DB4-----PB4 | RW-------PD6 |
(0023) |DB1-----PB1 | DB5-----PB5 | RS-------PD7 |
(0024) |DB2-----PB2 | DB6-----PB6 | E--------PD5 |
(0025) |DB3-----PB3 | DB7-----PB7 | VLCD接1K电阻到GND|
(0026) ---------------------------------------------------
(0027) ==============================================================*/
(0028) #include <iom16V.h>
(0029) #include <macros.h>
(0030)
(0031) #define CTLPORT PORTD //模拟总线用了PD口的PD5,PD6,PD7
(0032) #define LCD_RS 5 // pin-0 on CTLPORT
(0033) #define LCD_RW 6 // pin-1 on CTLPORT
(0034) #define LCD_E 7 // pin-2 on CTLPORT
(0035)
(0036) #define SET_LCD_E CTLPORT|=(1<<LCD_E) // LCD: E = 1
(0037) #define CLR_LCD_E CTLPORT&=~(1<<LCD_E) // LCD: E = 0
(0038) #define SET_LCD_RW CTLPORT|=(1<<LCD_RW) // LCD: R/W = 1 (read)
(0039) #define CLR_LCD_RW CTLPORT&=~(1<<LCD_RW) // LCD: R/W = 0 (write)
(0040) #define SET_LCD_RS CTLPORT|=(1<<LCD_RS) // LCD: R/S = 1 (data reg)
(0041) #define CLR_LCD_RS CTLPORT&=~(1<<LCD_RS) // LCD: R/S = 0 (status reg)
(0042)
(0043) //#define DataPortOUT PORTB // 数据端口PB口
(0044) //#define DataPortIN PINB
(0045) #define DataPortfx DDRB
(0046) #define Busy 0x80
(0047) #define LCM_Data PORTB // 数据端口PB口
(0048) #define LCM_Data1 PINB // 数据端口PB口
(0049)
(0050) #pragma data:code
(0051) unsigned char const table_1[] = {"1515484166"};
(0052) //unsigned char table_2[] = {'0','0','-','0','0','-','0','0'};
(0053) #pragma data:data
(0054) unsigned char table_2[] = {'0','0','-','0','0','-','0','0'};
(0055) void WriteDataLCM(unsigned char WDLCM);
(0056) void WriteCommandLCM(unsigned char WCLCM,unsigned char BuysC);
(0057) unsigned char ReadDataLCM(void);
(0058) unsigned char ReadStatusLCM(void);
(0059) void LCMInit(void);
(0060) void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
(0061) void DisplayListChar(unsigned char X, unsigned char Y, unsigned char const *DData);
(0062) void Delay5Ms(void);
(0063) void Delay400Ms(void);
(0064)
(0065)
(0066)
(0067)
(0068)
(0069) //写数据
(0070) void WriteDataLCM(unsigned char WDLCM)
(0071) {
(0072) ReadStatusLCM(); //检测忙
5F D031 RCALL _ReadStatusLCM
(0073) LCM_Data = WDLCM;
60 BAA8 OUT 0x18,R10
(0074) SET_LCD_RS;
61 9A95 SBI 0x12,5
(0075) CLR_LCD_RW;
62 9896 CBI 0x12,6
(0076) SET_LCD_RS;
63 9A95 SBI 0x12,5
(0077) CLR_LCD_RW;
64 9896 CBI 0x12,6
(0078) CLR_LCD_E; //若晶振速度太高可以在这后加小的延时
65 9897 CBI 0x12,7
(0079) CLR_LCD_E; //延时
66 9897 CBI 0x12,7
(0080) CLR_LCD_E;
67 9897 CBI 0x12,7
(0081) CLR_LCD_E;
68 9897 CBI 0x12,7
(0082) CLR_LCD_E;
69 9897 CBI 0x12,7
(0083) CLR_LCD_E;
6A 9897 CBI 0x12,7
(0084) SET_LCD_E;
6B 9A97 SBI 0x12,7
(0085) SET_LCD_E;
6C 9A97 SBI 0x12,7
6D 90A9 LD R10,Y+
6E 9508 RET
_WriteCommandLCM:
BuysC --> R12
WCLCM --> R10
6F 92AA ST R10,-Y
70 92CA ST R12,-Y
71 2EC2 MOV R12,R18
72 2EA0 MOV R10,R16
(0086) }
(0087)
(0088) //写指令
(0089) void WriteCommandLCM(unsigned char WCLCM,unsigned char BuysC) //BuysC为0时忽略忙检测
(0090) {
(0091) if (BuysC) ReadStatusLCM(); //根据需要检测忙
73 20CC TST R12
74 F009 BEQ 0x0076
75 D01B RCALL _ReadStatusLCM
(0092) LCM_Data = WCLCM;
76 BAA8 OUT 0x18,R10
(0093) CLR_LCD_RS;
77 9895 CBI 0x12,5
(0094) CLR_LCD_RW;
78 9896 CBI 0x12,6
(0095) CLR_LCD_E;
79 9897 CBI 0x12,7
(0096) CLR_LCD_E;
7A 9897 CBI 0x12,7
(0097) CLR_LCD_E;
7B 9897 CBI 0x12,7
(0098) CLR_LCD_E;
7C 9897 CBI 0x12,7
(0099) CLR_LCD_E;
7D 9897 CBI 0x12,7
(0100) CLR_LCD_E;
7E 9897 CBI 0x12,7
(0101) SET_LCD_E;
7F 9A97 SBI 0x12,7
(0102) SET_LCD_E;
80 9A97 SBI 0x12,7
81 90C9 LD R12,Y+
82 90A9 LD R10,Y+
83 9508 RET
(0103) }
(0104)
(0105) //读数据
(0106) unsigned char ReadDataLCM(void)
(0107) {
(0108) SET_LCD_RS;
_ReadDataLCM:
84 9A95 SBI 0x12,5
(0109) SET_LCD_RW;
85 9A96 SBI 0x12,6
(0110) CLR_LCD_E;
86 9897 CBI 0x12,7
(0111) CLR_LCD_E;
87 9897 CBI 0x12,7
(0112) CLR_LCD_E;
88 9897 CBI 0x12,7
(0113) CLR_LCD_E;
89 9897 CBI 0x12,7
(0114) CLR_LCD_E;
8A 9897 CBI 0x12,7
(0115) CLR_LCD_E;
8B 9897 CBI 0x12,7
(0116) CLR_LCD_E;
8C 9897 CBI 0x12,7
(0117) SET_LCD_E;
8D 9A97 SBI 0x12,7
(0118) SET_LCD_E;
8E 9A97 SBI 0x12,7
(0119) return(LCM_Data);
8F B308 IN R16,0x18
90 9508 RET
(0120) }
(0121)
(0122) //读状态
(0123) unsigned char ReadStatusLCM(void)
(0124) {
(0125) DDRB=0x00; //输入
_ReadStatusLCM:
91 2422 CLR R2
92 BA27 OUT 0x17,R2
(0126) CLR_LCD_RS;
93 9895 CBI 0x12,5
(0127) SET_LCD_RW;
94 9A96 SBI 0x12,6
(0128) CLR_LCD_E;
95 9897 CBI 0x12,7
(0129) CLR_LCD_E;
96 9897 CBI 0x12,7
(0130) CLR_LCD_E;
97 9897 CBI 0x12,7
(0131) CLR_LCD_E;
98 9897 CBI 0x12,7
(0132) SET_LCD_E;
99 9A97 SBI 0x12,7
(0133) while (LCM_Data1 & Busy); //检测忙信号
9A 99B7 SBIC 0x16,7
9B CFFE RJMP 0x009A
(0134) DDRB=0xff;//变回输出
9C EF8F LDI R24,0xFF
9D BB87 OUT 0x17,R24
(0135) return(LCM_Data1);
9E B306 IN R16,0x16
9F 9508 RET
(0136) }
(0137)
(0138) void LCMInit(void) //LCM初始化
(0139) {
(0140) LCM_Data = 0;
_LCMInit:
A0 2422 CLR R2
A1 BA28 OUT 0x18,R2
(0141) WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
A2 2722 CLR R18
A3 E308 LDI R16,0x38
A4 DFCA RCALL _WriteCommandLCM
(0142) Delay5Ms();
A5 D051 RCALL _Delay5Ms
(0143) WriteCommandLCM(0x38,0);
A6 2722 CLR R18
A7 E308 LDI R16,0x38
A8 DFC6 RCALL _WriteCommandLCM
(0144) Delay5Ms();
A9 D04D RCALL _Delay5Ms
(0145) WriteCommandLCM(0x38,0);
AA 2722 CLR R18
AB E308 LDI R16,0x38
AC DFC2 RCALL _WriteCommandLCM
(0146) Delay5Ms();
AD D049 RCALL _Delay5Ms
(0147)
(0148) WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
AE E021 LDI R18,1
AF E308 LDI R16,0x38
B0 DFBE RCALL _WriteCommandLCM
(0149) WriteCommandLCM(0x08,1); //关闭显示
B1 E021 LDI R18,1
B2 E008 LDI R16,0x8
B3 DFBB RCALL _WriteCommandLCM
(0150) WriteCommandLCM(0x01,1); //显示清屏
B4 E021 LDI R18,1
B5 E001 LDI R16,1
B6 DFB8 RCALL _WriteCommandLCM
(0151) WriteCommandLCM(0x06,1); // 显示光标移动设置
B7 E021 LDI R18,1
B8 E006 LDI R16,6
B9 DFB5 RCALL _WriteCommandLCM
(0152) WriteCommandLCM(0x0C,1); // 显示开及光标设置
BA E021 LDI R18,1
BB E00C LDI R16,0xC
BC DFB2 RCALL _WriteCommandLCM
BD 9508 RET
_DisplayOneChar:
DData --> Y,+2
Y --> R22
X --> R20
BE 934A ST R20,-Y
BF 936A ST R22,-Y
C0 2F62 MOV R22,R18
C1 2F40 MOV R20,R16
(0153) }
(0154)
(0155) //按指定位置显示一个字符
(0156) void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
(0157) {
(0158) Y &= 0x1;
C2 7061 ANDI R22,1
(0159) X &= 0xF; //限制X不能大于15,Y不能大于1
C3 704F ANDI R20,0xF
(0160) if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
C4 2366 TST R22
C5 F009 BEQ 0x00C7
C6 6440 ORI R20,0x40
(0161) X |= 0x80; //算出指令码
C7 6840 ORI R20,0x80
(0162) WriteCommandLCM(X, 1); //这里不检测忙信号,发送地址码
C8 E021 LDI R18,1
C9 2F04 MOV R16,R20
CA DFA4 RCALL _WriteCommandLCM
(0163) WriteDataLCM(DData);
CB 810A LDD R16,Y+2
CC DF90 RCALL _WriteDataLCM
(0164) WriteCommandLCM(X, 0); //光标返回,调节时很重要
CD 2722 CLR R18
CE 2F04 MOV R16,R20
CF DF9F RCALL _WriteCommandLCM
D0 9169 LD R22,Y+
D1 9149 LD R20,Y+
D2 9508 RET
_DisplayListChar:
ListLength --> R10
DData --> R12
Y --> R22
X --> R20
D3 940E 024D CALL push_xgsetF03C
D5 2F62 MOV R22,R18
D6 2F40 MOV R20,R16
D7 9721 SBIW R28,1
D8 84C9 LDD R12,Y+9
D9 84DA LDD R13,Y+10
(0165) }
(0166)
(0167) //按指定位置显示一串字符
(0168) void DisplayListChar(unsigned char X, unsigned char Y, unsigned char const *DData)
(0169) {
(0170) unsigned char ListLength;
(0171)
(0172) ListLength = 0;
DA 24AA CLR R10
(0173) Y &= 0x1;
DB 7061 ANDI R22,1
(0174) X &= 0xF; //限制X不能大于15,Y不能大于1
DC 704F ANDI R20,0xF
DD C00E RJMP 0x00EC
(0175) while (DData[ListLength]>0x20) //若到达字串尾则退出
(0176) {
(0177) if (X <= 0xF) //X坐标应小于0xF
DE E08F LDI R24,0xF
DF 1784 CP R24,R20
E0 F058 BCS 0x00EC
(0178) {
(0179) DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
E1 2DEA MOV R30,R10
E2 27FF CLR R31
E3 0DEC ADD R30,R12
E4 1DFD ADC R31,R13
E5 9024 LPM R2,11(Z)
E6 8228 STD Y+0,R2
E7 2F26 MOV R18,R22
E8 2F04 MOV R16,R20
E9 DFD4 RCALL _DisplayOneChar
(0180) ListLength++;
EA 94A3 INC R10
(0181) X++;
EB 9543 INC R20
EC 2DEA MOV R30,R10
ED 27FF CLR R31
EE 0DEC ADD R30,R12
EF 1DFD ADC R31,R13
F0 9024 LPM R2,-44(Z)
F1 E280 LDI R24,0x20
F2 1582 CP R24,R2
F3 F350 BCS 0x00DE
F4 9621 ADIW R28,1
F5 940C 0256 JMP pop_xgsetF03C
(0182) }
(0183) }
(0184) }
(0185)
(0186) //5ms延时
(0187) void Delay5Ms(void)
(0188) {
(0189) unsigned int TempCyc = 5552;
_Delay5Ms:
TempCyc --> R16
F7 EB00 LDI R16,0xB0
F8 E115 LDI R17,0x15
(0190) while(TempCyc--);
F9 0118 MOVW R2,R16
FA 5001 SUBI R16,1
FB 4010 SBCI R17,0
FC 2022 TST R2
FD F7D9 BNE 0x00F9
FE 2033 TST R3
FF F7C9 BNE 0x00F9
100 9508 RET
(0191) }
(0192)
(0193) //400ms延时
(0194) void Delay400Ms(void)
(0195) {
(0196) unsigned char TempCycA = 9;
_Delay400Ms:
TempCycA --> R16
TempCycB --> R18
101 E009 LDI R16,0x9
102 C009 RJMP 0x010C
(0197) unsigned int TempCycB;
(0198) while(TempCycA--)
(0199) {
(0200) TempCycB=7777;
103 E621 LDI R18,0x61
104 E13E LDI R19,0x1E
(0201) while(TempCycB--);
105 0119 MOVW R2,R18
106 5021 SUBI R18,1
107 4030 SBCI R19,0
108 2022 TST R2
109 F7D9 BNE 0x0105
10A 2033 TST R3
10B F7C9 BNE 0x0105
10C 2E20 MOV R2,R16
10D 2433 CLR R3
10E 5001 SUBI R16,1
10F 2022 TST R2
110 F791 BNE 0x0103
(0202) };
111 9508 RET
(0203) }
(0204)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -