📄 slat1.lst
字号:
(0141)
(0142) void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data) //列x=0~15,行y=0,1
(0143) {
(0144) LCD_set_xy( X, Y ); //写地址
00FC 2F26 MOV R18,R22
00FD 2F04 MOV R16,R20
00FE DFD3 RCALL _LCD_set_xy
(0145) LCD_write_data( data);
00FF 810C LDD R16,Y+4
0100 DFB3 RCALL _LCD_write_data
0101 940E01C2 CALL pop_gset2
0103 9508 RET
FILE: F:\ChengXuCunFang\ChengXU\AVR单片机程序存放\max485多机通讯1\从机1\main.c
(0001) //从机11
(0002) #include<iom16v.h>
(0003) #include <macros.h>
(0004) #include "delay.h"
(0005) #include "1602.h"
(0006)
(0007) #define amount 10 //设定通讯数据量
(0008) #define address 11 //请在这里设定本机地址
(0009) #define max485_out PORTD |=(1<<PD4)
(0010) #define max485_in PORTD &=~(1<<PD4)
(0011) #define max485_RW_ok DDRD|=(1<<PD4)
(0012)
(0013) unsigned char send[amount]; //发件箱
(0014) unsigned char inbox[amount]; //收件箱
(0015) unsigned char n=0; //记忆中断次数
(0016)
(0017) //波特率9600/9个数据位/1个停止位/奇校验/收发开启/接收中断/地址过滤
(0018) void usart_init(void)
(0019) {
(0020) UCSRA=0x01;
_usart_init:
0104 E081 LDI R24,1
0105 B98B OUT 0x0B,R24
(0021) UCSRB=0x9C;
0106 E98C LDI R24,0x9C
0107 B98A OUT 0x0A,R24
(0022) UCSRC=0xB6;
0108 EB86 LDI R24,0xB6
0109 BD80 OUT 0x20,R24
(0023) UBRRH=0x00;
010A 2422 CLR R2
010B BC20 OUT 0x20,R2
(0024) UBRRL=47;
010C E28F LDI R24,0x2F
010D B989 OUT 0x09,R24
010E 9508 RET
_crc8:
crc --> R20
i --> R22
len --> R18
ptr --> R16
010F 940E01CE CALL push_gset2
(0025) }
(0026)
(0027) unsigned char crc8(unsigned char *ptr, unsigned char len)
(0028) {
(0029) unsigned char i;
(0030) unsigned char crc=0;
0111 2744 CLR R20
0112 C020 RJMP 0x0133
(0031) while(len--!=0)
(0032) {
(0033) for(i=1; i!=0; i*=2)
0113 E061 LDI R22,1
0114 C01A RJMP 0x012F
(0034) {
(0035) if((crc&1)!=0) {crc/=2; crc^=0x8C;}
0115 FF40 SBRS R20,0
0116 C009 RJMP 0x0120
0117 9546 LSR R20
0118 E88C LDI R24,0x8C
0119 E090 LDI R25,0
011A 2E24 MOV R2,R20
011B 2433 CLR R3
011C 2628 EOR R2,R24
011D 2639 EOR R3,R25
011E 2D42 MOV R20,R2
011F C001 RJMP 0x0121
(0036) else crc/=2;
0120 9546 LSR R20
(0037) if((*ptr&i)!=0) crc^=0x8C;
0121 01F8 MOVW R30,R16
0122 8020 LDD R2,Z+0
0123 2226 AND R2,R22
0124 F039 BEQ 0x012C
0125 E88C LDI R24,0x8C
0126 E090 LDI R25,0
0127 2E24 MOV R2,R20
0128 2433 CLR R3
0129 2628 EOR R2,R24
012A 2639 EOR R3,R25
012B 2D42 MOV R20,R2
012C E082 LDI R24,2
012D 9F86 MUL R24,R22
012E 2D60 MOV R22,R0
012F 2366 TST R22
0130 F721 BNE 0x0115
(0038) }
(0039) ptr++;
0131 5F0F SUBI R16,0xFF
0132 4F1F SBCI R17,0xFF
0133 2E22 MOV R2,R18
0134 2433 CLR R3
0135 5021 SUBI R18,1
0136 2022 TST R2
0137 F6D9 BNE 0x0113
(0040) }
(0041) return(crc);
0138 2F04 MOV R16,R20
0139 940E01C2 CALL pop_gset2
013B 9508 RET
_usart_out:
i --> R20
n --> R18
datas --> R16
013C 940E01D0 CALL push_gset1
(0042) }
(0043)
(0044)
(0045)
(0046) //**************************************************************************************
(0047)
(0048) void usart_out(unsigned char *datas,unsigned char n)
(0049) {
(0050) unsigned char i=0;
013E 2744 CLR R20
(0051) max485_out; //使MAX485处于发送状态
013F 9A94 SBI 0x12,4
0140 C011 RJMP 0x0152
(0052) while(i<n) //一共发送n个数据
(0053) {
(0054) if(i==0) UCSRB|=1; else UCSRB&=254;
0141 2344 TST R20
0142 F411 BNE 0x0145
0143 9A50 SBI 0x0A,0
0144 C003 RJMP 0x0148
0145 B18A IN R24,0x0A
0146 7F8E ANDI R24,0xFE
0147 B98A OUT 0x0A,R24
(0055) UDR=*(datas+i); //装载数据开始发送
0148 2FE4 MOV R30,R20
0149 27FF CLR R31
014A 0FE0 ADD R30,R16
014B 1FF1 ADC R31,R17
014C 8020 LDD R2,Z+0
014D B82C OUT 0x0C,R2
(0056) while((UCSRA&64)==0); //等待发送结束
014E 9B5E SBIS 0x0B,6
014F CFFE RJMP 0x014E
(0057) UCSRA|=64; //清除发送结束标志
0150 9A5E SBI 0x0B,6
(0058) i++; //发送次数统计
0151 9543 INC R20
0152 1742 CP R20,R18
0153 F368 BCS 0x0141
(0059) }
(0060) max485_in; //使MAX485处于接收状态
0154 9894 CBI 0x12,4
0155 940E01D3 CALL pop_gset1
0157 9508 RET
_RXC_Int:
0158 940E01E7 CALL push_lset
(0061) }
(0062)
(0063) //**************************************************************************************
(0064) #pragma interrupt_handler RXC_Int: 12
(0065) void RXC_Int(void) //接收中断
(0066) {
(0067) if( UCSRA&28 ){ n=UDR; n=0; UCSRA|=0x01; } else //接收出错就重新打开地址帧筛选功能
015A B18B IN R24,0x0B
015B 718C ANDI R24,0x1C
015C F041 BEQ 0x0165
015D B02C IN R2,0x0C
015E 92200060 STS n,R2
0160 2422 CLR R2
0161 92200060 STS n,R2
0163 9A58 SBI 0x0B,0
0164 C03A RJMP 0x019F
(0068) {
(0069) if( UCSRB&2 ) n=0; //检测到地址信息时计数清零
0165 9B51 SBIS 0x0A,1
0166 C003 RJMP 0x016A
0167 2422 CLR R2
0168 92200060 STS n,R2
(0070) inbox[n]=UDR; n++; //把接收到的数据保存到收件箱
016A E68C LDI R24,0x6C
016B E090 LDI R25,0
016C 91E00060 LDS R30,n
016E 27FF CLR R31
016F 0FE8 ADD R30,R24
0170 1FF9 ADC R31,R25
0171 B02C IN R2,0x0C
0172 8220 STD Z+0,R2
0173 91800060 LDS R24,n
0175 5F8F SUBI R24,0xFF
0176 93800060 STS n,R24
(0071) if( inbox[0]==address ) UCSRA&=254; else UCSRA|=0x01; //地址筛选
0178 9180006C LDS R24,inbox
017A 308B CPI R24,0xB
017B F421 BNE 0x0180
017C B18B IN R24,0x0B
017D 7F8E ANDI R24,0xFE
017E B98B OUT 0x0B,R24
017F C001 RJMP 0x0181
0180 9A58 SBI 0x0B,0
(0072) if( n==amount ) //如果接收到完整的数据包
0181 91800060 LDS R24,n
0183 308A CPI R24,0xA
0184 F4D1 BNE 0x019F
(0073) {
(0074) if( inbox[amount-1]==crc8(inbox,amount-1) ) //如果crc8校验正确就...
0185 E029 LDI R18,0x9
0186 E60C LDI R16,0x6C
0187 E010 LDI R17,0
0188 DF86 RCALL _crc8
0189 90200075 LDS R2,0x75
018B 1620 CP R2,R16
018C F491 BNE 0x019F
(0075) {
(0076) send[0]=1; //发件箱地址指向主机
018D E081 LDI R24,1
018E 93800076 STS send,R24
(0077) //send[1]=? //请更新发件箱的数据
(0078) //send[n]=?
(0079) send[amount-1]=crc8(send,amount-1); //产生发件箱的crc8校验码
0190 E029 LDI R18,0x9
0191 E706 LDI R16,0x76
0192 E010 LDI R17,0
0193 DF7B RCALL _crc8
0194 9300007F STS 0x7F,R16
(0080) usart_out(send,amount); //发送发件箱的数据包/查询方式比较耗时
0196 E02A LDI R18,0xA
0197 E706 LDI R16,0x76
0198 E010 LDI R17,0
0199 DFA2 RCALL _usart_out
(0081) OCR1A=inbox[3]; //收件箱测试(控制T/C1的PWM驱动LED)
019A 9020006F LDS R2,inbox+3
019C 2433 CLR R3
019D BC3B OUT 0x2B,R3
019E BC2A OUT 0x2A,R2
(0082) }
(0083) }
(0084) }
019F 940E01FE CALL pop_lset
01A1 9518 RETI
_main:
01A2 9722 SBIW R28,2
(0085) }
(0086)
(0087) //**************************************************************************************
(0088)
(0089) void main(void)
(0090) {
(0091) usart_init();
01A3 DF60 RCALL _usart_init
(0092) LCD_init();
01A4 DED6 RCALL _LCD_init
(0093) max485_in;
01A5 9894 CBI 0x12,4
(0094) max485_RW_ok;
01A6 9A8C SBI 0x11,4
(0095) TCCR1A =0B10000001; //OCR1A/PD5/8位快速PWM
01A7 E881 LDI R24,0x81
01A8 BD8F OUT 0x2F,R24
(0096) TCCR1B =0B00001001; //时钟1分频
01A9 E089 LDI R24,0x9
01AA BD8E OUT 0x2E,R24
(0097) DDRD |=0b00100000; //输出使能
01AB 9A8D SBI 0x11,5
(0098) OCR1A =255; //初始化PWM输出100%占空比
01AC EF8F LDI R24,0xFF
01AD E090 LDI R25,0
01AE BD9B OUT 0x2B,R25
01AF BD8A OUT 0x2A,R24
(0099) SEI(); //打开全局中断,需要macros.h支持
01B0 9478 BSET 7
(0100) LCD_write_string(0,0,"Send:");
01B1 E686 LDI R24,0x66
01B2 E090 LDI R25,0
01B3 8399 STD Y+1,R25
01B4 8388 STD Y+0,R24
01B5 2722 CLR R18
01B6 2700 CLR R16
01B7 DF2A RCALL _LCD_write_string
(0101) LCD_write_string(0,1,"Rev:");
01B8 E681 LDI R24,0x61
01B9 E090 LDI R25,0
01BA 8399 STD Y+1,R25
01BB 8388 STD Y+0,R24
01BC E021 LDI R18,1
01BD 2700 CLR R16
01BE DF23 RCALL _LCD_write_string
(0102)
(0103) while (1)
01BF CFFF RJMP 0x01BF
(0104) {
(0105)
(0106) };
FILE: <library>
01C0 9622 ADIW R28,2
01C1 9508 RET
pop_gset2:
01C2 E0E2 LDI R30,2
01C3 940C01D4 JMP pop
pop_gset3:
01C5 E0E4 LDI R30,4
01C6 940C01D4 JMP pop
push_gset5:
01C8 92FA ST R15,-Y
01C9 92EA ST R14,-Y
push_gset4:
01CA 92DA ST R13,-Y
01CB 92CA ST R12,-Y
push_gset3:
01CC 92BA ST R11,-Y
01CD 92AA ST R10,-Y
push_gset2:
01CE 937A ST R23,-Y
01CF 936A ST R22,-Y
push_gset1:
01D0 935A ST R21,-Y
01D1 934A ST R20,-Y
01D2 9508 RET
pop_gset1:
01D3 E0E1 LDI R30,1
pop:
01D4 9149 LD R20,Y+
01D5 9159 LD R21,Y+
01D6 FDE0 SBRC R30,0
01D7 9508 RET
01D8 9169 LD R22,Y+
01D9 9179 LD R23,Y+
01DA FDE1 SBRC R30,1
01DB 9508 RET
01DC 90A9 LD R10,Y+
01DD 90B9 LD R11,Y+
01DE FDE2 SBRC R30,2
01DF 9508 RET
01E0 90C9 LD R12,Y+
01E1 90D9 LD R13,Y+
01E2 FDE3 SBRC R30,3
01E3 9508 RET
01E4 90E9 LD R14,Y+
01E5 90F9 LD R15,Y+
01E6 9508 RET
push_lset:
01E7 93FA ST R31,-Y
01E8 93EA ST R30,-Y
01E9 93BA ST R27,-Y
01EA 93AA ST R26,-Y
01EB 939A ST R25,-Y
01EC 938A ST R24,-Y
01ED 933A ST R19,-Y
01EE 932A ST R18,-Y
01EF 931A ST R17,-Y
01F0 930A ST R16,-Y
01F1 929A ST R9,-Y
01F2 928A ST R8,-Y
01F3 927A ST R7,-Y
01F4 926A ST R6,-Y
01F5 925A ST R5,-Y
01F6 924A ST R4,-Y
01F7 923A ST R3,-Y
01F8 922A ST R2,-Y
01F9 921A ST R1,-Y
01FA 920A ST R0,-Y
01FB B60F IN R0,0x3F
01FC 920A ST R0,-Y
01FD 9508 RET
pop_lset:
01FE 9009 LD R0,Y+
01FF BE0F OUT 0x3F,R0
0200 9009 LD R0,Y+
0201 9019 LD R1,Y+
0202 9029 LD R2,Y+
0203 9039 LD R3,Y+
0204 9049 LD R4,Y+
0205 9059 LD R5,Y+
0206 9069 LD R6,Y+
0207 9079 LD R7,Y+
0208 9089 LD R8,Y+
0209 9099 LD R9,Y+
020A 9109 LD R16,Y+
020B 9119 LD R17,Y+
020C 9129 LD R18,Y+
020D 9139 LD R19,Y+
020E 9189 LD R24,Y+
020F 9199 LD R25,Y+
0210 91A9 LD R26,Y+
0211 91B9 LD R27,Y+
0212 91E9 LD R30,Y+
0213 91F9 LD R31,Y+
0214 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -