📄 lcd1602四线接口应用范例.lst
字号:
__start:
__text_start:
0043 E5CF LDI R28,0x5F
0044 E0D4 LDI R29,4
0045 BFCD OUT 0x3D,R28
0046 BFDE OUT 0x3E,R29
0047 51C0 SUBI R28,0x10
0048 40D0 SBCI R29,0
0049 EA0A LDI R16,0xAA
004A 8308 STD Y+0,R16
004B 2400 CLR R0
004C E6E3 LDI R30,0x63
004D E0F0 LDI R31,0
004E E010 LDI R17,0
004F 3AEE CPI R30,0xAE
0050 07F1 CPC R31,R17
0051 F011 BEQ 0x0054
0052 9201 ST R0,Z+
0053 CFFB RJMP 0x004F
0054 8300 STD Z+0,R16
0055 E8E3 LDI R30,0x83
0056 E0F0 LDI R31,0
0057 E6A0 LDI R26,0x60
0058 E0B0 LDI R27,0
0059 E010 LDI R17,0
005A 38E6 CPI R30,0x86
005B 07F1 CPC R31,R17
005C F021 BEQ 0x0061
005D 95C8 LPM
005E 9631 ADIW R30,1
005F 920D ST R0,X+
0060 CFF9 RJMP 0x005A
0061 D39C RCALL _main
_exit:
0062 CFFF RJMP _exit
FILE: E:\刻录的\电子技术\项目\驱动程序\LCD1602四线接口应用范例\LCD_1602_Driver.c
(0001) #include <iom8v.h>
(0002) #include <macros.h>
(0003) #include "LCD_1602.h"
(0004) void delay_nms(unsigned int n);
(0005) void delay_nus(unsigned int n);
(0006) unsigned char lcd_data[32];//32字节显存,记录LCD上显示的数据
(0007) unsigned char data[32];//32字节缓存,保存将要写入LCD的数据
(0008) unsigned char add;//显存地址标号
(0009) unsigned char new=32;//显存标号
(0010) unsigned int num=0;
(0011) /**********************************************************
(0012) TC1602B LCD DISPLAY
(0013) 建立时间:2005年12月12号
(0014) 修改日期:2005年12月12号
(0015) LCD_write函数功能:当command=0时,向LCD写入数据,否则向LCD写
(0016) 入命令
(0017) LCD第一行显示寄存器地址:0X80-0X8F
(0018) LCD第二行显示寄存器地址:0XC0-0XCF
(0019) **********************************************************/
(0020) void LCD_init(void)
(0021) {
(0022) LCD_EN_DDR|=LCD_EN;//设定该引脚方向为输出
_LCD_init:
0063 9A8E SBI 0x11,6
(0023) LCD_RS_DDR|=LCD_RS;//设定该引脚方向为输出
0064 9A8F SBI 0x11,7
(0024) LCD_D4_DDR|=LCD_D4;//设定数据口为输出
0065 9A8D SBI 0x11,5
(0025) LCD_D5_DDR|=LCD_D5;//设定数据口为输出
0066 9A8C SBI 0x11,4
(0026) LCD_D6_DDR|=LCD_D6;//设定数据口为输出
0067 9A8B SBI 0x11,3
(0027) LCD_D7_DDR|=LCD_D7;//设定数据口为输出
0068 9A8A SBI 0x11,2
(0028)
(0029) LCD_EN_PORT&=~LCD_EN;//EN设为低电平
0069 9896 CBI 0x12,6
(0030) LCD_RS_PORT&=~LCD_RS;//RS设为低电平
006A 9897 CBI 0x12,7
(0031) LCD_D4_PORT&=~LCD_D4;//数据口置低电平
006B 9895 CBI 0x12,5
(0032) LCD_D5_PORT&=~LCD_D5;//数据口置低电平
006C 9894 CBI 0x12,4
(0033) LCD_D6_PORT&=~LCD_D6;//数据口置低电平
006D 9893 CBI 0x12,3
(0034) LCD_D7_PORT&=~LCD_D7;//数据口置低电平
006E 9892 CBI 0x12,2
(0035)
(0036) LCD_write_char(0,0x33); //4bit test
006F E323 LDI R18,0x33
0070 E030 LDI R19,0
0071 2700 CLR R16
0072 2711 CLR R17
0073 D02E RCALL _LCD_write_char
(0037) delay_nms(25);
0074 E109 LDI R16,0x19
0075 E010 LDI R17,0
0076 D403 RCALL _delay_nms
(0038) LCD_write_char(0,0x32);
0077 E322 LDI R18,0x32
0078 E030 LDI R19,0
0079 2700 CLR R16
007A 2711 CLR R17
007B D026 RCALL _LCD_write_char
(0039) delay_nms(15);
007C E00F LDI R16,0xF
007D E010 LDI R17,0
007E D3FB RCALL _delay_nms
(0040) LCD_write_char(0,0x28);
007F E228 LDI R18,0x28
0080 E030 LDI R19,0
0081 2700 CLR R16
0082 2711 CLR R17
0083 D01E RCALL _LCD_write_char
(0041) delay_nms(15);
0084 E00F LDI R16,0xF
0085 E010 LDI R17,0
0086 D3F3 RCALL _delay_nms
(0042) LCD_write_char(0,0x0C); //显示开
0087 E02C LDI R18,0xC
0088 E030 LDI R19,0
0089 2700 CLR R16
008A 2711 CLR R17
008B D016 RCALL _LCD_write_char
(0043) delay_nms(15);
008C E00F LDI R16,0xF
008D E010 LDI R17,0
008E D3EB RCALL _delay_nms
(0044) LCD_write_char(0,0x01); //显示清屏
008F E021 LDI R18,1
0090 E030 LDI R19,0
0091 2700 CLR R16
0092 2711 CLR R17
0093 D00E RCALL _LCD_write_char
(0045) delay_nms(15);
0094 E00F LDI R16,0xF
0095 E010 LDI R17,0
0096 D3E3 RCALL _delay_nms
(0046) LCD_write_char(0,0x06); //显示光标移动设置
0097 E026 LDI R18,6
0098 E030 LDI R19,0
0099 2700 CLR R16
009A 2711 CLR R17
009B D006 RCALL _LCD_write_char
(0047) LCD_clear();
009C D068 RCALL _LCD_clear
(0048) delay_nms(10);
009D E00A LDI R16,0xA
009E E010 LDI R17,0
009F D3DA RCALL _delay_nms
(0049) LCD_init_CGRAM();
00A0 D32D RCALL _LCD_init_CGRAM
00A1 9508 RET
_LCD_write_char:
data --> R20
command --> R22
00A2 D4A0 RCALL push_gset2
00A3 01A9 MOVW R20,R18
00A4 01B8 MOVW R22,R16
(0050) }
(0051) /*-----------------------------------------------------------------------
(0052) LCD_write_char : 写一个字节到LCD的函数
(0053) 编写日期 :2005-12-12
(0054) 最后修改日期 :2005-12-12
(0055) -----------------------------------------------------------------------*/
(0056) void LCD_write_char(unsigned command,unsigned data)
(0057) {
(0058) if (command == 0)
00A5 3060 CPI R22,0
00A6 0767 CPC R22,R23
00A7 F411 BNE 0x00AA
(0059) LCD_RS_PORT &= ~LCD_RS; //RS=0 写地址
00A8 9897 CBI 0x12,7
00A9 C001 RJMP 0x00AB
(0060) else
(0061) LCD_RS_PORT |= LCD_RS; //RS=1 写数据
00AA 9A97 SBI 0x12,7
(0062)
(0063) LCD_write_DATA_PORT(data);//写高4位
00AB 2F04 MOV R16,R20
00AC D018 RCALL _LCD_write_DATA_PORT
(0064) LCD_write_DATA_PORT(data<<4);//写低4位
00AD 2F04 MOV R16,R20
00AE 0F00 LSL R16
00AF 1F11 ROL R17
00B0 0F00 LSL R16
00B1 1F11 ROL R17
00B2 0F00 LSL R16
00B3 1F11 ROL R17
00B4 0F00 LSL R16
00B5 1F11 ROL R17
00B6 D00E RCALL _LCD_write_DATA_PORT
(0065) delay_nus(250);
00B7 EF0A LDI R16,0xFA
00B8 E010 LDI R17,0
00B9 D3CD RCALL _delay_nus
(0066) num++;//统计向LCD发送的字节数
00BA 91800061 LDS R24,num
00BC 91900062 LDS R25,num+1
00BE 9601 ADIW R24,1
00BF 93900062 STS num+1,R25
00C1 93800061 STS num,R24
00C3 D475 RCALL pop_gset2
00C4 9508 RET
_LCD_write_DATA_PORT:
data --> R20
00C5 D47F RCALL push_gset1
00C6 2F40 MOV R20,R16
(0067) }
(0068) /*-----------------------------------------------------------------------
(0069) LCD_write_DATA_PORT : 写数据到LCD数据口函数
(0070)
(0071) 输入参数data :要写入的数据(仅高4位)
(0072) 编写日期 :2005-12-12
(0073) 最后修改日期 :2005-12-12
(0074) -----------------------------------------------------------------------*/
(0075) void LCD_write_DATA_PORT(unsigned char data)
(0076) {
(0077) if((data>>4)%2)
00C7 E012 LDI R17,2
00C8 2F04 MOV R16,R20
00C9 9502 SWAP R16
00CA 700F ANDI R16,0xF
00CB D455 RCALL mod8u
00CC 2300 TST R16
00CD F011 BEQ 0x00D0
(0078) LCD_D4_PORT |=LCD_D4;
00CE 9A95 SBI 0x12,5
00CF C001 RJMP 0x00D1
(0079) else
(0080) LCD_D4_PORT &=~LCD_D4;
00D0 9895 CBI 0x12,5
(0081)
(0082) if((data>>5)%2)
00D1 E012 LDI R17,2
00D2 2F04 MOV R16,R20
00D3 9506 LSR R16
00D4 9506 LSR R16
00D5 9506 LSR R16
00D6 9506 LSR R16
00D7 9506 LSR R16
00D8 D448 RCALL mod8u
00D9 2300 TST R16
00DA F011 BEQ 0x00DD
(0083) LCD_D5_PORT |=LCD_D5;
00DB 9A94 SBI 0x12,4
00DC C001 RJMP 0x00DE
(0084) else
(0085) LCD_D5_PORT &=~LCD_D5;
00DD 9894 CBI 0x12,4
(0086)
(0087) if((data>>6)%2)
00DE E012 LDI R17,2
00DF 2F04 MOV R16,R20
00E0 9506 LSR R16
00E1 9506 LSR R16
00E2 9506 LSR R16
00E3 9506 LSR R16
00E4 9506 LSR R16
00E5 9506 LSR R16
00E6 D43A RCALL mod8u
00E7 2300 TST R16
00E8 F011 BEQ 0x00EB
(0088) LCD_D6_PORT |=LCD_D6;
00E9 9A93 SBI 0x12,3
00EA C001 RJMP 0x00EC
(0089) else
(0090) LCD_D6_PORT &=~LCD_D6;
00EB 9893 CBI 0x12,3
(0091)
(0092) if((data>>7)%2)
00EC E012 LDI R17,2
00ED 2F04 MOV R16,R20
00EE 9506 LSR R16
00EF 9506 LSR R16
00F0 9506 LSR R16
00F1 9506 LSR R16
00F2 9506 LSR R16
00F3 9506 LSR R16
00F4 9506 LSR R16
00F5 D42B RCALL mod8u
00F6 2300 TST R16
00F7 F011 BEQ 0x00FA
(0093) LCD_D7_PORT |=LCD_D7;
00F8 9A92 SBI 0x12,2
00F9 C001 RJMP 0x00FB
(0094) else
(0095) LCD_D7_PORT &=~LCD_D7;
00FA 9892 CBI 0x12,2
(0096)
(0097) LCD_EN_PORT |= LCD_EN; //EN端产生一个由低电平变高电平,写LCD
00FB 9A96 SBI 0x12,6
(0098) delay_nus(25);
00FC E109 LDI R16,0x19
00FD E010 LDI R17,0
00FE D388 RCALL _delay_nus
(0099) LCD_EN_PORT &= ~LCD_EN; //EN端产生一个由高电平变低电平,写LCD
00FF 9896 CBI 0x12,6
(0100) delay_nus(25);
0100 E109 LDI R16,0x19
0101 E010 LDI R17,0
0102 D384 RCALL _delay_nus
0103 D444 RCALL pop_gset1
0104 9508 RET
_LCD_clear:
i --> R20
0105 D43F RCALL push_gset1
(0101) }
(0102) /*-----------------------------------------------------------------------
(0103) LCD_clear : 清除屏幕的函数
(0104)
(0105) 输入参数 :无
(0106) 编写日期 :2005/10/18
(0107) 说明 : lcd_data[]也会被清0
(0108) -----------------------------------------------------------------------*/
(0109) void LCD_clear(void)
(0110) {
(0111) unsigned char i;
(0112) LCD_write_char(0,0x01);//显示清屏
0106 E021 LDI R18,1
0107 E030 LDI R19,0
0108 2700 CLR R16
0109 2711 CLR R17
010A DF97 RCALL _LCD_write_char
(0113) for(i=0;i<32;i++)
010B 2744 CLR R20
010C C009 RJMP 0x0116
(0114) {
(0115) lcd_data[i]=0;
010D E884 LDI R24,0x84
010E E090 LDI R25,0
010F 2FE4 MOV R30,R20
0110 27FF CLR R31
0111 0FE8 ADD R30,R24
0112 1FF9 ADC R31,R25
0113 2422 CLR R2
0114 8220 STD Z+0,R2
0115 9543 INC R20
0116 3240 CPI R20,0x20
0117 F3A8 BCS 0x010D
(0116) }
(0117) delay_nus(500);
0118 EF04 LDI R16,0xF4
0119 E011 LDI R17,1
011A D36C RCALL _delay_nus
011B D42C RCALL pop_gset1
011C 9508 RET
_LCD_check:
lcd --> Y+0
i --> R20
y --> R22
x --> R20
011D D425 RCALL push_gset2
011E 2F62 MOV R22,R18
011F 2F40 MOV R20,R16
0120 9722 SBIW R28,2
(0118) }
(0119) /*-----------------------------------------------------------------------
(0120) LCD_check : 统计发送数据到LCD次数的函数
(0121)
(0122) 输入参数 :x,y 显示结果的座标
(0123) 编写日期 :2005/10/18
(0124) 说明 :如果每秒调用一次,就是统计每秒的次数
(0125) -----------------------------------------------------------------------*/
(0126) void LCD_check(unsigned char x,unsigned char y) //检测每秒钟写LCD
(0127) //次数的函数
(0128) {
(0129) unsigned char i;
(0130) unsigned char lcd[2]={0};
0121 E286 LDI R24,0x26
0122 E090 LDI R25,0
0123 01FE MOVW R30,R28
0124 E002 LDI R16,2
0125 E010 LDI R17,0
0126 93FA ST R31,-Y
0127 93EA ST R30,-Y
0128 939A ST R25,-Y
0129 938A ST R24,-Y
012A D431 RCALL asgncblk
(0131) add=y*16+x;//设置起始座标
012B E180 LDI R24,0x10
012C 9F86 MUL R24,R22
012D 2C20 MOV R2,R0
012E 0E24 ADD R2,R20
012F 92200063 STS add,R2
(0132) lcd[0]=num/10+48;
0131 E02A LDI R18,0xA
0132 E030 LDI R19,0
0133 91000061 LDS R16,num
0135 91100062 LDS R17,num+1
0137 D35E RCALL div16u
0138 01C8 MOVW R24,R16
0139 96C0 ADIW R24,0x30
013A 8388 STD Y+0,R24
(0133) lcd[1]=num%10+48;
013B E02A LDI R18,0xA
013C E030 LDI R19,0
013D 91000061 LDS R16,num
013F 91100062 LDS R17,num+1
0141 D352 RCALL mod16u
0142 01C8 MOVW R24,R16
0143 96C0 ADIW R24,0x30
0144 8389 STD Y+1,R24
(0134) num=0;
0145 2422 CLR R2
0146 2433 CLR R3
0147 92300062 STS num+1,R3
0149 92200061 STS num,R2
(0135) for (i=0;i<2;i++)
014B 2744 CLR R20
014C C025 RJMP 0x0172
(0136) {
(0137) if(lcd_data[add]==lcd[i]){}
014D 01CE MOVW R24,R28
014E 2FE4 MOV R30,R20
014F 27FF CLR R31
0150 0FE8 ADD R30,R24
0151 1FF9 ADC R31,R25
0152 8020 LDD R2,Z+0
0153 E884 LDI R24,0x84
0154 E090 LDI R25,0
0155 91E00063 LDS R30,add
0157 27FF CLR R31
0158 0FE8 ADD R30,R24
0159 1FF9 ADC R31,R25
015A 8030 LDD R3,Z+0
015B 1432 CP R3,R2
015C F409 BNE 0x015E
015D C00E RJMP 0x016C
(0138) else
(0139) {data[add]=lcd[i];}
015E 01CE MOVW R24,R28
015F 2FE4 MOV R30,R20
0160 27FF CLR R31
0161 0FE8 ADD R30,R24
0162 1FF9 ADC R31,R25
0163 8020 LDD R2,Z+0
0164 E684 LDI R24,0x64
0165 E090 LDI R25,0
0166 91E00063 LDS R30,add
0168 27FF CLR R31
0169 0FE8 ADD R30,R24
016A 1FF9 ADC R31,R25
016B 8220 STD Z+0,R2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -