⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mater.lst

📁 本文提出了基于MCU和RS485总线的嵌入式系统的常用设计方法
💻 LST
📖 第 1 页 / 共 2 页
字号:
_LCD_write_char:
  data                 --> Y+4
  Y                    --> R22
  X                    --> R20
    00F8 940E01E8  CALL	push_gset2
    00FA 2F62      MOV	R22,R18
    00FB 2F40      MOV	R20,R16
(0138)     }
(0139)       
(0140) }
(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 940E01DC  CALL	pop_gset2
    0103 9508      RET
FILE: F:\ChengXuCunFang\ChengXU\AVR单片机程序存放\max485多机通讯1\主机\main.c
(0001) /* 通讯规则: 
(0002)   01:时钟7.3728 MHz/波特率9600/9个数据位/奇校验/1个停止位/硬件多机通讯功能/ 
(0003)   02:通讯连接采用硬件MAX485,双向单工
(0004)   03:MAX485的RE/DE并联接到单片机的PD2脚(高电平发送/低电平接收)
(0005)   04:所有MAX485的A脚并联/B脚并联/D脚接TXD/R脚接RXD
(0006)   05:每个上行/下行的数据包的字节个数都是一样的(通讯数据量) 
(0007)   06:数据包格式: 地址_数据1_数据2_数据3_数据n_CRC8校验码
(0008)   07:所有单元的数据接收都是采用中断+查询的方式 
(0009)   08:总是由主机向从机下发一个数据包,从机收到数据包并校验正确后向主机回复一个数据包 
(0010)   09:不管是主机还是从机,如果收到的数据包有任何错误,都将丢弃该数据包,等效于没有接收 
(0011)   10:通讯采用主机轮询方式,从机之间不能相互通讯,必须通过主机才能交换数据 
(0012)   11:无效地址是0,主机地址是1,从机地址是11.12.13...广播地址是255 
(0013) */
(0014) 
(0015) #include<iom16v.h>
(0016) #include <macros.h> 
(0017) #include "1602.h"
(0018) #include "delay.h"
(0019) 
(0020) #define amount   10
(0021) #define address  1
(0022) 
(0023) unsigned char send[amount];
(0024) unsigned char inbox[amount];
(0025) unsigned char n=0;//记忆叫断接收的次数
(0026) 
(0027) 
(0028) 
(0029)   //end 
(0030) 
(0031) //波特率9600/9个数据位/1个停止位/奇校验/收发开启/接收中断/地址过滤 
(0032) void usart_init(void) 
(0033) {   
(0034)   UCSRA=0x01; 
_usart_init:
    0104 E081      LDI	R24,1
    0105 B98B      OUT	0x0B,R24
(0035)   UCSRB=0x9C; 
    0106 E98C      LDI	R24,0x9C
    0107 B98A      OUT	0x0A,R24
(0036)   UCSRC=0xB6; 
    0108 EB86      LDI	R24,0xB6
    0109 BD80      OUT	0x20,R24
(0037)   UBRRH=0x00; 
    010A 2422      CLR	R2
    010B BC20      OUT	0x20,R2
(0038)   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 940E01E8  CALL	push_gset2
(0039) }
(0040) 
(0041) unsigned char crc8(unsigned char *ptr, unsigned char len)   
(0042) {  
(0043)   unsigned char i;  
(0044)   unsigned char crc=0;  
    0111 2744      CLR	R20
    0112 C020      RJMP	0x0133
(0045)   while(len--!=0)   
(0046)    {  
(0047)      for(i=1; i!=0; i*=2)  
    0113 E061      LDI	R22,1
    0114 C01A      RJMP	0x012F
(0048)       {  
(0049)         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
(0050)         else crc/=2;  
    0120 9546      LSR	R20
(0051)         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
(0052)        }   
(0053)      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
(0054)     }  
(0055)   return(crc);  
    0138 2F04      MOV	R16,R20
    0139 940E01DC  CALL	pop_gset2
    013B 9508      RET
_RXC_Int:
    013C 922A      ST	R2,-Y
    013D 938A      ST	R24,-Y
    013E 939A      ST	R25,-Y
    013F 93EA      ST	R30,-Y
    0140 93FA      ST	R31,-Y
    0141 B62F      IN	R2,0x3F
    0142 922A      ST	R2,-Y
(0056) }
(0057) 
(0058) #pragma interrupt_handler RXC_Int: 12
(0059) void RXC_Int(void) 
(0060) {
(0061)  if( UCSRA&28 ){ n=UDR; n=0; UCSRA|=0x01; } else          //接收出错就重新打开地址帧筛选功能 
    0143 B18B      IN	R24,0x0B
    0144 718C      ANDI	R24,0x1C
    0145 F041      BEQ	0x014E
    0146 B02C      IN	R2,0x0C
    0147 92200060  STS	n,R2
    0149 2422      CLR	R2
    014A 92200060  STS	n,R2
    014C 9A58      SBI	0x0B,0
    014D C01C      RJMP	0x016A
(0062)   {
(0063)     if( UCSRB&2  ) n=0;                                    //检测到地址信息时计数清零
    014E 9B51      SBIS	0x0A,1
    014F C003      RJMP	0x0153
    0150 2422      CLR	R2
    0151 92200060  STS	n,R2
(0064)     inbox[n]=UDR;  n++;                                    //把接收到的数据保存到收件箱   
    0153 E68C      LDI	R24,0x6C
    0154 E090      LDI	R25,0
    0155 91E00060  LDS	R30,n
    0157 27FF      CLR	R31
    0158 0FE8      ADD	R30,R24
    0159 1FF9      ADC	R31,R25
    015A B02C      IN	R2,0x0C
    015B 8220      STD	Z+0,R2
    015C 91800060  LDS	R24,n
    015E 5F8F      SUBI	R24,0xFF
    015F 93800060  STS	n,R24
(0065)     if( inbox[0]==address ) UCSRA&=254; else UCSRA|=0x01;  //地址筛选  
    0161 9180006C  LDS	R24,inbox
    0163 3081      CPI	R24,1
    0164 F421      BNE	0x0169
    0165 B18B      IN	R24,0x0B
    0166 7F8E      ANDI	R24,0xFE
    0167 B98B      OUT	0x0B,R24
    0168 C001      RJMP	0x016A
    0169 9A58      SBI	0x0B,0
(0066)   }
    016A 9029      LD	R2,Y+
    016B BE2F      OUT	0x3F,R2
    016C 91F9      LD	R31,Y+
    016D 91E9      LD	R30,Y+
    016E 9199      LD	R25,Y+
    016F 9189      LD	R24,Y+
    0170 9029      LD	R2,Y+
    0171 9518      RETI
_usart_out:
  i                    --> R20
  n                    --> R18
  datas                --> R16
    0172 940E01EA  CALL	push_gset1
(0067) }  
(0068) 
(0069) void usart_out(unsigned char *datas,unsigned char n) 
(0070) { 
(0071)   unsigned char i=0;   
    0174 2744      CLR	R20
(0072)   PORTD |=(1<<PD4);                                        //使MAX485处于发送状态 
    0175 9A94      SBI	0x12,4
    0176 C011      RJMP	0x0188
(0073)   while(i<n)                                               //一共发送n个数据 
(0074)   {   
(0075)     if(i==0) UCSRB|=1; else UCSRB&=254;    
    0177 2344      TST	R20
    0178 F411      BNE	0x017B
    0179 9A50      SBI	0x0A,0
    017A C003      RJMP	0x017E
    017B B18A      IN	R24,0x0A
    017C 7F8E      ANDI	R24,0xFE
    017D B98A      OUT	0x0A,R24
(0076)     UDR=*(datas+i);                                        //装载数据开始发送  
    017E 2FE4      MOV	R30,R20
    017F 27FF      CLR	R31
    0180 0FE0      ADD	R30,R16
    0181 1FF1      ADC	R31,R17
    0182 8020      LDD	R2,Z+0
    0183 B82C      OUT	0x0C,R2
(0077)     while((UCSRA&64)==0);                                  //等待发送结束 
    0184 9B5E      SBIS	0x0B,6
    0185 CFFE      RJMP	0x0184
(0078)     UCSRA|=64;                                             //清除发送结束标志 
    0186 9A5E      SBI	0x0B,6
(0079)     i++;                                                   //发送次数统计 
    0187 9543      INC	R20
    0188 1742      CP	R20,R18
    0189 F368      BCS	0x0177
(0080)   }  
(0081)   PORTD&=~(1<<PD4);                                        //使MAX485处于接收状态 
    018A 9894      CBI	0x12,4
    018B 940E01ED  CALL	pop_gset1
    018D 9508      RET
_main:
    018E 9722      SBIW	R28,2
(0082) } 
(0083) void main()
(0084) {
(0085)  usart_init(); 
    018F DF74      RCALL	_usart_init
(0086)  LCD_init();   //液晶初始化
    0190 DEEA      RCALL	_LCD_init
(0087)  DDRD |=(1<<PD4);
    0191 9A8C      SBI	0x11,4
(0088)  DDRA |=0x07;
    0192 B38A      IN	R24,0x1A
    0193 6087      ORI	R24,7
    0194 BB8A      OUT	0x1A,R24
(0089)  SEI();        //打开全局中断,需要macros.h支持
    0195 9478      BSET	7
(0090)  LCD_write_string(0,0,"Send:");
    0196 E686      LDI	R24,0x66
    0197 E090      LDI	R25,0
    0198 8399      STD	Y+1,R25
    0199 8388      STD	Y+0,R24
    019A 2722      CLR	R18
    019B 2700      CLR	R16
    019C DF45      RCALL	_LCD_write_string
(0091)  LCD_write_string(0,1,"Rev:");
    019D E681      LDI	R24,0x61
    019E E090      LDI	R25,0
    019F 8399      STD	Y+1,R25
    01A0 8388      STD	Y+0,R24
    01A1 E021      LDI	R18,1
    01A2 2700      CLR	R16
    01A3 DF3E      RCALL	_LCD_write_string
    01A4 C034      RJMP	0x01D9
(0092)  while(1){
(0093)     send[3]=9;                     //更新发件箱的数据(测试代码)
    01A5 E089      LDI	R24,0x9
    01A6 93800079  STS	send+3,R24
(0094)     send[0]=11;                                            //指向从机地址
    01A8 E08B      LDI	R24,0xB
    01A9 93800076  STS	send,R24
(0095)     send[amount-1]=crc8(send,amount-1);                    //计算发件箱数据的crc8校验码 
    01AB E029      LDI	R18,0x9
    01AC E706      LDI	R16,0x76
    01AD E010      LDI	R17,0
    01AE DF60      RCALL	_crc8
    01AF 9300007F  STS	0x7F,R16
(0096)     usart_out(send,amount);                                //将发件箱的数据send[]发送出去; 
    01B1 E02A      LDI	R18,0xA
    01B2 E706      LDI	R16,0x76
    01B3 E010      LDI	R17,0
    01B4 DFBD      RCALL	_usart_out
(0097)     LCD_write_string(5,0,send);
    01B5 E786      LDI	R24,0x76
    01B6 E090      LDI	R25,0
    01B7 8399      STD	Y+1,R25
    01B8 8388      STD	Y+0,R24
    01B9 2722      CLR	R18
    01BA E005      LDI	R16,5
    01BB DF26      RCALL	_LCD_write_string
(0098)     n=0;                                                   //计数复位,准备接收新数据
    01BC 2422      CLR	R2
    01BD 92200060  STS	n,R2
(0099)     delay_nms(15);                                          //等待从机回复数据,这个时间要计算好
    01BF E00F      LDI	R16,0xF
    01C0 E010      LDI	R17,0
    01C1 DEAA      RCALL	_delay_nms
(0100)     
(0101)     if(n==amount && inbox[amount-1]==crc8(inbox,amount-1)) //接收正确处理与测试
    01C2 91800060  LDS	R24,n
    01C4 308A      CPI	R24,0xA
    01C5 F471      BNE	0x01D4
    01C6 E029      LDI	R18,0x9
    01C7 E60C      LDI	R16,0x6C
    01C8 E010      LDI	R17,0
    01C9 DF45      RCALL	_crc8
    01CA 90200075  LDS	R2,0x75
    01CC 1620      CP	R2,R16
    01CD F431      BNE	0x01D4
(0102)     {  
(0103)       PORTA|=(1<<PA1); delay_nms(10); PORTA&=~(1<<PA1);
    01CE 9AD9      SBI	0x1B,1
    01CF E00A      LDI	R16,0xA
    01D0 E010      LDI	R17,0
    01D1 DE9A      RCALL	_delay_nms
    01D2 98D9      CBI	0x1B,1
(0104)     }
    01D3 C005      RJMP	0x01D9
(0105)     else                                                   //接收错误处理与测试
(0106)     {
(0107)       PORTA|=(1<<PA2); delay_nms(10); PORTA&=~(1<<PA2);
FILE: <library>
    01D4 9ADA      SBI	0x1B,2
    01D5 E00A      LDI	R16,0xA
    01D6 E010      LDI	R17,0
    01D7 DE94      RCALL	_delay_nms
    01D8 98DA      CBI	0x1B,2
    01D9 CFCB      RJMP	0x01A5
    01DA 9622      ADIW	R28,2
    01DB 9508      RET
pop_gset2:
    01DC E0E2      LDI	R30,2
    01DD 940C01EE  JMP	pop
pop_gset3:
    01DF E0E4      LDI	R30,4
    01E0 940C01EE  JMP	pop
push_gset5:
    01E2 92FA      ST	R15,-Y
    01E3 92EA      ST	R14,-Y
push_gset4:
    01E4 92DA      ST	R13,-Y
    01E5 92CA      ST	R12,-Y
push_gset3:
    01E6 92BA      ST	R11,-Y
    01E7 92AA      ST	R10,-Y
push_gset2:
    01E8 937A      ST	R23,-Y
    01E9 936A      ST	R22,-Y
push_gset1:
    01EA 935A      ST	R21,-Y
    01EB 934A      ST	R20,-Y
    01EC 9508      RET
pop_gset1:
    01ED E0E1      LDI	R30,1
pop:
    01EE 9149      LD	R20,Y+
    01EF 9159      LD	R21,Y+
    01F0 FDE0      SBRC	R30,0
    01F1 9508      RET
    01F2 9169      LD	R22,Y+
    01F3 9179      LD	R23,Y+
    01F4 FDE1      SBRC	R30,1
    01F5 9508      RET
    01F6 90A9      LD	R10,Y+
    01F7 90B9      LD	R11,Y+
    01F8 FDE2      SBRC	R30,2
    01F9 9508      RET
    01FA 90C9      LD	R12,Y+
    01FB 90D9      LD	R13,Y+
    01FC FDE3      SBRC	R30,3
    01FD 9508      RET
    01FE 90E9      LD	R14,Y+
    01FF 90F9      LD	R15,Y+
    0200 9508      RET

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -