📄 atmega16l_uart.s
字号:
;
; 10: 256Word/0xf00;
;
; 11: 128Word/0xf80
;
;
; /*
; ATMEGA16L 配置为外部16M晶振的方法:
; 配置环境:SL-ISP V1.4.2.3
; 熔丝配置:以下仅注明需要打勾的地方
;
; BODLEVEL=0 //很关键
; CKSEL=1111 //很关键
; SUT=01 //可根据自己需要调整
; BOOTSZ=00 //可根据自己需要调整
; CKOPT=0 //很关键
; SPIEN=0 //特别关键,想不勾也不可能,不过如果显示没勾上就意味着软件出
; //------------------------------------------------------------------------------
; /*
; 引导码: 2 byte = 0xFEFE
; 系统设备号 1 byte = 0x02
; 这三个不管他
; 对这三个固定值后面的数据没个字节进行CRC16效验,
; 算法:
; void CRC16(unsigned int *crc,unsigned char chr).{. data unsigned int tmp;.. tmp = *crc;. *crc = (tmp << 8) ^ TableOfCRC16[chr ^ (tmp >> 8)];.}
; 最后两个字节就是CRC16的值:
; UDR = CRC >> 8;
; UDR = CRC;
; 这个就是发送CRC最后两位数据:
; 引导码: 2 byte = 0xFEFE
; 系统设备号 1 byte = 0x02
; 控制器地址码: 1 byte = 1 - 127(0xFF为广播地址,0x00为系统保留)
; 数据包长度: 2 byte = 0 - 0x07FF,表示紧跟数据包长度;
; 数据包: (变长) 长度可变,由数据包长度指定;
; 校验码: 2 byte = 计算从地址码开始到数据包最后一个字节的CRC16码。
; */
; //CCITT CRC16
; flash unsigned int TableOfCRC16[256] = /*CRC16校验码表*/
; {
; 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
; 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
; 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
; 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
; 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
; 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
; 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
; 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
; 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
; 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
; 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
; 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
; 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
; 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
; 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
; 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
; 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
; 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
; 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
; 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
; 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
; 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
; 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
; 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
; 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
; 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
; 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
; 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
; 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
; 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
; 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
; 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
; };
;
; /*计算单字符CRC16代码*/
; void CRC16(unsigned int *crc,unsigned char chr)
; {
.dbline 292
; unsigned int tmp;
; tmp = *crc;
movw R30,R16
ldd R10,z+0
ldd R11,z+1
.dbline 293
; *crc = (tmp << 8) ^ TableOfCRC16[chr ^ (tmp >> 8)];
movw R2,R10
mov R2,R3
clr R3
mov R30,R18
clr R31
eor R30,R2
eor R31,R3
lsl R30
rol R31
ldi R24,<_TableOfCRC16
ldi R25,>_TableOfCRC16
add R30,R24
adc R31,R25
lpm R2,Z+
lpm R3,Z
movw R4,R10
mov R5,R4
clr R4
eor R4,R2
eor R5,R3
movw R30,R16
std z+1,R5
std z+0,R4
.dbline -2
L2:
.dbline 0 ; func end
ld R11,y+
ld R10,y+
ret
.dbsym r tmp 10 i
.dbsym r chr 18 c
.dbsym r crc 16 pi
.dbend
.dbfunc e Uart0_Init _Uart0_Init fV
.even
_Uart0_Init::
.dbline -1
.dbline 299
; }
;
; //------------------------------------------------------------------------------
; //串口初始化
; void Uart0_Init(void)
; {
.dbline 300
; UCSRB = 0x00; //disable while setting baud rate
clr R2
out 0xa,R2
.dbline 301
; UCSRA = 0x00;
out 0xb,R2
.dbline 303
; /*设置帧格式:8个数据位 1个停止位*/
; UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//8位数据+1位STOP位
ldi R24,134
out 0x20,R24
.dbline 305
; /*设置波特率 9600*/
; UBRRL = 0x67; //set baud rate lo
ldi R24,103
out 0x9,R24
.dbline 306
; UBRRH = 0x00; //set baud rate hi
out 0x20,R2
.dbline 308
; /*接收结束中断使能/发送结束中断使能/接收器与发送器使能*/
; UCSRB = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);
ldi R24,216
out 0xa,R24
.dbline -2
L3:
.dbline 0 ; func end
ret
.dbend
.area vector(rom, abs)
.org 44
jmp _Uart0_rx_isr
.area text(rom, con, rel)
.dbfile C:\DOCUME~1\Administrator\桌面\LCU904~1\固件程序\ATmega16L_Uart.C
.area bss(ram, con, rel)
.dbfile C:\DOCUME~1\Administrator\桌面\LCU904~1\固件程序\ATmega16L_Uart.C
L5:
.blkb 1
L6:
.blkb 2
L7:
.blkb 2
L8:
.blkb 2
.area text(rom, con, rel)
.dbfile C:\DOCUME~1\Administrator\桌面\LCU904~1\固件程序\ATmega16L_Uart.C
.dbfunc e Uart0_rx_isr _Uart0_rx_isr fV
.dbstruct 0 260 StructOfProtocol
.dbfield 0 Address c
.dbfield 1 Length i
.dbfield 3 Command c
.dbfield 4 Data A[256:256]c
.dbend
.dbstruct 0 4 data
.dbfield 0 pc_rxd c
.dbfield 1 pc_txd c
.dbfield 2 c51_rxd c
.dbfield 3 c51_txd c
.dbend
.dbsym s p_uart L8 pc
.dbsym s Count L7 i
.dbsym s CRC L6 i
.dbsym s Status L5 c
; communication -> R10,R11
; p_buf -> R20,R21
; tmp -> R22
.even
_Uart0_rx_isr::
st -y,R0
st -y,R1
st -y,R2
st -y,R3
st -y,R4
st -y,R5
st -y,R6
st -y,R7
st -y,R8
st -y,R9
st -y,R16
st -y,R17
st -y,R18
st -y,R19
st -y,R24
st -y,R25
st -y,R26
st -y,R27
st -y,R30
st -y,R31
in R0,0x3f
st -y,R0
xcall push_xgsetF03C
.dbline -1
.dbline 315
; }
;
; //------------------------------------------------------------------------------
; //接收数据
; #pragma interrupt_handler Uart0_rx_isr:12
; void Uart0_rx_isr(void)
; {
.dbline 322
; unsigned char tmp;
; static unsigned char Status;
; static unsigned int CRC,Count;
; static unsigned char *p_uart;
; struct StructOfProtocol *p_buf;
; struct data *communication;
; tmp = UDR; //接收数据
in R22,0xc
.dbline 323
; switch (Status)
lds R20,L5
clr R21
cpi R20,0
cpc R20,R21
breq L12
X0:
cpi R20,1
ldi R30,0
cpc R21,R30
breq L13
X1:
cpi R20,2
ldi R30,0
cpc R21,R30
brne X18
xjmp L18
X18:
X2:
cpi R20,3
ldi R30,0
cpc R21,R30
brne X19
xjmp L21
X19:
X3:
cpi R20,4
ldi R30,0
cpc R21,R30
brne X20
xjmp L22
X20:
X4:
cpi R20,5
ldi R30,0
cpc R21,R30
brne X21
xjmp L23
X21:
X5:
cpi R20,6
ldi R30,0
cpc R21,R30
brne X22
xjmp L26
X22:
X6:
cpi R20,7
ldi R30,0
cpc R21,R30
brne X23
xjmp L29
X23:
X7:
cpi R20,8
ldi R30,0
cpc R21,R30
brne X24
xjmp L30
X24:
X8:
xjmp L9
L12:
.dbline 326
; {
; case 0: /*接收初始化*/
; Count = 0; /*清计数器*/
clr R2
clr R3
sts L7+1,R3
sts L7,R2
.dbline 327
; Status++;
lds R24,L5
subi R24,255 ; addi 1
sts L5,R24
L13:
.dbline 329
; case 1: /*引导码接收*/
; if (tmp == BOOT_CODE) /*引导码字符确认*/
cpi R22,254
brne L14
X9:
.dbline 330
; {
.dbline 331
; if (++Count >= 2) Status++; /*引导码长度确认*/
lds R24,L7
lds R25,L7+1
adiw R24,1
movw R2,R24
sts L7+1,R3
sts L7,R2
cpi R24,2
ldi R30,0
cpc R25,R30
brsh X25
xjmp L10
X25:
X10:
.dbline 331
lds R24,L5
subi R24,255 ; addi 1
sts L5,R24
.dbline 332
; }
xjmp L10
L14:
.dbline 333
; else Status = 0;
clr R2
sts L5,R2
.dbline 334
; break;
xjmp L10
L18:
.dbline 336
; case 2: /*设备号接收*/
; if (tmp == DEVICE_NUMBER) /*设备号确认*/
cpi R22,2
brne L19
X11:
.dbline 337
; {
.dbline 338
; CRC = 0xffff; /*初始化校验码*/
ldi R24,65535
ldi R25,255
sts L6+1,R25
sts L6,R24
.dbline 339
; p_uart = Buffer485; /*初始化数据接收指针*/
ldi R24,<_Buffer485
ldi R25,>_Buffer485
sts L8+1,R25
sts L8,R24
.dbline 340
; Status++;
lds R24,L5
subi R24,255 ; addi 1
sts L5,R24
.dbline 341
; }
xjmp L10
L19:
.dbline 342
; else Status = 0;
clr R2
sts L5,R2
.dbline 343
; break;
xjmp L10
L21:
.dbline 345
; case 3: /*地址码接收*/
; *p_uart++ = tmp; /*接收地址*/
lds R30,L8
lds R31,L8+1
st Z+,R22
sts L8+1,R31
sts L8,R30
.dbline 346
; CRC16(&CRC,tmp); /*数据校验*/
mov R18,R22
ldi R16,<L6
ldi R17,>L6
xcall _CRC16
.dbline 347
; Status++;
lds R24,L5
subi R24,255 ; addi 1
sts L5,R24
.dbline 348
; break;
xjmp L10
L22:
.dbline 350
; case 4: /*包长度高位字节接收*/
; *p_uart++ = tmp; /*接收包长度低位字节*/
lds R30,L8
lds R31,L8+1
st Z+,R22
sts L8+1,R31
sts L8,R30
.dbline 351
; CRC16(&CRC,tmp); /*数据校验*/
mov R18,R22
ldi R16,<L6
ldi R17,>L6
xcall _CRC16
.dbline 352
; Status++;
lds R24,L5
subi R24,255 ; addi 1
sts L5,R24
.dbline 353
; break;
xjmp L10
L23:
.dbline 355
; case 5: /*包长度低位字节接收*/
; *p_uart++ = tmp; /*接收包长度高位字节*/
lds R30,L8
lds R31,L8+1
st Z+,R22
sts L8+1,R31
sts L8,R30
.dbline 356
; CRC16(&CRC,tmp); /*数据校验*/
mov R18,R22
ldi R16,<L6
ldi R17,>L6
xcall _CRC16
.dbline 357
; p_buf = (struct StructOfProtocol *)Buffer485;
ldi R20,<_Buffer485
ldi R21,>_Buffer485
.dbline 358
; Count = p_buf->Length;
movw R30,R20
ldd R2,z+1
ldd R3,z+2
sts L7+1,R3
sts L7,R2
.dbline 359
; if (Count && Count <= (256 - 8)) Status++; /*包长度检查*/
tst R2
brne X12
tst R3
breq L24
X12:
ldi R24,248
ldi R25,0
cp R24,R2
cpc R25,R3
brlo L24
X13:
.dbline 359
lds R24,L5
subi R24,255 ; addi 1
sts L5,R24
xjmp L10
L24:
.dbline 360
; else Status = 0; /*包长度异常 - 状态返回*/
clr R2
sts L5,R2
.dbline 361
; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -