📄 main.lis
字号:
.module main.c
.area text(rom, con, rel)
0000 .dbfile D:\avr\+++精华+++\485\485_master/delay.h
0000 .dbfunc e delay_1us _delay_1us fV
.even
0000 _delay_1us::
0000 .dbline -1
0000 .dbline 15
0000 ; /*******************************************************************************
0000 ; 485多机通讯
0000 ; --------------------------------------------------------------------------------
0000 ; 通讯规则:
0000 ; 1:时钟7.3728 MHz/波特率9600/9个数据位/奇校验/1个停止位/硬件多机通讯功能/
0000 ; 2:通讯连接采用硬件MAX485,双向单工
0000 ; 3:每个上行/下行的数据包的字节个数都是一样的(通讯数据量)
0000 ; 4:每个上行/下行的数据包都采用CRC8校验
0000 ; 5:数据接收采用中断+查询的方式
0000 ; 6:总是由主机向从机发送一个数据包,从机收到数据包后向主机回复一个数据包
0000 ; 7:不管是主机还是从机,如果收到的数据包有任何错误,都将丢弃该数据包,等效于没有接收
0000 ; 8:从机之间不能相互通讯,必须通过主机才能交换数据
0000 ; 9:无效地址是0,主机地址是1,从机地址是2.3.4......广播地址是255
0000 ; ********************************************************************************/
0000 ;
0000 .dbline 16
0000 ; #include <iom16v.h>
0000 0000 nop
0002 .dbline -2
0002 L1:
0002 .dbline 0 ; func end
0002 0895 ret
0004 .dbend
0004 .dbfunc e delay_nus _delay_nus fV
0004 ; i -> R20,R21
0004 ; n -> R22,R23
.even
0004 _delay_nus::
0004 0E940000 xcall push_gset2
0008 B801 movw R22,R16
000A .dbline -1
000A .dbline 20
000A ; #include <macros.h>
000A ; #include "delay.h"
000A ; #include "1602.h"
000A ; #include "usart.h"
000A .dbline 21
000A ; #include "crc8.h" //CRC校验函数就在这个文件里面
000A 4427 clr R20
000C 5527 clr R21
000E .dbline 22
000E ; #include "key.h"
000E 03C0 xjmp L6
0010 L3:
0010 .dbline 23
0010 F7DF xcall _delay_1us
0012 L4:
0012 .dbline 22
0012 4F5F subi R20,255 ; offset = 1
0014 5F4F sbci R21,255
0016 L6:
0016 .dbline 22
0016 4617 cp R20,R22
0018 5707 cpc R21,R23
001A D0F3 brlo L3
001C .dbline -2
001C L2:
001C 0E940000 xcall pop_gset2
0020 .dbline 0 ; func end
0020 0895 ret
0022 .dbsym r i 20 i
0022 .dbsym r n 22 i
0022 .dbend
0022 .dbfunc e delay_1ms _delay_1ms fV
0022 ; i -> R16,R17
.even
0022 _delay_1ms::
0022 .dbline -1
0022 .dbline 27
0022 ; #define amount 10 //设定通讯数据量(包括1个地址帧,n个数据帧,1个校验帧)
0022 ;
0022 ;
0022 ; unsigned char send[amount]; //发件箱
0022 ; unsigned char inbox[amount]; //收件箱
0022 .dbline 29
0022 0027 clr R16
0024 1127 clr R17
0026 02C0 xjmp L11
0028 L8:
0028 .dbline 29
0028 L9:
0028 .dbline 29
0028 0F5F subi R16,255 ; offset = 1
002A 1F4F sbci R17,255
002C L11:
002C .dbline 29
002C ; unsigned char n=0; //记忆中断次数
002C ; unsigned char flag_me=0;
002C 0437 cpi R16,116
002E E4E0 ldi R30,4
0030 1E07 cpc R17,R30
0032 D0F3 brlo L8
0034 .dbline -2
0034 L7:
0034 .dbline 0 ; func end
0034 0895 ret
0036 .dbsym r i 16 i
0036 .dbend
0036 .dbfunc e delay_nms _delay_nms fV
0036 ; i -> R20,R21
0036 ; n -> R22,R23
.even
0036 _delay_nms::
0036 0E940000 xcall push_gset2
003A B801 movw R22,R16
003C .dbline -1
003C .dbline 33
003C ; unsigned char flag_all=0;
003C ;
003C ;
003C ;
003C .dbline 34
003C ; //-------------------主机接收子程序--------------------------------
003C 4427 clr R20
003E 5527 clr R21
0040 .dbline 35
0040 ; #pragma interrupt_handler RXC_Int: 12
0040 03C0 xjmp L16
0042 L13:
0042 .dbline 36
0042 EFDF xcall _delay_1ms
0044 L14:
0044 .dbline 35
0044 4F5F subi R20,255 ; offset = 1
0046 5F4F sbci R21,255
0048 L16:
0048 .dbline 35
0048 4617 cp R20,R22
004A 5707 cpc R21,R23
004C D0F3 brlo L13
004E .dbline -2
004E L12:
004E 0E940000 xcall pop_gset2
0052 .dbline 0 ; func end
0052 0895 ret
0054 .dbsym r i 20 i
0054 .dbsym r n 22 i
0054 .dbend
0054 .dbfile D:\avr\+++精华+++\485\485_master/1602.h
0054 .dbfunc e LCD_init _LCD_init fV
.even
0054 _LCD_init::
0054 .dbline -1
0054 .dbline 44
0054 ; void RXC_Int(void) //接收中断
0054 ; {
0054 ; unsigned char ERROR=0;
0054 ; if(UCSRA&0x08||UCSRA&0x10 )ERROR=1; //奇偶效验错误(avr自动完成)或者帧错误就记录下来
0054 ; inbox[n]=UDR;
0054 ; n++; //记忆中断次数
0054 ; if(ERROR) inbox[0]=0; //如果通讯有错,收件箱的地址帧就标记成无效地址0
0054 ; }
0054 ;
0054 .dbline 45
0054 ; void int_485(void)//接收程序,在中断中调用或者扫描调用
0054 84B3 in R24,0x14
0056 8F60 ori R24,15
0058 84BB out 0x14,R24
005A .dbline 46
005A ; {
005A A59A sbi 0x14,5
005C .dbline 47
005C ; //if(n<3) 如果接收到的数据还不到3个,那么就是通讯线路故障
005C A49A sbi 0x14,4
005E .dbline 48
005E ;
005E 08E2 ldi R16,40
0060 14D0 xcall _LCD_write_command
0062 .dbline 49
0062 ; //如果收件箱已经收到amount个数据,并且crc8校验成功就...
0062 0DD0 xcall _LCD_en_write
0064 .dbline 50
0064 ; if(n==amount && inbox[amount-1]==crc8(inbox,amount-1))
0064 08E2 ldi R16,40
0066 10E0 ldi R17,0
0068 CDDF xcall _delay_nus
006A .dbline 51
006A ; {
006A 08E2 ldi R16,40
006C 0ED0 xcall _LCD_write_command
006E .dbline 52
006E ; if(inbox[0]==1)flag_me=1;
006E 0CE0 ldi R16,12
0070 0CD0 xcall _LCD_write_command
0072 .dbline 53
0072 ; //接收完数据后会置标志位
0072 01E0 ldi R16,1
0074 0AD0 xcall _LCD_write_command
0076 .dbline 54
0076 ; if(inbox[0]==255) flag_me=1; //请在这里添加收到广播数据的处理程序
0076 02E0 ldi R16,2
0078 10E0 ldi R17,0
007A DDDF xcall _delay_nms
007C .dbline -2
007C L17:
007C .dbline 0 ; func end
007C 0895 ret
007E .dbend
007E .dbfunc e LCD_en_write _LCD_en_write fV
.even
007E _LCD_en_write::
007E .dbline -1
007E .dbline 61
007E ;
007E ; }
007E ;
007E ; }
007E ;
007E ;
007E ;
007E .dbline 62
007E ; void out_485(unsigned char address,unsigned char *ptr)
007E AD9A sbi 0x15,5
0080 .dbline 63
0080 ; {unsigned char i;
0080 01E0 ldi R16,1
0082 10E0 ldi R17,0
0084 BFDF xcall _delay_nus
0086 .dbline 64
0086 ; n=0; //中断次数清0
0086 AD98 cbi 0x15,5
0088 .dbline -2
0088 L18:
0088 .dbline 0 ; func end
0088 0895 ret
008A .dbend
008A .dbfunc e LCD_write_command _LCD_write_command fV
008A ; command -> R20
.even
008A _LCD_write_command::
008A 0E940000 xcall push_gset1
008E 402F mov R20,R16
0090 .dbline -1
0090 .dbline 68
0090 ; inbox[0]=0; //收件箱地址清0
0090 ; //请更新准备发送的数据
0090 ; //send[1]=?
0090 ; //......
0090 .dbline 82
0090 ; //send[n]=?
0090 ; send[0]=address; //改变这个地址就可以实现与某个从机对话
0090 ; for(i=1;i<amount-1;i++)send[i]=*ptr++;//把发送的数据方到发信箱
0090 ;
0090 ; send[amount-1]=crc8(send,amount-1); //计算发件箱的crc8校验码
0090 ;
0090 ; usart_out(send,amount); //将发件箱的数据send[]发送出去;
0090 ;
0090 ; //等待,从机接收到数据后会回复数据的,如果是10个字节数据量,不能少于13ms!!!
0090 ; //这个时间由人工计算,要考虑从机由于各种中断延长回复时间的可能
0090 ;
0090 ; delay_nms(15);
0090 ; }
0090 ;
0090 00E1 ldi R16,16
0092 10E0 ldi R17,0
0094 B7DF xcall _delay_nus
0096 .dbline 83
0096 ;
0096 AC98 cbi 0x15,4
0098 .dbline 84
0098 ;
0098 85B3 in R24,0x15
009A 807F andi R24,240
009C 85BB out 0x15,R24
009E .dbline 85
009E ; void main(void)
009E 842F mov R24,R20
00A0 8295 swap R24
00A2 8F70 andi R24,#0x0F
00A4 8F70 andi R24,15
00A6 25B2 in R2,0x15
00A8 282A or R2,R24
00AA 25BA out 0x15,R2
00AC .dbline 86
00AC ; { unsigned char key[8],i,address,j;
00AC E8DF xcall _LCD_en_write
00AE .dbline 87
00AE ; usart_init(); //串口初始化
00AE 85B3 in R24,0x15
00B0 807F andi R24,240
00B2 85BB out 0x15,R24
00B4 .dbline 88
00B4 ; UCSRA=0x00; //主机关闭地址筛选功能(多机通讯功能)
00B4 842F mov R24,R20
00B6 8F70 andi R24,15
00B8 25B2 in R2,0x15
00BA 282A or R2,R24
00BC 25BA out 0x15,R2
00BE .dbline 89
00BE ; LCD_init();//液晶初始化
00BE DFDF xcall _LCD_en_write
00C0 .dbline -2
00C0 L19:
00C0 0E940000 xcall pop_gset1
00C4 .dbline 0 ; func end
00C4 0895 ret
00C6 .dbsym r command 20 c
00C6 .dbend
00C6 .dbfunc e LCD_write_data _LCD_write_data fV
00C6 ; data -> R20
.even
00C6 _LCD_write_data::
00C6 0E940000 xcall push_gset1
00CA 402F mov R20,R16
00CC .dbline -1
00CC .dbline 95
00CC ; SEI(); //打开全局中断,需要macros.h支持
00CC ; LCD_write_string(0,0,"out:");
00CC ; LCD_write_string(0,1,"int:");
00CC ;
00CC ;
00CC ; while(1)
00CC .dbline 109
00CC ; {
00CC ; //-------------以下为测试语句------------------------------------
00CC ;
00CC ; if(flag_me)
00CC ; {
00CC ; LCD_write_string(7,1,inbox);
00CC ; flag_me=0;
00CC ; }
00CC ; i=get_key();
00CC ; switch (i)
00CC ; {
00CC ; case '+':{address=2;LCD_write_string(4,0,"2>>");}
00CC ; break;
00CC ; case '-':{address=3;LCD_write_string(4,0,"3>>");}
00CC 00E1 ldi R16,16
00CE 10E0 ldi R17,0
00D0 99DF xcall _delay_nus
00D2 .dbline 110
00D2 ; break;
00D2 AC9A sbi 0x15,4
00D4 .dbline 111
00D4 ; case '=':out_485(address,key);
00D4 85B3 in R24,0x15
00D6 807F andi R24,240
00D8 85BB out 0x15,R24
00DA .dbline 112
00DA ; break;
00DA 842F mov R24,R20
00DC 8295 swap R24
00DE 8F70 andi R24,#0x0F
00E0 8F70 andi R24,15
00E2 25B2 in R2,0x15
00E4 282A or R2,R24
00E6 25BA out 0x15,R2
00E8 .dbline 113
00E8 ; case 'C':{j=0;LCD_write_string(7,0," ");}
00E8 CADF xcall _LCD_en_write
00EA .dbline 115
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -