📄 lcd.lst
字号:
__start:
__text_start:
0033 E5CF LDI R28,0x5F
0034 E0D4 LDI R29,4
0035 BFCD OUT 0x3D,R28
0036 BFDE OUT 0x3E,R29
0037 51C0 SUBI R28,0x10
0038 40D0 SBCI R29,0
0039 EA0A LDI R16,0xAA
003A 8308 STD Y+0,R16
003B 2400 CLR R0
003C E7E1 LDI R30,0x71
003D E0F0 LDI R31,0
003E E010 LDI R17,0
003F 37E1 CPI R30,0x71
0040 07F1 CPC R31,R17
0041 F011 BEQ 0x0044
0042 9201 ST R0,Z+
0043 CFFB RJMP 0x003F
0044 8300 STD Z+0,R16
0045 E5E4 LDI R30,0x54
0046 E0F0 LDI R31,0
0047 E6A0 LDI R26,0x60
0048 E0B0 LDI R27,0
0049 E010 LDI R17,0
004A 36E5 CPI R30,0x65
004B 07F1 CPC R31,R17
004C F021 BEQ 0x0051
004D 95C8 LPM
004E 9631 ADIW R30,1
004F 920D ST R0,X+
0050 CFF9 RJMP 0x004A
0051 940E00FF CALL _main
_exit:
0053 CFFF RJMP _exit
_delay:
i --> R20
n --> R16
0054 940E0125 CALL push_gset1
FILE: F:\单片机源程序\AVR单片机程序\MAGE16\lcd1602\lcd.c
(0001) //编译器:ICC-AVR
(0002) //日期: 2007-4-13 20:29:57
(0003) //目标芯片 : ATmega16
(0004) //时钟: 8.0000Mhz
(0005) //版本:VISION 2.0
(0006) /*
(0007) LCD引脚定义
(0008) 1---GND
(0009) 2---VCC
(0010) 3---VO
(0011) 4---RS
(0012) 5---RW
(0013) 6---EN
(0014) 7到14--D0-D7
(0015) 15--背景灯+
(0016) 16--背景灯-
(0017)
(0018) 下面是AVR与LCD连接信息
(0019) PA1 ->RS
(0020) PA0 ->EN
(0021) GND ->RW
(0022) PA4 ->D4
(0023) PA5 ->D5
(0024) PA6 ->D6
(0025) PA7 ->D7
(0026) */
(0027)
(0028) #include <iom16v.h>
(0029) #include <macros.h>
(0030)
(0031) #define LCD_EN_PORT PORTA //数据寄存器,以下2个要设为同一个口
(0032) #define LCD_EN_DDR DDRA //数据方向寄存器
(0033) #define LCD_RS_PORT PORTA //以下2个要设为同一个口
(0034) #define LCD_RS_DDR DDRA
(0035) #define LCD_DATA_PORT PORTA //以下3个要设为同一个口
(0036) #define LCD_DATA_DDR DDRA //一定要用高4位
(0037) #define LCD_DATA_PIN PINA //端口输入引脚
(0038) #define LCD_RS (1<<PA1) //0x04 portA1 out
(0039) #define LCD_EN (1<<PA0) //0x08 portA0 out
(0040) #define LCD_DATA ((1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7)) //0xf0 portA4/5/6/7 out
(0041)
(0042) #define uchar unsigned char
(0043) #define uint unsigned int
(0044)
(0045) void LCD_init(void);
(0046) void LCD_en_write(void);
(0047) void LCD_write_command(uchar command) ;
(0048) void LCD_write_data(uchar data);
(0049) void LCD_set_xy (uchar x, uchar y);
(0050) void LCD_write_string(uchar X,uchar Y,uchar *s);
(0051) void LCD_write_char(uchar X,uchar Y,uchar data);
(0052) void delay(uint n);
(0053)
(0054) void delay(uint n) //N ms延时函数
(0055) {
0056 C009 RJMP 0x0060
(0056) uint i;
(0057) while(n--)
(0058) for (i=0;i<125;i++);
0057 2744 CLR R20
0058 2755 CLR R21
0059 C002 RJMP 0x005C
005A 5F4F SUBI R20,0xFF
005B 4F5F SBCI R21,0xFF
005C 374D CPI R20,0x7D
005D E0E0 LDI R30,0
005E 075E CPC R21,R30
005F F3D0 BCS 0x005A
0060 0118 MOVW R2,R16
0061 5001 SUBI R16,1
0062 4010 SBCI R17,0
0063 2022 TST R2
0064 F791 BNE 0x0057
0065 2033 TST R3
0066 F781 BNE 0x0057
0067 940E0128 CALL pop_gset1
0069 9508 RET
(0059) }
(0060)
(0061) void LCD_init(void) //液晶初始化
(0062) {
(0063) LCD_DATA_DDR|=LCD_DATA; //数据口方向为输出
_LCD_init:
006A B38A IN R24,0x1A
006B 6F80 ORI R24,0xF0
006C BB8A OUT 0x1A,R24
(0064) LCD_EN_DDR|=LCD_EN; //设置EN方向为输出
006D 9AD0 SBI 0x1A,0
(0065) LCD_RS_DDR|=LCD_RS; //设置RS方向为输出
006E 9AD1 SBI 0x1A,1
(0066) LCD_write_command(0x28);
006F E208 LDI R16,0x28
0070 D014 RCALL _LCD_write_command
(0067) LCD_en_write();
0071 D00D RCALL _LCD_en_write
(0068) delay(40);
0072 E208 LDI R16,0x28
0073 E010 LDI R17,0
0074 DFDF RCALL _delay
(0069) LCD_write_command(0x28); //4位显示
0075 E208 LDI R16,0x28
0076 D00E RCALL _LCD_write_command
(0070) LCD_write_command(0x0c); //显示开
0077 E00C LDI R16,0xC
0078 D00C RCALL _LCD_write_command
(0071) LCD_write_command(0x01); //清屏
0079 E001 LDI R16,1
007A D00A RCALL _LCD_write_command
(0072) delay(2);
007B E002 LDI R16,2
007C E010 LDI R17,0
007D DFD6 RCALL _delay
007E 9508 RET
(0073) }
(0074)
(0075) void LCD_en_write(void) //液晶使能
(0076) {
(0077) LCD_EN_PORT|=LCD_EN;
_LCD_en_write:
007F 9AD8 SBI 0x1B,0
(0078) delay(1);
0080 E001 LDI R16,1
0081 E010 LDI R17,0
0082 DFD1 RCALL _delay
(0079) LCD_EN_PORT&=~LCD_EN;
0083 98D8 CBI 0x1B,0
0084 9508 RET
_LCD_write_command:
command --> R20
0085 940E0125 CALL push_gset1
0087 2F40 MOV R20,R16
(0080) }
(0081)
(0082) void LCD_write_command(uchar command) //写指令
(0083) {
(0084) delay(16);
0088 E100 LDI R16,0x10
0089 E010 LDI R17,0
008A DFC9 RCALL _delay
(0085) LCD_RS_PORT&=~LCD_RS; //RS=0
008B 98D9 CBI 0x1B,1
(0086) LCD_DATA_PORT&=0X0f; //清高四位
008C B38B IN R24,0x1B
008D 708F ANDI R24,0xF
008E BB8B OUT 0x1B,R24
(0087) LCD_DATA_PORT|=command&0xf0; //写高四位
008F 2F84 MOV R24,R20
0090 7F80 ANDI R24,0xF0
0091 B22B IN R2,0x1B
0092 2A28 OR R2,R24
0093 BA2B OUT 0x1B,R2
(0088) LCD_en_write();
0094 DFEA RCALL _LCD_en_write
(0089) command=command<<4; //低四位移到高四位
0095 2F84 MOV R24,R20
0096 708F ANDI R24,0xF
0097 9582 SWAP R24
0098 2F48 MOV R20,R24
(0090) LCD_DATA_PORT&=0x0f; //清高四位
0099 B38B IN R24,0x1B
009A 708F ANDI R24,0xF
009B BB8B OUT 0x1B,R24
(0091) LCD_DATA_PORT|=command&0xf0; //写低四位
009C 2F84 MOV R24,R20
009D 7F80 ANDI R24,0xF0
009E B22B IN R2,0x1B
009F 2A28 OR R2,R24
00A0 BA2B OUT 0x1B,R2
(0092) LCD_en_write();
00A1 DFDD RCALL _LCD_en_write
00A2 940E0128 CALL pop_gset1
00A4 9508 RET
_LCD_write_data:
data --> R20
00A5 940E0125 CALL push_gset1
00A7 2F40 MOV R20,R16
(0093)
(0094) }
(0095)
(0096) void LCD_write_data(uchar data) //写数据
(0097) {
(0098) delay(16);
00A8 E100 LDI R16,0x10
00A9 E010 LDI R17,0
00AA DFA9 RCALL _delay
(0099) LCD_RS_PORT|=LCD_RS; //RS=1
00AB 9AD9 SBI 0x1B,1
(0100) LCD_DATA_PORT&=0X0f; //清高四位
00AC B38B IN R24,0x1B
00AD 708F ANDI R24,0xF
00AE BB8B OUT 0x1B,R24
(0101) LCD_DATA_PORT|=data&0xf0; //写高四位
00AF 2F84 MOV R24,R20
00B0 7F80 ANDI R24,0xF0
00B1 B22B IN R2,0x1B
00B2 2A28 OR R2,R24
00B3 BA2B OUT 0x1B,R2
(0102) LCD_en_write();
00B4 DFCA RCALL _LCD_en_write
(0103) data=data<<4; //低四位移到高四位
00B5 2F84 MOV R24,R20
00B6 708F ANDI R24,0xF
00B7 9582 SWAP R24
00B8 2F48 MOV R20,R24
(0104) LCD_DATA_PORT&=0X0f; //清高四位
00B9 B38B IN R24,0x1B
00BA 708F ANDI R24,0xF
00BB BB8B OUT 0x1B,R24
(0105) LCD_DATA_PORT|=data&0xf0; //写低四位
00BC 2F84 MOV R24,R20
00BD 7F80 ANDI R24,0xF0
00BE B22B IN R2,0x1B
00BF 2A28 OR R2,R24
00C0 BA2B OUT 0x1B,R2
(0106) LCD_en_write();
00C1 DFBD RCALL _LCD_en_write
00C2 940E0128 CALL pop_gset1
00C4 9508 RET
_LCD_set_xy:
address --> R20
y --> R20
x --> R22
00C5 940E0123 CALL push_gset2
00C7 2F42 MOV R20,R18
00C8 2F60 MOV R22,R16
(0107) }
(0108)
(0109)
(0110) void LCD_set_xy( uchar x, uchar y ) //写地址函数
(0111) {
(0112) uchar address;
(0113) if (y == 0) address = 0x80 + x;
00C9 2344 TST R20
00CA F419 BNE 0x00CE
00CB 2F46 MOV R20,R22
00CC 5840 SUBI R20,0x80
00CD C002 RJMP 0x00D0
(0114) else address = 0xc0 + x;
00CE 2F46 MOV R20,R22
00CF 5440 SUBI R20,0x40
(0115) LCD_write_command( address);
00D0 2F04 MOV R16,R20
00D1 DFB3 RCALL _LCD_write_command
00D2 940E0117 CALL pop_gset2
00D4 9508 RET
_LCD_write_string:
s --> R20
Y --> R10
X --> R22
00D5 940E0121 CALL push_gset3
00D7 2EA2 MOV R10,R18
00D8 2F60 MOV R22,R16
00D9 814E LDD R20,Y+6
00DA 815F LDD R21,Y+7
(0116) }
(0117)
(0118) void LCD_write_string(uchar X,uchar Y,uchar *s) //列x=0~15,行y=0,1
(0119) {
(0120) LCD_set_xy( X, Y ); //写地址
00DB 2D2A MOV R18,R10
00DC 2F06 MOV R16,R22
00DD DFE7 RCALL _LCD_set_xy
00DE C005 RJMP 0x00E4
(0121) while (*s) // 写显示字符
(0122) {
(0123) LCD_write_data( *s );
00DF 01FA MOVW R30,R20
00E0 8100 LDD R16,Z+0
00E1 DFC3 RCALL _LCD_write_data
(0124) s ++;
00E2 5F4F SUBI R20,0xFF
00E3 4F5F SBCI R21,0xFF
00E4 01FA MOVW R30,R20
00E5 8020 LDD R2,Z+0
00E6 2022 TST R2
00E7 F7B9 BNE 0x00DF
00E8 940E011A CALL pop_gset3
00EA 9508 RET
_LCD_write_char:
data --> Y+4
Y --> R22
X --> R20
00EB 940E0123 CALL push_gset2
00ED 2F62 MOV R22,R18
00EE 2F40 MOV R20,R16
(0125) }
(0126)
(0127) }
(0128)
(0129) void LCD_write_char(uchar X,uchar Y,uchar data) //列x=0~15,行y=0,1
(0130) {
(0131) LCD_set_xy( X, Y ); //写地址
00EF 2F26 MOV R18,R22
00F0 2F04 MOV R16,R20
00F1 DFD3 RCALL _LCD_set_xy
(0132) LCD_write_data( data);
00F2 810C LDD R16,Y+4
00F3 DFB1 RCALL _LCD_write_data
00F4 940E0117 CALL pop_gset2
00F6 9508 RET
(0133)
(0134) }
(0135)
(0136) void init_devices(void)
(0137) {
(0138) CLI(); //disable all interrupts
_init_devices:
00F7 94F8 BCLR 7
(0139) LCD_init();
00F8 DF71 RCALL _LCD_init
(0140) MCUCR = 0x00;
00F9 2422 CLR R2
00FA BE25 OUT 0x35,R2
(0141) GICR = 0x00;
00FB BE2B OUT 0x3B,R2
(0142) TIMSK = 0x00; // r interrupt sources
00FC BE29 OUT 0x39,R2
(0143) SEI(); //re-enable interrupts
00FD 9478 BSET 7
00FE 9508 RET
_main:
00FF 9722 SBIW R28,2
(0144) }
(0145)
(0146)
(0147) void main(void)
(0148) {
(0149) init_devices();
0100 DFF6 RCALL _init_devices
(0150) LCD_write_string(0,0,"MCU IS:");
0101 E689 LDI R24,0x69
0102 E090 LDI R25,0
0103 8399 STD Y+1,R25
0104 8388 STD Y+0,R24
0105 2722 CLR R18
0106 2700 CLR R16
0107 DFCD RCALL _LCD_write_string
(0151) for(;;)
(0152) {
(0153) LCD_write_string(0,1,"ATmega16");
0108 E680 LDI R24,0x60
0109 E090 LDI R25,0
010A 8399 STD Y+1,R25
010B 8388 STD Y+0,R24
010C E021 LDI R18,1
010D 2700 CLR R16
010E DFC6 RCALL _LCD_write_string
(0154) LCD_write_char(7,0,'');
FILE: <library>
010F 2422 CLR R2
0110 8228 STD Y+0,R2
0111 2722 CLR R18
0112 E007 LDI R16,7
0113 DFD7 RCALL _LCD_write_char
0114 CFF3 RJMP 0x0108
0115 9622 ADIW R28,2
0116 9508 RET
pop_gset2:
0117 E0E2 LDI R30,2
0118 940C0129 JMP pop
pop_gset3:
011A E0E4 LDI R30,4
011B 940C0129 JMP pop
push_gset5:
011D 92FA ST R15,-Y
011E 92EA ST R14,-Y
push_gset4:
011F 92DA ST R13,-Y
0120 92CA ST R12,-Y
push_gset3:
0121 92BA ST R11,-Y
0122 92AA ST R10,-Y
push_gset2:
0123 937A ST R23,-Y
0124 936A ST R22,-Y
push_gset1:
0125 935A ST R21,-Y
0126 934A ST R20,-Y
0127 9508 RET
pop_gset1:
0128 E0E1 LDI R30,1
pop:
0129 9149 LD R20,Y+
012A 9159 LD R21,Y+
012B FDE0 SBRC R30,0
012C 9508 RET
012D 9169 LD R22,Y+
012E 9179 LD R23,Y+
012F FDE1 SBRC R30,1
0130 9508 RET
0131 90A9 LD R10,Y+
0132 90B9 LD R11,Y+
0133 FDE2 SBRC R30,2
0134 9508 RET
0135 90C9 LD R12,Y+
0136 90D9 LD R13,Y+
0137 FDE3 SBRC R30,3
0138 9508 RET
0139 90E9 LD R14,Y+
013A 90F9 LD R15,Y+
013B 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -