📄 spi.lst
字号:
__text_start:
__start:
002A E5CF LDI R28,0x5F
002B E0D4 LDI R29,4
002C BFCD OUT 0x3D,R28
002D BFDE OUT 0x3E,R29
002E 51C0 SUBI R28,0x10
002F 40D0 SBCI R29,0
0030 EA0A LDI R16,0xAA
0031 8308 STD Y+0,R16
0032 2400 CLR R0
0033 E6E0 LDI R30,0x60
0034 E0F0 LDI R31,0
0035 E010 LDI R17,0
0036 36E0 CPI R30,0x60
0037 07F1 CPC R31,R17
0038 F011 BEQ 0x003B
0039 9201 ST R0,Z+
003A CFFB RJMP 0x0036
003B 8300 STD Z+0,R16
003C E5E4 LDI R30,0x54
003D E0F0 LDI R31,0
003E E6A0 LDI R26,0x60
003F E0B0 LDI R27,0
0040 E010 LDI R17,0
0041 35E4 CPI R30,0x54
0042 07F1 CPC R31,R17
0043 F021 BEQ 0x0048
0044 95C8 LPM
0045 9631 ADIW R30,1
0046 920D ST R0,X+
0047 CFF9 RJMP 0x0041
0048 940E029D CALL _main
_exit:
004A CFFF RJMP _exit
FILE: E:\写的程序\AVR(C)\1602显示.c
(0001) #include <iom16v.h>
(0002) #include <macros.h>
(0003)
(0004) //定义MCU与LCD的接口
(0005) #define LCD_EN_PORT PORTC
(0006) #define LCD_RW_PORT PORTC
(0007) #define LCD_RS_PORT PORTC
(0008) #define LCD_DATA_PORT PORTA
(0009) #define LCD_DATA_DDR DDRA
(0010) #define LCD_DATA_PIN PINA
(0011)
(0012) #define LCD_EN 0x80 //portC7 out
(0013) #define LCD_RW 0x40 //portC6 out/in
(0014) #define LCD_RS 0x20 //portC5 out
(0015) #define LCD_DATA 0xf0 //porta4/5/6/7 out
(0016)
(0017) /*-----------------------------------------------------------------------
(0018) 延时函数
(0019) 系统时钟:8M
(0020) -----------------------------------------------------------------------*/
(0021) void delay_1us(void) //1us延时函数
(0022) {
(0023) asm("nop");
_delay_1us:
004B 0000 NOP
004C 9508 RET
_delay_nus:
i --> R20
n --> R22
004D 940E0335 CALL push_gset2
004F 01B8 MOVW R22,R16
(0024) }
(0025)
(0026) void delay_nus(unsigned int n) //N us延时函数
(0027) {
(0028) unsigned int i=0;
0050 2744 CLR R20
0051 2755 CLR R21
(0029) for (i=0;i<n;i++)
0052 C003 RJMP 0x0056
(0030) delay_1us();
0053 DFF7 RCALL _delay_1us
0054 5F4F SUBI R20,0xFF
0055 4F5F SBCI R21,0xFF
0056 1746 CP R20,R22
0057 0757 CPC R21,R23
0058 F3D0 BCS 0x0053
0059 940E0326 CALL pop_gset2
005B 9508 RET
(0031) }
(0032)
(0033) void delay_1ms(void) //1ms延时函数
(0034) {
(0035) unsigned int i;
(0036) for (i=0;i<1140;i++);
_delay_1ms:
i --> R16
005C 2700 CLR R16
005D 2711 CLR R17
005E C002 RJMP 0x0061
005F 5F0F SUBI R16,0xFF
0060 4F1F SBCI R17,0xFF
0061 3704 CPI R16,0x74
0062 E0E4 LDI R30,4
0063 071E CPC R17,R30
0064 F3D0 BCS 0x005F
0065 9508 RET
_delay_nms:
i --> R20
n --> R22
0066 940E0335 CALL push_gset2
0068 01B8 MOVW R22,R16
(0037) }
(0038)
(0039) void delay_nms(unsigned int n) //N ms延时函数
(0040) {
(0041) unsigned int i=0;
0069 2744 CLR R20
006A 2755 CLR R21
(0042) for (i=0;i<n;i++)
006B C003 RJMP 0x006F
(0043) delay_1ms();
006C DFEF RCALL _delay_1ms
006D 5F4F SUBI R20,0xFF
006E 4F5F SBCI R21,0xFF
006F 1746 CP R20,R22
0070 0757 CPC R21,R23
0071 F3D0 BCS 0x006C
0072 940E0326 CALL pop_gset2
0074 9508 RET
(0044) }
(0045)
(0046) /*--------------------------------------------------------------------------------------------------
(0047) Public function prototypes
(0048) --------------------------------------------------------------------------------------------------*/
(0049) void LCD_init(void);
(0050) void LCD_en_write(void);
(0051) void LCD_write_char(unsigned command,unsigned data);
(0052) void LCD_wait_Ready(void);
(0053) void LCD_set_xy(unsigned char x, unsigned char y);
(0054) void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);
(0055) void delay_nus(unsigned int n);
(0056) void delay_nms(unsigned int n);
(0057)
(0058) /**********************************************************
(0059) 光标命令
(0060) LCD_write_char(0x0e,0); //光标开
(0061) LCD_write_char(0x0d,0); //光标所在字符闪烁
(0062) LCD_write_char(0x0c,0); //光标关
(0063) **********************************************************/
(0064) /**********************************************************
(0065) TC1602B LCD DISPLAY
(0066) LCD_write函数功能:当command=0时,向LCD写入数据,否则向LCD写
(0067) 入命令
(0068) LCD第一行显示寄存器地址:0X80-0X8F
(0069) LCD第二行显示寄存器地址:0XC0-0XCF
(0070) **********************************************************/
(0071) void LCD_init(void)
(0072) {
(0073) DDRA=0XFF; //设置PA输出
_LCD_init:
0075 EF8F LDI R24,0xFF
0076 BB8A OUT 0x1A,R24
(0074) PORTA=0XFF; //全部加上上拉电阻
0077 BB8B OUT 0x1B,R24
(0075) DDRC=0XFF; //设置PC为输出
0078 BB84 OUT 0x14,R24
(0076) PORTC=0XFF; //全部加上上拉电阻
0079 BB85 OUT 0x15,R24
(0077) delay_nms(15);
007A E00F LDI R16,0xF
007B E010 LDI R17,0
007C DFE9 RCALL _delay_nms
(0078) LCD_write_char(0x28,0); //4bit test
007D 2722 CLR R18
007E 2733 CLR R19
007F E208 LDI R16,0x28
0080 E010 LDI R17,0
0081 D016 RCALL _LCD_write_char
(0079) LCD_write_char(0x0c,0); //显示开
0082 2722 CLR R18
0083 2733 CLR R19
0084 E00C LDI R16,0xC
0085 E010 LDI R17,0
0086 D011 RCALL _LCD_write_char
(0080) LCD_write_char(0x01,0); //显示清屏
0087 2722 CLR R18
0088 2733 CLR R19
0089 E001 LDI R16,1
008A E010 LDI R17,0
008B D00C RCALL _LCD_write_char
(0081) LCD_write_char(0x06,0); //显示光标移动设置
008C 2722 CLR R18
008D 2733 CLR R19
008E E006 LDI R16,6
008F E010 LDI R17,0
0090 D007 RCALL _LCD_write_char
0091 9508 RET
(0082) }
(0083)
(0084) void LCD_en_write(void) //EN端产生一个高电平脉冲,写LCD
(0085) {
(0086) LCD_EN_PORT |= LCD_EN;
_LCD_en_write:
0092 9AAF SBI 0x15,7
(0087) delay_nus(1);
0093 E001 LDI R16,1
0094 E010 LDI R17,0
0095 DFB7 RCALL _delay_nus
(0088) LCD_EN_PORT &= ~LCD_EN;
0096 98AF CBI 0x15,7
0097 9508 RET
_LCD_write_char:
data_temp --> R22
command_temp --> R20
data --> R12
command --> R10
0098 940E0331 CALL push_gset4
009A 0169 MOVW R12,R18
009B 0158 MOVW R10,R16
(0089) }
(0090)
(0091) /*-----------------------------------------------------------------------
(0092) LCD_write_char : 英文字符串显示函数
(0093)
(0094) 输入参数:*s :英文字符串指针;
(0095) X、Y : 显示字符串的位置,X:0-15,Y:0-1
(0096) LCD第一行显示寄存器地址:0X80-0X8F
(0097) LCD第一行显示寄存器地址:0XC0-0XCF
(0098) -----------------------------------------------------------------------*/
(0099) void LCD_write_char(unsigned command,unsigned data)
(0100) {
(0101) unsigned command_temp,data_temp;
(0102) command_temp = command;
009C 01A5 MOVW R20,R10
(0103) data_temp = data;
009D 01B6 MOVW R22,R12
(0104) LCD_wait_Ready();
009E D04F RCALL _LCD_wait_Ready
(0105) LCD_RW_PORT &= ~LCD_RW; //RW=0
009F 98AE CBI 0x15,6
(0106) if (command == 0)
00A0 3040 CPI R20,0
00A1 0745 CPC R20,R21
00A2 F469 BNE 0x00B0
(0107) {
(0108) LCD_RS_PORT |= LCD_RS; //RS=1
00A3 9AAD SBI 0x15,5
(0109) LCD_DATA_PORT &= 0X0F;
00A4 B38B IN R24,0x1B
00A5 708F ANDI R24,0xF
00A6 BB8B OUT 0x1B,R24
(0110) LCD_DATA_PORT|= data_temp&0xf0; //send high 4bit gai f
00A7 01CB MOVW R24,R22
00A8 7F80 ANDI R24,0xF0
00A9 7090 ANDI R25,0
00AA B22B IN R2,0x1B
00AB 2433 CLR R3
00AC 2A28 OR R2,R24
00AD 2A39 OR R3,R25
00AE BA2B OUT 0x1B,R2
(0111) }
00AF C00C RJMP 0x00BC
(0112) else
(0113) {
(0114) LCD_RS_PORT &= ~LCD_RS; //RS=0
00B0 98AD CBI 0x15,5
(0115) LCD_DATA_PORT &= 0X0F;
00B1 B38B IN R24,0x1B
00B2 708F ANDI R24,0xF
00B3 BB8B OUT 0x1B,R24
(0116) LCD_DATA_PORT |= command_temp&0xf0;//send high 4bit gai f
00B4 01CA MOVW R24,R20
00B5 7F80 ANDI R24,0xF0
00B6 7090 ANDI R25,0
00B7 B22B IN R2,0x1B
00B8 2433 CLR R3
00B9 2A28 OR R2,R24
00BA 2A39 OR R3,R25
00BB BA2B OUT 0x1B,R2
(0117) }
(0118) LCD_en_write();
00BC DFD5 RCALL _LCD_en_write
(0119) command_temp=command_temp << 4; //send low 4bit
00BD 0F44 LSL R20
00BE 1F55 ROL R21
00BF 0F44 LSL R20
00C0 1F55 ROL R21
00C1 0F44 LSL R20
00C2 1F55 ROL R21
00C3 0F44 LSL R20
00C4 1F55 ROL R21
(0120) data_temp=data_temp << 4;
00C5 0F66 LSL R22
00C6 1F77 ROL R23
00C7 0F66 LSL R22
00C8 1F77 ROL R23
00C9 0F66 LSL R22
00CA 1F77 ROL R23
00CB 0F66 LSL R22
00CC 1F77 ROL R23
(0121) LCD_DATA_PORT &= 0X0F;
00CD B38B IN R24,0x1B
00CE 708F ANDI R24,0xF
00CF BB8B OUT 0x1B,R24
(0122) if (command==0)
00D0 20AA TST R10
00D1 F459 BNE 0x00DD
00D2 20BB TST R11
00D3 F449 BNE 0x00DD
(0123) LCD_DATA_PORT |= data_temp&0xf0;
00D4 01CB MOVW R24,R22
00D5 7F80 ANDI R24,0xF0
00D6 7090 ANDI R25,0
00D7 B22B IN R2,0x1B
00D8 2433 CLR R3
00D9 2A28 OR R2,R24
00DA 2A39 OR R3,R25
00DB BA2B OUT 0x1B,R2
00DC C008 RJMP 0x00E5
(0124) else
(0125) LCD_DATA_PORT |= command_temp&0xf0;
00DD 01CA MOVW R24,R20
00DE 7F80 ANDI R24,0xF0
00DF 7090 ANDI R25,0
00E0 B22B IN R2,0x1B
00E1 2433 CLR R3
00E2 2A28 OR R2,R24
00E3 2A39 OR R3,R25
00E4 BA2B OUT 0x1B,R2
(0126) LCD_en_write();
00E5 DFAC RCALL _LCD_en_write
(0127) LCD_RW_PORT |= LCD_RW;
00E6 9AAE SBI 0x15,6
(0128) LCD_RS_PORT ^= LCD_RS;
00E7 E280 LDI R24,0x20
00E8 B225 IN R2,0x15
00E9 2628 EOR R2,R24
00EA BA25 OUT 0x15,R2
00EB 940E032C CALL pop_gset4
00ED 9508 RET
(0129) }
(0130)
(0131) void LCD_wait_Ready(void) //等待LCD空闲
(0132) {
(0133) LCD_DATA_DDR &= ~0x80; //PA7 I/O口方向设置为输入
_LCD_wait_Ready:
00EE 98D7 CBI 0x1A,7
(0134) LCD_RW_PORT |= LCD_RW; //RW=1
00EF 9AAE SBI 0x15,6
(0135) LCD_RS_PORT &= ~LCD_RS; //RS=0
00F0 98AD CBI 0x15,5
(0136) LCD_EN_PORT |= LCD_EN; //EN=1
00F1 9AAF SBI 0x15,7
(0137) while (!( LCD_DATA_PIN&0x80 ) == 0); //RW=1,读PA7,为0表示空闲;
00F2 99CF SBIC 0x19,7
00F3 C003 RJMP 0x00F7
00F4 E001 LDI R16,1
00F5 E010 LDI R17,0
00F6 C002 RJMP 0x00F9
00F7 2700 CLR R16
00F8 2711 CLR R17
00F9 3000 CPI R16,0
00FA 0701 CPC R16,R17
00FB F3B1 BEQ 0x00F2
(0138) LCD_EN_PORT &= ~LCD_EN; //EN=0
00FC 98AF CBI 0x15,7
(0139) LCD_DATA_DDR |= 0xf0;
00FD B38A IN R24,0x1A
00FE 6F80 ORI R24,0xF0
00FF BB8A OUT 0x1A,R24
0100 9508 RET
_LCD_set_xy:
address --> R20
y --> R20
x --> R22
0101 940E0335 CALL push_gset2
0103 2F42 MOV R20,R18
0104 2F60 MOV R22,R16
(0140) }
(0141)
(0142) /*-----------------------------------------------------------------------
(0143) LCD_set_xy : 设置LCD显示的起始位置
(0144)
(0145) 输入参数:x、y : 显示字符串的位置,X:0-15,Y:0-1
(0146) LCD第一行显示寄存器地址:0X80-0X8F
(0147) LCD第一行显示寄存器地址:0XC0-0XCF
(0148) -----------------------------------------------------------------------*/
(0149) void LCD_set_xy( unsigned char x, unsigned char y )
(0150) {
(0151) unsigned char address;
(0152) if (y == 0) address = 0x80 + x;
0105 2344 TST R20
0106 F419 BNE 0x010A
0107 2F46 MOV R20,R22
0108 5840 SUBI R20,0x80
0109 C002 RJMP 0x010C
(0153) else
(0154) address = 0xc0 + x;
010A 2F46 MOV R20,R22
010B 5440 SUBI R20,0x40
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -