下面是针对IAR EWAVR的内联汇编优化代码,包含C代码。
如果使用C的话,需要针对使用的MCU和编译器作些优化。
//
// for iar ewavr
//
//----------------------------------------------------------------------------------------------
//
// CRC16-CCITT(ITU), 多项式: x16+x12+x5+1, LSB右移(0x8408).
//
unsigned short crc16_itu_lsb( unsigned short crc, unsigned int len, unsigned char *data )
{
// unsigned char temp;
// while(len--)
// {
// temp = crc ^ *data++;
// temp ^= temp<<4;
// crc = (crc>>8) ^ (temp<<3) ^ (temp<<8) ^ (temp>>4);
// }
// return crc;
__asm ( " MOVW R30, R20 \n" // R21:R20 = unsigned char *data
" LDI R20, 1<<4 \n"
" RJMP crc16_itu_lsb_while \n"
"crc16_itu_lsb_do: \n"
// temp = crc ^ *data++;
" LD R0, Z+ \n"
" EOR R16, R0 \n" // R16 = crc^*data
// temp ^= temp<<4;
" MUL R16, R20 \n" // R0 = temp<<4
" EOR R16, R0 \n" // R16 = temp^(temp<<4)
// crc = (crc>>8) ^ (temp<<3) ^ (temp<<8) ^ (temp>>4);
" MUL R16, R20 \n" // R1:R0 = temp<<4
" EOR R17, R1 \n" // R17 = (crc>>8)^(temp>>4)
" LSR R1 \n"
" ROR R0 \n" // R1:R0 = temp<<3
" EOR R0, R17 \n" // R0 = crc_l
" EOR R1, R16 \n" // R1 = crc_h
" MOVW R16, R0 \n" // R17:R16 = unsigned short crc
"crc16_itu_lsb_while: \n"
" SUBI R18, 1 \n" // R19:R18 = unsigned int len
" SBCI R19, 0 \n"
" BRCC crc16_itu_lsb_do \n"
);
return crc;
}
//----------------------------------------------------------------------------------------------
//
// CRC16-CCITT(ITU), 多项式: x16+x12+x5+1, MSB左移(0x1021).
//
unsigned short crc16_itu_msb( unsigned short crc, unsigned int len, unsigned char *data )
{
// unsigned char temp;
// while(len--)
// {
// temp = (crc>>8) ^ *data++;
// temp ^= temp>>4;
// crc = (crc<<8) ^ (temp<<5) ^ (temp<<0) ^ (temp<<12);
// }
// return crc;
__asm ( " MOVW R30, R20 \n" // R21:R20 = unsigned char *data
" LDI R20, 1<<4 \n"
" RJMP crc16_itu_msb_while \n"
"crc16_itu_msb_do: \n"
// temp = (crc>>8) ^ *data++;
" LD R0, Z+ \n"
" EOR R17, R0 \n" // R17 = (crc>>8)^*data
// temp ^= temp>>4;
" MUL R17, R20 \n" // R1 = temp>>4
" EOR R17, R1 \n" // R17 = temp^(temp>>4)
// crc = (crc<<8) ^ (temp<<5) ^ (temp<<0) ^ (temp<<12);
" MUL R17, R20 \n" // R1:R0 = temp<<4
" EOR R16, R0 \n" // R16 = (crc<<8)^(temp<<12)
" LSL R0 \n"
" ROL R1 \n" // R1:R0 = temp<<5
" EOR R0, R17 \n" // R0 = crc_l
" EOR R1, R16 \n" // R1 = crc_h
" MOVW R16, R0 \n" // R17:R16 = unsigned short crc
"crc16_itu_msb_while: \n"
" SUBI R18, 1 \n" // R19:R18 = unsigned int len
" SBCI R19, 0 \n"
" BRCC crc16_itu_msb_do \n"
);
return crc;
} |