📄 11uart.lst
字号:
__text_start:
__start:
0046 EFCF LDI R28,0xFF
0047 E1D0 LDI R29,0x10
0048 BFCD OUT 0x3D,R28
0049 BFDE OUT 0x3E,R29
004A 51C0 SUBI R28,0x10
004B 40D0 SBCI R29,0
004C EA0A LDI R16,0xAA
004D 8308 STD Y+0,R16
004E 2400 CLR R0
004F E0E0 LDI R30,0
0050 E0F1 LDI R31,1
0051 E011 LDI R17,1
0052 30E0 CPI R30,0
0053 07F1 CPC R31,R17
0054 F011 BEQ 0x0057
0055 9201 ST R0,Z+
0056 CFFB RJMP 0x0052
0057 8300 STD Z+0,R16
0058 E8EC LDI R30,0x8C
0059 E0F0 LDI R31,0
005A E0A0 LDI R26,0
005B E0B1 LDI R27,1
005C E010 LDI R17,0
005D 38EC CPI R30,0x8C
005E 07F1 CPC R31,R17
005F F021 BEQ 0x0064
0060 95C8 LPM
0061 9631 ADIW R30,1
0062 920D ST R0,X+
0063 CFF9 RJMP 0x005D
0064 940E008D CALL _main
_exit:
0066 CFFF RJMP _exit
_delay_ms:
a --> R20
b --> R22
i --> R16
0067 940E0113 CALL push_gset2
FILE: E:\ICCAVR\project\AVRMEG~3\icc\011-UART-485\main.c
(0001) /*
(0002) 实验十一:
(0003)
(0004) RS485通信实险。
(0005) 1、UART0和UART1两个串口综合实验,串口以查询方式接收数据和发送数据。
(0006) UART0:任务A,每秒向串口0发送一个字节变化的数据,不接收数据。
(0007) UART1:任务B,从串口1接收数据,将收到的数据原样返回并显示在PB口。
(0008) 两个串口这间各知独立运行。
(0009) 可以将两路485信号并接到一起,这样就要以相互通信了。
(0010) 2、内部1 M晶振,程序采用单任务方式,软件延时。
(0011) 3、进行此实验请SW1两组跳针插上到485一边,插上LED短路块。
(0012) 4、实验中使用了两路RS485总线,通过此实验让大家了解RS485网络的基本应用。
(0013) 此实验原理及程序思路和上一个RS232实验完全相同,大家对照学习可以加
(0014) 深影像,并掌握RS485和RS232的使用方法。
(0015)
(0016) AVR mega128学习板
(0017) www.iccavr.com 阿发
(0018) 11:47 2007-10-14
(0019) */
(0020)
(0021) #include "iom128v.h"
(0022) #include "uart.h"
(0023)
(0024) /*延时函数*/
(0025) void delay_ms(unsigned char i) {
(0026)
(0027) unsigned char a, b;
(0028) for (a = 0; a < i; a++) {
0069 2744 CLR R20
006A C006 RJMP 0x0071
(0029) for (b = 1; b; b++);
006B E061 LDI R22,1
006C C001 RJMP 0x006E
006D 9563 INC R22
006E 2366 TST R22
006F F7E9 BNE 0x006D
0070 9543 INC R20
0071 1740 CP R20,R16
0072 F3C0 BCS 0x006B
0073 940E010A CALL pop_gset2
0075 9508 RET
(0030) }
(0031) }
(0032)
(0033) /*IO口初始化函数*/
(0034) void io_init(void) {
(0035)
(0036) DDRA = 0x00; /*方向输入*/
_io_init:
0076 2422 CLR R2
0077 BA2A OUT 0x1A,R2
(0037) PORTA = 0xFF; /*打开上拉*/
0078 EF8F LDI R24,0xFF
0079 BB8B OUT 0x1B,R24
(0038) DDRB = 0xFF; /*方向输出*/
007A BB87 OUT 0x17,R24
(0039) PORTB = 0xFF; /*输出高电平*/
007B BB88 OUT 0x18,R24
(0040) DDRC = 0x00; /*不用的IO口建议设置为输入带上拉*/
007C BA24 OUT 0x14,R2
(0041) PORTC = 0xFF;
007D BB85 OUT 0x15,R24
(0042) DDRD = 0x00;
007E BA21 OUT 0x11,R2
(0043) PORTD = 0xFF;
007F BB82 OUT 0x12,R24
(0044) DDRE = 0x00;
0080 B822 OUT 0x02,R2
(0045) PORTE = 0xFF;
0081 B983 OUT 0x03,R24
(0046) DDRF = 0x00;
0082 92200061 STS 0x61,R2
(0047) PORTF = 0xFF;
0084 93800062 STS 0x62,R24
(0048) DDRG = 0x18; /*设置两路RS485的方向控制脚为输出*/
0086 E188 LDI R24,0x18
0087 93800064 STS 0x64,R24
(0049) PORTG = 0xE7; /*设置两路RS485均为输入状态*/
0089 EE87 LDI R24,0xE7
008A 93800065 STS 0x65,R24
008C 9508 RET
(0050) }
(0051)
(0052) /*主函数*/
(0053) void main(void) {
(0054)
(0055) unsigned char j = 0;
_main:
j --> R20
i --> R22
temp --> R10
008D 2744 CLR R20
(0056) unsigned int i = 0;
008E 2766 CLR R22
008F 2777 CLR R23
(0057) unsigned int temp = 0;
0090 24AA CLR R10
0091 24BB CLR R11
(0058)
(0059) io_init();
0092 DFE3 RCALL _io_init
(0060) uart_init0();
0093 940E00B8 CALL _uart_init0
(0061) uart_init1();
0095 940E00D8 CALL _uart_init1
0097 C01E RJMP 0x00B6
(0062)
(0063) while (1) {
(0064) delay_ms(1);
0098 E001 LDI R16,1
0099 DFCD RCALL _delay_ms
(0065)
(0066) /*UART0部分*/
(0067) i ++;
009A 5F6F SUBI R22,0xFF
009B 4F7F SBCI R23,0xFF
(0068) if (i > 500) { /*500mS执行一次*/
009C EF84 LDI R24,0xF4
009D E091 LDI R25,1
009E 1786 CP R24,R22
009F 0797 CPC R25,R23
00A0 F430 BCC 0x00A7
(0069) uart_transmit0(j); /*发送变量j*/
00A1 2F04 MOV R16,R20
00A2 940E00C5 CALL _uart_transmit0
(0070) j ++;
00A4 9543 INC R20
(0071) i = 0;
00A5 2766 CLR R22
00A6 2777 CLR R23
(0072) }
(0073)
(0074) /*UART1部分*/
(0075) temp = uart_receive1(); /*接收数据*/
00A7 940E00FE CALL _uart_receive1
00A9 0158 MOVW R10,R16
(0076) if (temp != 0) { /*判断是否接收到数据*/
00AA 3000 CPI R16,0
00AB 0701 CPC R16,R17
00AC F049 BEQ 0x00B6
(0077) PORTB = ~(temp & 0xFF); /*显示低电平有效*/
00AD 01C5 MOVW R24,R10
00AE 7090 ANDI R25,0
00AF 9580 COM R24
00B0 9590 COM R25
00B1 BB88 OUT 0x18,R24
(0078) uart_transmit1(temp & 0xFF); /*发送收到的数据*/
00B2 2D0A MOV R16,R10
00B3 7010 ANDI R17,0
00B4 940E00E8 CALL _uart_transmit1
00B6 CFE1 RJMP 0x0098
00B7 9508 RET
FILE: E:\ICCAVR\project\AVRMEG~3\icc\011-UART-485\uart.c
(0001) /*
(0002) RS485网络驱动函数。
(0003)
(0004) RS485网络和普通的RS232网络从程序上来讲,维一的区别是就是有方向控制。
(0005) 数据发送时芯片需要工作在输出方式,这样数据才能被有效发出。
(0006) 不发送数据时一定要把RS485芯片设置为输入状态,否则会影响网络上其它设备。
(0007) */
(0008)
(0009) #include "iom128v.h"
(0010) #include <macros.h>
(0011)
(0012) /*串口初始化函数*/
(0013) void uart_init0(void) {
(0014)
(0015) UCSR0A = (1 << U2X0); /*倍速*/
_uart_init0:
00B8 E082 LDI R24,2
00B9 B98B OUT 0x0B,R24
(0016) UCSR0B = (1 << TXEN0) | (1 << RXEN0); /*允许接收和发送*/
00BA E188 LDI R24,0x18
00BB B98A OUT 0x0A,R24
(0017) UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /*8位数据、1 位停止、异步、无校验*/
00BC E086 LDI R24,6
00BD 93800095 STS 0x95,R24
(0018) UBRR0H = 0x00;
00BF 2422 CLR R2
00C0 92200090 STS 0x90,R2
(0019) UBRR0L = 12; /*波特率9600*/
00C2 E08C LDI R24,0xC
00C3 B989 OUT 0x09,R24
00C4 9508 RET
(0020) }
(0021)
(0022) /*数据发送,查询方式*/
(0023) void uart_transmit0(unsigned char i) {
(0024)
(0025) PORTG |= (1 << PG3); /*设置RS485为输出状态*/
_uart_transmit0:
i --> R16
00C5 91800065 LDS R24,0x65
00C7 6088 ORI R24,0x8
00C8 93800065 STS 0x65,R24
(0026) UDR0 = i; /*发送数据*/
00CA B90C OUT 0x0C,R16
(0027) while (!(UCSR0A & (1<<TXC0))); /*等待发送完成*/
00CB 9B5E SBIS 0x0B,6
00CC CFFE RJMP 0x00CB
(0028) UCSR0A |= (1 << TXC0); /*清除发送标志*/
00CD 9A5E SBI 0x0B,6
(0029) PORTG &= ~(1 << PG3); /*设置RS485为输入状态*/
00CE 91800065 LDS R24,0x65
00D0 7F87 ANDI R24,0xF7
00D1 93800065 STS 0x65,R24
00D3 9508 RET
(0030) }
(0031)
(0032) /*数据接收,等待查询方式*/
(0033) unsigned char uart_receive0(void) {
(0034)
(0035) while (!(UCSR0A & (1<<RXC0))); /* 等待接收数据*/
_uart_receive0:
00D4 9B5F SBIS 0x0B,7
00D5 CFFE RJMP _uart_receive0
(0036) return UDR0; /* 获取并返回数据*/
00D6 B10C IN R16,0x0C
00D7 9508 RET
(0037) }
(0038)
(0039) /*串口初始化函数*/
(0040) void uart_init1(void) {
(0041)
(0042) UCSR1A = (1 << U2X1); /*倍速*/
_uart_init1:
00D8 E082 LDI R24,2
00D9 9380009B STS 0x9B,R24
(0043) UCSR1B = (1 << TXEN1) | (1 << RXEN1); /*允许接收和发送*/
00DB E188 LDI R24,0x18
00DC 9380009A STS 0x9A,R24
(0044) UCSR1C = (1 << UCSZ11) | (1 << UCSZ10); /*8位数据、1 位停止、异步、无校验*/
00DE E086 LDI R24,6
00DF 9380009D STS 0x9D,R24
(0045) UBRR1H = 0x00;
00E1 2422 CLR R2
00E2 92200098 STS 0x98,R2
(0046) UBRR1L = 12; /*波特率9600*/
00E4 E08C LDI R24,0xC
00E5 93800099 STS 0x99,R24
00E7 9508 RET
(0047) }
(0048)
(0049) /*数据发送,查询方式*/
(0050) void uart_transmit1(unsigned char i) {
(0051)
(0052) PORTG |= (1 << PG4); /*设置RS485为输出状态*/
_uart_transmit1:
i --> R16
00E8 91800065 LDS R24,0x65
00EA 6180 ORI R24,0x10
00EB 93800065 STS 0x65,R24
(0053) UDR1 = i; /* 发送数据*/
00ED 9300009C STS 0x9C,R16
(0054) while (!(UCSR1A & (1<<TXC1))); /* 等待发送完成*/
00EF 9020009B LDS R2,0x9B
00F1 FE26 SBRS R2,6
00F2 CFFC RJMP 0x00EF
(0055) UCSR1A |= (1 << TXC1); /*清除发送标志*/
00F3 9180009B LDS R24,0x9B
00F5 6480 ORI R24,0x40
00F6 9380009B STS 0x9B,R24
(0056) PORTG &= ~(1 << PG4); /*设置RS485为输入状态*/
00F8 91800065 LDS R24,0x65
00FA 7E8F ANDI R24,0xEF
00FB 93800065 STS 0x65,R24
00FD 9508 RET
(0057) }
(0058)
(0059) /*数据接收,周期查询方式*/
(0060) unsigned int uart_receive1(void) {
(0061)
(0062) if ((UCSR1A & (1<<RXC1)) != 0) { /* 判断接收是否完成*/
_uart_receive1:
00FE 9020009B LDS R2,0x9B
0100 FE27 SBRS R2,7
0101 C005 RJMP 0x0107
(0063) return (UDR1 | 0x0100); /* 返回数据和标志*/
0102 9100009C LDS R16,0x9C
0104 2711 CLR R17
0105 6011 ORI R17,1
0106 C002 RJMP 0x0109
(0064) }
(0065) else {
(0066) return 0; /*返回无效标志*/
FILE: <library>
0107 2700 CLR R16
0108 2711 CLR R17
0109 9508 RET
pop_gset2:
010A E0E2 LDI R30,2
010B 940C0119 JMP pop
push_gset5:
010D 92FA ST R15,-Y
010E 92EA ST R14,-Y
push_gset4:
010F 92DA ST R13,-Y
0110 92CA ST R12,-Y
push_gset3:
0111 92BA ST R11,-Y
0112 92AA ST R10,-Y
push_gset2:
0113 937A ST R23,-Y
0114 936A ST R22,-Y
push_gset1:
0115 935A ST R21,-Y
0116 934A ST R20,-Y
0117 9508 RET
pop_gset1:
0118 E0E1 LDI R30,1
pop:
0119 9149 LD R20,Y+
011A 9159 LD R21,Y+
011B FDE0 SBRC R30,0
011C 9508 RET
011D 9169 LD R22,Y+
011E 9179 LD R23,Y+
011F FDE1 SBRC R30,1
0120 9508 RET
0121 90A9 LD R10,Y+
0122 90B9 LD R11,Y+
0123 FDE2 SBRC R30,2
0124 9508 RET
0125 90C9 LD R12,Y+
0126 90D9 LD R13,Y+
0127 FDE3 SBRC R30,3
0128 9508 RET
0129 90E9 LD R14,Y+
012A 90F9 LD R15,Y+
012B 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -