📄 1602lcd.lst
字号:
__text_start:
__start:
003A E5CF LDI R28,0x5F
003B E0D4 LDI R29,4
003C BFCD OUT 0x3D,R28
003D BFDE OUT 0x3E,R29
003E 51C0 SUBI R28,0x10
003F 40D0 SBCI R29,0
0040 EA0A LDI R16,0xAA
0041 8308 STD Y+0,R16
0042 2400 CLR R0
0043 E6E0 LDI R30,0x60
0044 E0F0 LDI R31,0
0045 E010 LDI R17,0
0046 36E0 CPI R30,0x60
0047 07F1 CPC R31,R17
0048 F011 BEQ 0x004B
0049 9201 ST R0,Z+
004A CFFB RJMP 0x0046
004B 8300 STD Z+0,R16
004C E7E4 LDI R30,0x74
004D E0F0 LDI R31,0
004E E6A0 LDI R26,0x60
004F E0B0 LDI R27,0
0050 E010 LDI R17,0
0051 37E4 CPI R30,0x74
0052 07F1 CPC R31,R17
0053 F021 BEQ 0x0058
0054 95C8 LPM
0055 9631 ADIW R30,1
0056 920D ST R0,X+
0057 CFF9 RJMP 0x0051
0058 940E00D6 CALL _main
_exit:
005A CFFF RJMP _exit
FILE: C:\DOCUME~1\Administrator\桌面\精雅系列单片机实验开发板演示程序\1602LCD\delay.h
(0001) #define xtal 8 //8MS
(0002) /************************************************************
(0003) * 函数名称:void DelayUS(unsigned int time)
(0004) * 功 能:软件延时1.1Us
(0005) * 入口参数:time 延时时间
(0006) * 出口参数:无
(0007) ************************************************************/
(0008) void DelayUS(unsigned int time)
(0009) {
_DelayUS:
time --> R16
005B C002 RJMP 0x005E
(0010) while(time>1)
(0011) time--;
005C 5001 SUBI R16,1
005D 4010 SBCI R17,0
005E E081 LDI R24,1
005F E090 LDI R25,0
0060 1780 CP R24,R16
0061 0791 CPC R25,R17
0062 F3C8 BCS 0x005C
0063 9508 RET
_DelayMS:
i --> R20
time --> R16
0064 940E010F CALL push_gset1
(0012) }
(0013) /************************************************************
(0014) * 函数名称:void DelayMS(unsigned int time)
(0015) * 功 能:软件延时 1/1000s
(0016) * 入口参数:time 延时时间 MS
(0017) * 出口参数:无
(0018) ************************************************************/
(0019) void DelayMS (unsigned int time)
(0020) {
0066 C009 RJMP 0x0070
(0021) unsigned int i;
(0022) while(time--)
(0023) {
(0024) for(i=1;i<(unsigned int)(xtal*143-2);i++)
0067 E041 LDI R20,1
0068 E050 LDI R21,0
0069 C002 RJMP 0x006C
006A 5F4F SUBI R20,0xFF
006B 4F5F SBCI R21,0xFF
006C 3746 CPI R20,0x76
006D E0E4 LDI R30,4
006E 075E CPC R21,R30
006F F3D0 BCS 0x006A
0070 0118 MOVW R2,R16
0071 5001 SUBI R16,1
0072 4010 SBCI R17,0
0073 2022 TST R2
0074 F791 BNE 0x0067
0075 2033 TST R3
0076 F781 BNE 0x0067
0077 940E0112 CALL pop_gset1
0079 9508 RET
FILE: C:\DOCUME~1\Administrator\桌面\精雅系列单片机实验开发板演示程序\1602LCD\1602LCD.c
(0001) /**********************************************
(0002) 液晶1602实验
(0003) 晶振: 内部8.0000Mhz
(0004) 连接:RS PA2,
(0005) RW PA1,
(0006) EN PA0,
(0007) DATA PD0-PD7
(0008) ***********************************************/
(0009) /******************头文件**********************/
(0010) #include <iom16v.h>
(0011) #include <macros.h>
(0012) #include "delay.h"
(0013) /******************宏定义**********************/
(0014) #define uchar unsigned char
(0015) #define uint unsigned int
(0016)
(0017) #define mode 0x38 //功能设置
(0018) //DL=1 八位数据接口
(0019) //N=1 两行显示
(0020) //F=0 5*7点阵字符
(0021) #define cursor 0x0f //显示开/关设置
(0022) //D=1 显示屏开
(0023) //C=1 光标开
(0024) //B=1 闪烁开
(0025) #define shift_off 0x06 //输入方式设置
(0026) //ID=1 读写一个字符后,地址和光标加1
(0027) //S=0 屏幕视窗停留在1-16列寄存器不移动
(0028) #define shift_on 0x07 //输入方式设置
(0029) //ID=1 读写一个字符后,地址和光标加1
(0030) //S=1 每次写完一个字符屏幕视窗从左边的寄存器向右边的寄存器移动实现字符左移的效果
(0031) #define run 0x1c //光标、画面移动,不影响DDRAM
(0032) //S/C=1 屏幕视窗向右平移一个字符
(0033) //R/L=1 右移
(0034) #define clean 0x01 //清屏指令
(0035) #define enter 0x02 //归位指令 AC=0 光标,画面回HOME位
(0036)
(0037) #define RS_H PORTA|=BIT(2) //RS=1,选择数据
(0038) #define RS_L PORTA&=~BIT(2) //RS=0,选择命令
(0039)
(0040) #define RW_H PORTA|=BIT(1) //R/W=1,读
(0041) #define RW_L PORTA&=~BIT(1) //R/W=0,写
(0042)
(0043) #define EN_H PORTA|=BIT(0) //EN=1,使能关
(0044) #define EN_L PORTA=~BIT(0) //EN=0,使能开
(0045)
(0046) const uchar table1[]="ji shu wu li xi"; //定义数据在flash中
(0047) const uchar table2[]="dianzixiaozu507";
(0048) /******************函数声明******************/
(0049) void port_init(void); //M16初始化
(0050) void n1602_init(void); //1602初始化
(0051) void write_com(uchar com); //写指令
(0052) void write_dat(uchar dat); //写数据
(0053) void set_xy(uchar x,uchar y); //设置行列
(0054) void show(uchar x,uchar y,uchar *str); //显示函数,x行,y列,*str字符串
(0055) /*****************M16初始化******************/
(0056) void port_init(void)
(0057) {
(0058) PORTA = 0x00;//设置端口数据、方向
_port_init:
007A 2422 CLR R2
007B BA2B OUT 0x1B,R2
(0059) DDRA = 0xFF;
007C EF8F LDI R24,0xFF
007D BB8A OUT 0x1A,R24
(0060) PORTB = 0x00;
007E BA28 OUT 0x18,R2
(0061) DDRB = 0x00;
007F BA27 OUT 0x17,R2
(0062) PORTC = 0x00;
0080 BA25 OUT 0x15,R2
(0063) DDRC = 0x00;
0081 BA24 OUT 0x14,R2
(0064) PORTD = 0x00;
0082 BA22 OUT 0x12,R2
(0065) DDRD = 0xFF;
0083 BB81 OUT 0x11,R24
0084 9508 RET
(0066) }
(0067) /*****************1602初始化*****************/
(0068) void n1602_init(void)
(0069) {
(0070) EN_L;
_n1602_init:
0085 EF8E LDI R24,0xFE
0086 BB8B OUT 0x1B,R24
(0071) write_com(mode); //功能设置
0087 E308 LDI R16,0x38
0088 D01D RCALL _write_com
(0072) DelayMS(1);
0089 E001 LDI R16,1
008A E010 LDI R17,0
008B DFD8 RCALL _DelayMS
(0073) write_com(clean); //清屏
008C E001 LDI R16,1
008D D018 RCALL _write_com
(0074) DelayMS(1);
008E E001 LDI R16,1
008F E010 LDI R17,0
0090 DFD3 RCALL _DelayMS
(0075) write_com(cursor); //显示开/关设置
0091 E00F LDI R16,0xF
0092 D013 RCALL _write_com
(0076) DelayMS(1);
0093 E001 LDI R16,1
0094 E010 LDI R17,0
0095 DFCE RCALL _DelayMS
(0077) write_com(shift_off); //每写完一个字符地址指针加+1,屏幕视窗不移动
0096 E006 LDI R16,6
0097 D00E RCALL _write_com
(0078) DelayMS(1);
0098 E001 LDI R16,1
0099 E010 LDI R17,0
009A DFC9 RCALL _DelayMS
009B 9508 RET
(0079)
(0080) }
(0081) void init_devices(void)
(0082) {
(0083) CLI(); //禁止所有中断
_init_devices:
009C 94F8 BCLR 7
(0084) MCUCR = 0x00;//INT0、INT1中断触发方式
009D 2422 CLR R2
009E BE25 OUT 0x35,R2
(0085) MCUCSR = 0x80;//禁止JTAG
009F E880 LDI R24,0x80
00A0 BF84 OUT 0x34,R24
(0086) GICR = 0x00;//外部中断使能
00A1 BE2B OUT 0x3B,R2
(0087) port_init();
00A2 DFD7 RCALL _port_init
(0088) n1602_init();
00A3 DFE1 RCALL _n1602_init
(0089) SEI();//开全局中断
00A4 9478 BSET 7
00A5 9508 RET
_write_com:
com --> R20
00A6 940E010F CALL push_gset1
00A8 2F40 MOV R20,R16
(0090) }
(0091) /******************写指令********************/
(0092) void write_com(uchar com)
(0093) {
(0094) RS_L; //选择命令
00A9 98DA CBI 0x1B,2
(0095) RW_L; //写
00AA 98D9 CBI 0x1B,1
(0096) PORTD=com; //送命令
00AB BB42 OUT 0x12,R20
(0097) EN_H;
00AC 9AD8 SBI 0x1B,0
(0098) DelayMS(1); //延时不可少,否则数据丢失
00AD E001 LDI R16,1
00AE E010 LDI R17,0
00AF DFB4 RCALL _DelayMS
(0099) EN_L; //下降沿写入
00B0 EF8E LDI R24,0xFE
00B1 BB8B OUT 0x1B,R24
00B2 940E0112 CALL pop_gset1
00B4 9508 RET
_write_dat:
dat --> R20
00B5 940E010F CALL push_gset1
00B7 2F40 MOV R20,R16
(0100) }
(0101) /******************写数据********************/
(0102) void write_dat(uchar dat)
(0103) {
(0104) RS_H; //选择数据
00B8 9ADA SBI 0x1B,2
(0105) RW_L; //写
00B9 98D9 CBI 0x1B,1
(0106) PORTD=dat; //送数据
00BA BB42 OUT 0x12,R20
(0107) EN_H;
00BB 9AD8 SBI 0x1B,0
(0108) DelayMS(1); //延时不可少,否则数据丢失
00BC E001 LDI R16,1
00BD E010 LDI R17,0
00BE DFA5 RCALL _DelayMS
(0109) EN_L; //下降沿写入
00BF EF8E LDI R24,0xFE
00C0 BB8B OUT 0x1B,R24
00C1 940E0112 CALL pop_gset1
00C3 9508 RET
_set_xy:
y --> R20
x --> R22
00C4 940E010D CALL push_gset2
00C6 2F42 MOV R20,R18
00C7 2F60 MOV R22,R16
(0110) }
(0111) /******************设置行列******************/
(0112) void set_xy(uchar x,uchar y) //x从1-2,y从1-40
(0113) {
(0114) if(x==1)
00C8 3061 CPI R22,1
00C9 F429 BNE 0x00CF
(0115) {write_com(0x80+y-1);} //对y调整为寄存器地址
00CA 2F04 MOV R16,R20
00CB 5800 SUBI R16,0x80
00CC 5001 SUBI R16,1
00CD DFD8 RCALL _write_com
00CE C004 RJMP 0x00D3
(0116) else
(0117) {write_com(0x80+0x40+y-1);}
00CF 2F04 MOV R16,R20
00D0 5400 SUBI R16,0x40
00D1 5001 SUBI R16,1
00D2 DFD3 RCALL _write_com
00D3 940E0104 CALL pop_gset2
00D5 9508 RET
(0118) }
(0119) /*******************主函数********************/
(0120) void main()
(0121) {
(0122) uchar i;
(0123) init_devices(); //单片机、1602初始化
_main:
i --> R20
00D6 DFC5 RCALL _init_devices
(0124)
(0125) ///***********************************第一种方法**************************************
(0126) set_xy(1,1); //数据放入第1行第18列以后的寄存器
00D7 E021 LDI R18,1
00D8 E001 LDI R16,1
00D9 DFEA RCALL _set_xy
(0127) DelayMS(1); //若出现乱码,可加适当延时
00DA E001 LDI R16,1
00DB E010 LDI R17,0
00DC DF87 RCALL _DelayMS
(0128) for(i=0;i<15;i++) //循环table1的字符数
00DD 2744 CLR R20
00DE C00C RJMP 0x00EB
(0129) {
(0130) write_dat(table1[i]); //写入第i个字符
00DF E584 LDI R24,0x54
00E0 E090 LDI R25,0
00E1 2FE4 MOV R30,R20
00E2 27FF CLR R31
00E3 0FE8 ADD R30,R24
00E4 1FF9 ADC R31,R25
00E5 9104 LPM R16,0(Z)
00E6 DFCE RCALL _write_dat
(0131) DelayMS(1); //若出现乱码,可加适当延时
00E7 E001 LDI R16,1
00E8 E010 LDI R17,0
00E9 DF7A RCALL _DelayMS
00EA 9543 INC R20
00EB 304F CPI R20,0xF
00EC F390 BCS 0x00DF
(0132) }
(0133) set_xy(2,1); //数据放入第2行第20列以后的寄存器
00ED E021 LDI R18,1
00EE E002 LDI R16,2
00EF DFD4 RCALL _set_xy
(0134) DelayMS(1); //若出现乱码,可加适当延时
00F0 E001 LDI R16,1
00F1 E010 LDI R17,0
00F2 DF71 RCALL _DelayMS
(0135) for(i=0;i<15;i++) //循环table2的字符数
00F3 2744 CLR R20
00F4 C00C RJMP 0x0101
(0136) {
(0137) write_dat(table2[i]); //写入第i个字符
00F5 E684 LDI R24,0x64
00F6 E090 LDI R25,0
00F7 2FE4 MOV R30,R20
00F8 27FF CLR R31
00F9 0FE8 ADD R30,R24
00FA 1FF9 ADC R31,R25
00FB 9104 LPM R16,0(Z)
00FC DFB8 RCALL _write_dat
(0138) DelayMS(1); //若出现乱码,可加适当延时
FILE: <library>
00FD E001 LDI R16,1
00FE E010 LDI R17,0
00FF DF64 RCALL _DelayMS
0100 9543 INC R20
0101 304F CPI R20,0xF
0102 F390 BCS 0x00F5
0103 9508 RET
pop_gset2:
0104 E0E2 LDI R30,2
0105 940C0113 JMP pop
push_gset5:
0107 92FA ST R15,-Y
0108 92EA ST R14,-Y
push_gset4:
0109 92DA ST R13,-Y
010A 92CA ST R12,-Y
push_gset3:
010B 92BA ST R11,-Y
010C 92AA ST R10,-Y
push_gset2:
010D 937A ST R23,-Y
010E 936A ST R22,-Y
push_gset1:
010F 935A ST R21,-Y
0110 934A ST R20,-Y
0111 9508 RET
pop_gset1:
0112 E0E1 LDI R30,1
pop:
0113 9149 LD R20,Y+
0114 9159 LD R21,Y+
0115 FDE0 SBRC R30,0
0116 9508 RET
0117 9169 LD R22,Y+
0118 9179 LD R23,Y+
0119 FDE1 SBRC R30,1
011A 9508 RET
011B 90A9 LD R10,Y+
011C 90B9 LD R11,Y+
011D FDE2 SBRC R30,2
011E 9508 RET
011F 90C9 LD R12,Y+
0120 90D9 LD R13,Y+
0121 FDE3 SBRC R30,3
0122 9508 RET
0123 90E9 LD R14,Y+
0124 90F9 LD R15,Y+
0125 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -