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

📄 485.lst

📁 AVR单片机的485通信参考程序
💻 LST
📖 第 1 页 / 共 3 页
字号:
(0114)  
(0115)   LCD_DATA_PORT&=0Xf0;        //清高四位
    00EA B385      IN	R24,0x15
    00EB 7F80      ANDI	R24,0xF0
    00EC BB85      OUT	0x15,R24
(0116)   LCD_DATA_PORT|=data&0x0f;   //写低四位
    00ED 2F84      MOV	R24,R20
    00EE 708F      ANDI	R24,0xF
    00EF B225      IN	R2,0x15
    00F0 2A28      OR	R2,R24
    00F1 BA25      OUT	0x15,R2
(0117)   LCD_en_write();
    00F2 DFC1      RCALL	_LCD_en_write
    00F3 940E026C  CALL	pop_gset1
    00F5 9508      RET
_LCD_set_xy:
  address              --> R20
  y                    --> R20
  x                    --> R22
    00F6 940E0267  CALL	push_gset2
    00F8 2F42      MOV	R20,R18
    00F9 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;
    00FA 2344      TST	R20
    00FB F419      BNE	0x00FF
    00FC 2F46      MOV	R20,R22
    00FD 5840      SUBI	R20,0x80
    00FE C002      RJMP	0x0101
(0127)     else   address = 0xc0 + x;
    00FF 2F46      MOV	R20,R22
    0100 5440      SUBI	R20,0x40
(0128)     LCD_write_command( address);
    0101 2F04      MOV	R16,R20
    0102 DFB7      RCALL	_LCD_write_command
    0103 940E025B  CALL	pop_gset2
    0105 9508      RET
_LCD_write_string:
  s                    --> R20
  Y                    --> R10
  X                    --> R22
    0106 940E0265  CALL	push_gset3
    0108 2EA2      MOV	R10,R18
    0109 2F60      MOV	R22,R16
    010A 814E      LDD	R20,Y+6
    010B 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 ); //写地址    
    010C 2D2A      MOV	R18,R10
    010D 2F06      MOV	R16,R22
    010E DFE7      RCALL	_LCD_set_xy
    010F C005      RJMP	0x0115
(0134)     while (*s)  // 写显示字符
(0135)     {
(0136)       LCD_write_data( *s );
    0110 01FA      MOVW	R30,R20
    0111 8100      LDD	R16,Z+0
    0112 DFC5      RCALL	_LCD_write_data
(0137)       s ++;
    0113 5F4F      SUBI	R20,0xFF
    0114 4F5F      SBCI	R21,0xFF
    0115 01FA      MOVW	R30,R20
    0116 8020      LDD	R2,Z+0
    0117 2022      TST	R2
    0118 F7B9      BNE	0x0110
    0119 940E025E  CALL	pop_gset3
    011B 9508      RET
_LCD_write_char:
  data                 --> Y+4
  Y                    --> R22
  X                    --> R20
    011C 940E0267  CALL	push_gset2
    011E 2F62      MOV	R22,R18
    011F 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 ); //写地址
    0120 2F26      MOV	R18,R22
    0121 2F04      MOV	R16,R20
    0122 DFD3      RCALL	_LCD_set_xy
(0145)   LCD_write_data( data);
    0123 810C      LDD	R16,Y+4
    0124 DFB3      RCALL	_LCD_write_data
    0125 940E025B  CALL	pop_gset2
    0127 9508      RET
FILE: D:\mojinpan\485\485_slave2\usart.h
(0001) #define BAUDRATE        9600	//波特率
(0002) #define F_CPU 			8000000
(0003) 
(0004) 
(0005) //波特率9600/9个数据位/1个停止位/奇校验/收发开启/接收中断 
(0006) void usart_init(void) 
(0007) { 
(0008) UCSR1A=0x01; 
_usart_init:
    0128 E081      LDI	R24,1
    0129 9380009B  STS	0x9B,R24
(0009) UCSR1B=0x9C; 
    012B E98C      LDI	R24,0x9C
    012C 9380009A  STS	0x9A,R24
(0010) UCSR1C=0x36; 
    012E E386      LDI	R24,0x36
    012F 9380009D  STS	0x9D,R24
(0011) UBRR1L= (F_CPU/BAUDRATE/16-1)%256;
    0131 E383      LDI	R24,0x33
    0132 93800099  STS	0x99,R24
(0012) UBRR1H= (F_CPU/BAUDRATE/16-1)/256; 
    0134 2422      CLR	R2
    0135 92200098  STS	0x98,R2
(0013) 
(0014) PORTE&=~0x80; //MAX485平时工作在接收状态 
    0137 981F      CBI	0x03,7
(0015) DDRE|=0x80; 
    0138 9A17      SBI	0x02,7
    0139 9508      RET
_usart_out:
  i                    --> R20
  n                    --> R22
  datas                --> R10
    013A 940E0265  CALL	push_gset3
    013C 2F62      MOV	R22,R18
    013D 0158      MOVW	R10,R16
(0016) } 
(0017) 
(0018) //----------------------------------------------------------- 
(0019) //从数组datas[]的首地址开始发送amount个数据,其中第0个数据是地址帧,其他是数据帧 
(0020) void usart_out(unsigned char *datas,unsigned char n) 
(0021) { 
(0022)  unsigned char i=0; 
    013E 2744      CLR	R20
(0023)  PORTE|=0x80; //使MAX485处于发送状态  
    013F 9A1F      SBI	0x03,7
    0140 C021      RJMP	0x0162
(0024)  while(i<n) //一共发送amount个数据 
(0025)   { 
(0026)    if(i==0) UCSR1B|=0x01; 
    0141 2344      TST	R20
    0142 F431      BNE	0x0149
    0143 9180009A  LDS	R24,0x9A
    0145 6081      ORI	R24,1
    0146 9380009A  STS	0x9A,R24
    0148 C005      RJMP	0x014E
(0027)    else UCSR1B&=0xfe; 
    0149 9180009A  LDS	R24,0x9A
    014B 7F8E      ANDI	R24,0xFE
    014C 9380009A  STS	0x9A,R24
(0028)    UDR1=*(datas+i); //装载数据开始发送 
    014E 2FE4      MOV	R30,R20
    014F 27FF      CLR	R31
    0150 0DEA      ADD	R30,R10
    0151 1DFB      ADC	R31,R11
    0152 8020      LDD	R2,Z+0
    0153 9220009C  STS	0x9C,R2
(0029)    while((UCSR1A&0x40)==0); //等待发送结束 
    0155 9020009B  LDS	R2,0x9B
    0157 FE26      SBRS	R2,6
    0158 CFFC      RJMP	0x0155
(0030)    UCSR1A|=0x40; //清除发送结束标志 
    0159 9180009B  LDS	R24,0x9B
    015B 6480      ORI	R24,0x40
    015C 9380009B  STS	0x9B,R24
(0031)    i++; //发送次数统计 
    015E 9543      INC	R20
(0032)    delay_nus(100);//每次发送必须有间隔,这个是最小值,实际情况可能还要加大
    015F E604      LDI	R16,0x64
    0160 E010      LDI	R17,0
    0161 DF15      RCALL	_delay_nus
    0162 1746      CP	R20,R22
    0163 F2E8      BCS	0x0141
(0033)   } 
(0034)  PORTE&=~0x80; //使MAX485处于接收状态
    0164 981F      CBI	0x03,7
    0165 940E025E  CALL	pop_gset3
    0167 9508      RET
_crc8:
  crc                  --> R20
  i                    --> R22
  len                  --> R18
  ptr                  --> R16
    0168 940E0267  CALL	push_gset2
FILE: D:\mojinpan\485\485_slave2\crc8.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; 
    016A 2744      CLR	R20
    016B C020      RJMP	0x018C
(0008) while(len--!=0) 
(0009) { 
(0010) for(i=1; i!=0; i*=2) 
    016C E061      LDI	R22,1
    016D C01A      RJMP	0x0188
(0011) { 
(0012) if((crc&1)!=0) {crc/=2; crc^=0x8C;} 
    016E FF40      SBRS	R20,0
    016F C009      RJMP	0x0179
    0170 9546      LSR	R20
    0171 E88C      LDI	R24,0x8C
    0172 E090      LDI	R25,0
    0173 2E24      MOV	R2,R20
    0174 2433      CLR	R3
    0175 2628      EOR	R2,R24
    0176 2639      EOR	R3,R25
    0177 2D42      MOV	R20,R2
    0178 C001      RJMP	0x017A
(0013) else crc/=2; 
    0179 9546      LSR	R20
(0014) if((*ptr&i)!=0) crc^=0x8C; 
    017A 01F8      MOVW	R30,R16
    017B 8020      LDD	R2,Z+0
    017C 2226      AND	R2,R22
    017D F039      BEQ	0x0185
    017E E88C      LDI	R24,0x8C
    017F E090      LDI	R25,0
    0180 2E24      MOV	R2,R20
    0181 2433      CLR	R3
    0182 2628      EOR	R2,R24
    0183 2639      EOR	R3,R25
    0184 2D42      MOV	R20,R2
    0185 E082      LDI	R24,2
    0186 9F86      MUL	R24,R22
    0187 2D60      MOV	R22,R0
    0188 2366      TST	R22
    0189 F721      BNE	0x016E
(0015) } 
(0016) ptr++; 
    018A 5F0F      SUBI	R16,0xFF
    018B 4F1F      SBCI	R17,0xFF
    018C 2E22      MOV	R2,R18
    018D 2433      CLR	R3
    018E 5021      SUBI	R18,1
    018F 2022      TST	R2
    0190 F6D9      BNE	0x016C
(0017) } 
(0018) return(crc); 
    0191 2F04      MOV	R16,R20
    0192 940E025B  CALL	pop_gset2
    0194 9508      RET
_RXC_Int:
  ERROR                --> R20
    0195 940E0280  CALL	push_lset
    0197 940E0269  CALL	push_gset1
    0199 9722      SBIW	R28,2
FILE: D:\mojinpan\485\485_slave2\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 <iom64v.h>
(0017) #include <macros.h> 
(0018) #include "1602.h" 
(0019) #include "delay.h" 
(0020) #include "usart.h" 
(0021) #include "crc8.h" //CRC校验函数就在这个文件里面 
(0022) 
(0023) #define amount 10 //设定通讯数据量(包括1个地址帧,n个数据帧,1个校验帧) 
(0024) #define address 2 //请在这里设定本机地址 
(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: 31
(0034) void RXC_Int(void) 		  		   	     //接收中断 
(0035) { 
(0036)  unsigned char ERROR=0; 
    019A 2744      CLR	R20
(0037) 
(0038)  if( UCSR1A&0x04 || UCSR1A&0x10 ) ERROR=1; //记录奇偶效验错误或者帧错误 
    019B 9020009B  LDS	R2,0x9B
    019D FC22      SBRC	R2,2
    019E C004      RJMP	0x01A3
    019F 9020009B  LDS	R2,0x9B
    01A1 FE24      SBRS	R2,4
    01A2 C001      RJMP	0x01A4
    01A3 E041      LDI	R20,1
(0039)  inbox[n]=UDR1; 	   			  			 //把接收到的数据保存到收件箱 
    01A4 E18C      LDI	R24,0x1C
    01A5 E091      LDI	R25,1
    01A6 91E00100  LDS	R30,n

⌨️ 快捷键说明

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