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

📄 rs485.lst

📁 本文提出了基于MCU和RS485总线的嵌入式系统的常用设计方法
💻 LST
📖 第 1 页 / 共 3 页
字号:
    00C8 708F      ANDI	R24,0xF
    00C9 708F      ANDI	R24,0xF
    00CA B225      IN	R2,0x15
    00CB 2A28      OR	R2,R24
    00CC BA25      OUT	0x15,R2
(0113)   LCD_en_write();
    00CD DFCA      RCALL	_LCD_en_write
(0114)  
(0115)   LCD_DATA_PORT&=0Xf0;        //清高四位
    00CE B385      IN	R24,0x15
    00CF 7F80      ANDI	R24,0xF0
    00D0 BB85      OUT	0x15,R24
(0116)   LCD_DATA_PORT|=data&0x0f;   //写低四位
    00D1 2F84      MOV	R24,R20
    00D2 708F      ANDI	R24,0xF
    00D3 B225      IN	R2,0x15
    00D4 2A28      OR	R2,R24
    00D5 BA25      OUT	0x15,R2
(0117)   LCD_en_write();
    00D6 DFC1      RCALL	_LCD_en_write
    00D7 940E0222  CALL	pop_gset1
    00D9 9508      RET
_LCD_set_xy:
  address              --> R20
  y                    --> R20
  x                    --> R22
    00DA 940E021D  CALL	push_gset2
    00DC 2F42      MOV	R20,R18
    00DD 2F60      MOV	R22,R16
(0118) 
(0119)   
(0120) }
(0121) 
(0122) 
(0123) void LCD_set_xy( unsigned char x, unsigned char y )  //写地址函数
(0124) {
(0125)     unsigned char address;
(0126)     if (y == 0) address = 0x80 + x;
    00DE 2344      TST	R20
    00DF F419      BNE	0x00E3
    00E0 2F46      MOV	R20,R22
    00E1 5840      SUBI	R20,0x80
    00E2 C002      RJMP	0x00E5
(0127)     else   address = 0xc0 + x;
    00E3 2F46      MOV	R20,R22
    00E4 5440      SUBI	R20,0x40
(0128)     LCD_write_command( address);
    00E5 2F04      MOV	R16,R20
    00E6 DFB7      RCALL	_LCD_write_command
    00E7 940E0211  CALL	pop_gset2
    00E9 9508      RET
_LCD_write_string:
  s                    --> R20
  Y                    --> R10
  X                    --> R22
    00EA 940E021B  CALL	push_gset3
    00EC 2EA2      MOV	R10,R18
    00ED 2F60      MOV	R22,R16
    00EE 814E      LDD	R20,Y+6
    00EF 815F      LDD	R21,Y+7
(0129) }
(0130)   
(0131) void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) //列x=0~15,行y=0,1
(0132) {
(0133)     LCD_set_xy( X, Y ); //写地址    
    00F0 2D2A      MOV	R18,R10
    00F1 2F06      MOV	R16,R22
    00F2 DFE7      RCALL	_LCD_set_xy
    00F3 C005      RJMP	0x00F9
(0134)     while (*s)  // 写显示字符
(0135)     {
(0136)       LCD_write_data( *s );
    00F4 01FA      MOVW	R30,R20
    00F5 8100      LDD	R16,Z+0
    00F6 DFC5      RCALL	_LCD_write_data
(0137)       s ++;
    00F7 5F4F      SUBI	R20,0xFF
    00F8 4F5F      SBCI	R21,0xFF
    00F9 01FA      MOVW	R30,R20
    00FA 8020      LDD	R2,Z+0
    00FB 2022      TST	R2
    00FC F7B9      BNE	0x00F4
    00FD 940E0214  CALL	pop_gset3
    00FF 9508      RET
_LCD_write_char:
  data                 --> Y+4
  Y                    --> R22
  X                    --> R20
    0100 940E021D  CALL	push_gset2
    0102 2F62      MOV	R22,R18
    0103 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 ); //写地址
    0104 2F26      MOV	R18,R22
    0105 2F04      MOV	R16,R20
    0106 DFD3      RCALL	_LCD_set_xy
(0145)   LCD_write_data( data);
    0107 810C      LDD	R16,Y+4
    0108 DFB3      RCALL	_LCD_write_data
    0109 940E0211  CALL	pop_gset2
    010B 9508      RET
FILE: F:\ChengXuCunFang\ChengXU\AVR单片机程序存放\max485多机通讯1\新建文件夹\485_slave3\usart.h
(0001) #define BAUDRATE        9600	//波特率
(0002) #define F_CPU 			7327800
(0003) 
(0004) 
(0005) //波特率9600/9个数据位/1个停止位/奇校验/收发开启/接收中断 
(0006) void usart_init(void) 
(0007) { 
(0008)  UCSRA=0x01;//多机通讯模式(MPCM=1) 
_usart_init:
    010C E081      LDI	R24,1
    010D B98B      OUT	0x0B,R24
(0009)  UCSRB=0x9C; 
    010E E98C      LDI	R24,0x9C
    010F B98A      OUT	0x0A,R24
(0010)  UCSRC=0xB6; 
    0110 EB86      LDI	R24,0xB6
    0111 BD80      OUT	0x20,R24
(0011)  UBRRL= (F_CPU/BAUDRATE/16-1)%256;
    0112 E28E      LDI	R24,0x2E
    0113 B989      OUT	0x09,R24
(0012)  UBRRH= (F_CPU/BAUDRATE/16-1)/256; 
    0114 2422      CLR	R2
    0115 BC20      OUT	0x20,R2
(0013)  PORTD &=~(1<<PD4);
    0116 9894      CBI	0x12,4
(0014)  DDRD|=(1<<PD4); 
    0117 9A8C      SBI	0x11,4
    0118 9508      RET
_usart_out:
  i                    --> R20
  n                    --> R22
  datas                --> R10
    0119 940E021B  CALL	push_gset3
    011B 2F62      MOV	R22,R18
    011C 0158      MOVW	R10,R16
(0015) } 
(0016) 
(0017) //----------------------------------------------------------- 
(0018) //从数组datas[]的首地址开始发送amount个数据,其中第0个数据是地址帧,其他是数据帧 
(0019) void usart_out(unsigned char *datas,unsigned char n) 
(0020) { 
(0021)  unsigned char i=0; 
    011D 2744      CLR	R20
(0022)  //PORTD|=0x08; //使MAX485处于发送状态 
(0023)  PORTD |=(1<<PD4);
    011E 9A94      SBI	0x12,4
    011F C014      RJMP	0x0134
(0024)  while(i<n )//一共发送amount个数据 
(0025)   { 
(0026)    if(i==0) UCSRB|=0x01; 
    0120 2344      TST	R20
    0121 F411      BNE	0x0124
    0122 9A50      SBI	0x0A,0
    0123 C003      RJMP	0x0127
(0027)    else UCSRB&=0xfe; 
    0124 B18A      IN	R24,0x0A
    0125 7F8E      ANDI	R24,0xFE
    0126 B98A      OUT	0x0A,R24
(0028)    UDR=*(datas+i); //装载数据开始发送 
    0127 2FE4      MOV	R30,R20
    0128 27FF      CLR	R31
    0129 0DEA      ADD	R30,R10
    012A 1DFB      ADC	R31,R11
    012B 8020      LDD	R2,Z+0
    012C B82C      OUT	0x0C,R2
(0029)    while((UCSRA&0x40)==0); //等待发送结束 
    012D 9B5E      SBIS	0x0B,6
    012E CFFE      RJMP	0x012D
(0030)    UCSRA|=0x40; //清除发送结束标志 
    012F 9A5E      SBI	0x0B,6
(0031)    i++; //发送次数统计
    0130 9543      INC	R20
(0032)    delay_nus(100);//每次发送必须有间隔,这个是最小值,实际情况可能还要加大
    0131 E604      LDI	R16,0x64
    0132 E010      LDI	R17,0
    0133 DF27      RCALL	_delay_nus
    0134 1746      CP	R20,R22
    0135 F350      BCS	0x0120
(0033)   } 
(0034)   PORTD &=~(1<<PD4);
    0136 9894      CBI	0x12,4
    0137 940E0214  CALL	pop_gset3
    0139 9508      RET
_crc8:
  crc                  --> R20
  i                    --> R22
  len                  --> R18
  ptr                  --> R16
    013A 940E021D  CALL	push_gset2
FILE: F:\ChengXuCunFang\ChengXU\AVR单片机程序存放\max485多机通讯1\新建文件夹\485_slave3\crc.h
(0001) //--------------------------------------------------------------------------------- 
(0002) //crc8校验程序 
(0003) //--------------------------------------------------------------------------------- 
(0004) unsigned char crc8(unsigned char *ptr, unsigned char len) 
(0005) { 
(0006) unsigned char i; 
(0007) unsigned char crc=0; 
    013C 2744      CLR	R20
    013D C020      RJMP	0x015E
(0008) while(len--!=0) 
(0009) { 
(0010) for(i=1; i!=0; i*=2) 
    013E E061      LDI	R22,1
    013F C01A      RJMP	0x015A
(0011) { 
(0012) if((crc&1)!=0) {crc/=2; crc^=0x8C;} 
    0140 FF40      SBRS	R20,0
    0141 C009      RJMP	0x014B
    0142 9546      LSR	R20
    0143 E88C      LDI	R24,0x8C
    0144 E090      LDI	R25,0
    0145 2E24      MOV	R2,R20
    0146 2433      CLR	R3
    0147 2628      EOR	R2,R24
    0148 2639      EOR	R3,R25
    0149 2D42      MOV	R20,R2
    014A C001      RJMP	0x014C
(0013) else crc/=2; 
    014B 9546      LSR	R20
(0014) if((*ptr&i)!=0) crc^=0x8C; 
    014C 01F8      MOVW	R30,R16
    014D 8020      LDD	R2,Z+0
    014E 2226      AND	R2,R22
    014F F039      BEQ	0x0157
    0150 E88C      LDI	R24,0x8C
    0151 E090      LDI	R25,0
    0152 2E24      MOV	R2,R20
    0153 2433      CLR	R3
    0154 2628      EOR	R2,R24
    0155 2639      EOR	R3,R25
    0156 2D42      MOV	R20,R2
    0157 E082      LDI	R24,2
    0158 9F86      MUL	R24,R22
    0159 2D60      MOV	R22,R0
    015A 2366      TST	R22
    015B F721      BNE	0x0140
(0015) } 
(0016) ptr++; 
    015C 5F0F      SUBI	R16,0xFF
    015D 4F1F      SBCI	R17,0xFF
    015E 2E22      MOV	R2,R18
    015F 2433      CLR	R3
    0160 5021      SUBI	R18,1
    0161 2022      TST	R2
    0162 F6D9      BNE	0x013E
(0017) } 
(0018) return(crc); 
    0163 2F04      MOV	R16,R20
    0164 940E0211  CALL	pop_gset2
    0166 9508      RET
_RXC_Int:
  ERROR                --> R20
    0167 940E0236  CALL	push_lset
    0169 940E021F  CALL	push_gset1
FILE: F:\ChengXuCunFang\ChengXU\AVR单片机程序存放\max485多机通讯1\新建文件夹\485_slave3\main.c
(0001) /*******************************************************************************
(0002)                            485多机通讯
(0003) --------------------------------------------------------------------------------
(0004) 通讯规则: 
(0005) 1:时钟7.3728 MHz/波特率9600/9个数据位/奇校验/1个停止位/硬件多机通讯功能/ 
(0006) 2:通讯连接采用硬件MAX485,双向单工 
(0007) 3:每个上行/下行的数据包的字节个数都是一样的(通讯数据量) 
(0008) 4:每个上行/下行的数据包都采用CRC8校验 
(0009) 5:数据接收采用中断+查询的方式 
(0010) 6:总是由主机向从机发送一个数据包,从机收到数据包后向主机回复一个数据包 
(0011) 7:不管是主机还是从机,如果收到的数据包有任何错误,都将丢弃该数据包,等效于没有接收 
(0012) 8:从机之间不能相互通讯,必须通过主机才能交换数据 
(0013) 9:无效地址是0,主机地址是1,从机地址是2.3.4......广播地址是255 
(0014) ********************************************************************************/ 
(0015) 
(0016) #include <iom16v.h>
(0017) #include <macros.h> 
(0018) #include "1602.h" 
(0019) #include "delay.h" 
(0020) #include "usart.h" 
(0021) #include "crc.h" //CRC校验函数就在这个文件里面 
(0022) 
(0023) #define amount 10 //设定通讯数据量(包括1个地址帧,n个数据帧,1个校验帧) 
(0024) #define address 3 //请在这里设定本机地址 
(0025) 
(0026) unsigned char send[amount]; //发件箱 
(0027) unsigned char inbox[amount]; //收件箱 
(0028) unsigned char n=0; //记忆中断次数 
(0029) unsigned char flag_me=0;     //个人数据标志
(0030) unsigned char flag_all=0;    //广播数据标志
(0031) 
(0032) //-------------------从机接收子程序-------------------------------- 
(0033) #pragma interrupt_handler RXC_Int: 12
(0034) void RXC_Int(void) 		  		   	     //接收中断 
(0035) { 
(0036)  unsigned char ERROR=0; 
    016B 2744      CLR	R20
(0037)  
(0038)  if( UCSRA&0x04 || UCSRA&0x10 ) ERROR=1; //记录奇偶效验错误或者帧错误 
    016C 995A      SBIC	0x0B,2
    016D C002      RJMP	0x0170
    016E 9B5C      SBIS	0x0B,4

⌨️ 快捷键说明

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