ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
28 ноября
187666 Топик полностью
MegaJohn (01.04.2010 10:32, просмотров: 126) ответил ++ на Да надо реализовать на этой неделе в qt_designer. Так что нужно уже сегодня.
Тогда только это: modbus_common.C #include <protocol\modbus\modbus_common.h> #include <hashing\crc16.h> //////////////////////////////////////////////////////////////////////////////// void u16_to_u8hl( u16 src, u8 *dest ) { *dest++ = src >> 8; *dest = src & 0xFF; } //////////////////////////////////////////////////////////////////////////////// u16 u8hl_to_u16( u8 *src ) { u16 retval = (*(src++)) << 8; return( retval + *src ); } //////////////////////////////////////////////////////////////////////////////// // 0x03 = 3DEC u8 read_holding_registers( u8 *buff_p, u8 slv_addr, u16 begin_reg, u8 num_regs ) { u8 *buff_head = buff_p; *buff_p++ = slv_addr; *buff_p++ = 0x03; u16_to_u8hl( begin_reg, buff_p ); buff_p += 2; u16_to_u8hl( num_regs, buff_p ); crc16_put_crc( buff_head, 8 ); return 8; } //////////////////////////////////////////////////////////////////////////////// // 0x03 = 3DEC bool read_holding_registers_verify_response( u8 *buff_p, u8 slv_addr, u8 num_regs, u16 *dest ) { u8 reg_cnt = buff_p[ 2 ] / 2; u8 len = 3; if( buff_p[ 0 ] != slv_addr ) return false; if( buff_p[ 1 ] != 0x03 ) return false; if( num_regs != reg_cnt ) return false; if( !crc16_verify_crc( buff_p, 5 + 2 * reg_cnt ) ) return false; while( reg_cnt-- ) { *dest++ = u8hl_to_u16( &buff_p[ len ] ); len += 2; } return true; } //////////////////////////////////////////////////////////////////////////////// // 0x03 = 3DEC bool read_holding_registers_arr_p_vals_verify_response( u8 *buff_p, u8 slv_addr, u8 num_regs, u16 **dest ) { u8 reg_cnt = buff_p[ 2 ] / 2; u8 len = 3; if( buff_p[ 0 ] != slv_addr ) return false; if( buff_p[ 1 ] != 0x03 ) return false; if( num_regs != reg_cnt ) return false; if( !crc16_verify_crc( buff_p, 5 + 2 * reg_cnt ) ) return false; while( reg_cnt-- ) { *(*dest++) = u8hl_to_u16( &buff_p[ len ] ); len += 2; } return true; } //////////////////////////////////////////////////////////////////////////////// u8 read_holding_registers_response( u8 *buff_p, u8 slv_addr, u16 *data_p, u16 begin_reg, u8 num_regs ) { u8 len = 3 + 2*num_regs + 2; buff_p[ 0 ] = slv_addr; buff_p[ 1 ] = 0x03; buff_p[ 2 ] = num_regs * 2; u8 *tmp_p = &buff_p[ 3 ]; while( num_regs-- ) { u16_to_u8hl( *data_p++, tmp_p ); tmp_p += 2; } crc16_put_crc( buff_p, len ); return len; } //////////////////////////////////////////////////////////////////////////////// // 0x0F = 15DEC u8 force_multiple_coils_arr_p_vals( u8 *buff_p, u8 slv_addr, u16 begin_coil, bool **src, u8 num_coils ) { u8 len = 0; u8 temp = 0; u8 shift = ( 1 << 0 ); buff_p[ len++ ] = slv_addr; buff_p[ len++ ] = 0x0F; u16_to_u8hl( begin_coil, &buff_p[ len ] ); len += 2; u16_to_u8hl( num_coils, &buff_p[ len ] ); len += 2; buff_p[ len++ ] = ( num_coils + 7 ) / 8; while( num_coils-- ) { if( *(*src++) ) temp |= shift; shift <<= 1; if( !shift ) { // âñå áèòû ïîìåùåíû â áàéò buff_p[ len++ ] = temp; temp = 0; shift = (1 << 0); } } if( shift != (1 << 0) )// åñëè êîëè÷åñòâî áàéò íå êðàòíî 8, òî ïîïàäàåì ñþäà. buff_p[ len++ ] = temp; len += 2; crc16_put_crc( buff_p, len ); return len; } //////////////////////////////////////////////////////////////////////////////// bool force_multiple_coils_verify_response( u8 *buff_p, u8 slv_addr, u16 begin_coil, u8 num_coils ) { if( buff_p[ 0 ] != slv_addr ) return false; if( buff_p[ 1 ] != 0x0F ) return false; if( u8hl_to_u16( &buff_p[2] ) != begin_coil ) return false; if( u8hl_to_u16( &buff_p[4] ) != num_coils ) return false; if( !crc16_verify_crc( buff_p, 8 ) ) return false; return true; } //////////////////////////////////////////////////////////////////////////////// // 0x10 = 16DEC u8 preset_multiple_regs( u8 *buff_p, u8 slv_addr, u16 begin_reg, u16 *src, u8 num_regs ) { u8 len = 0; buff_p[ len++ ] = slv_addr; buff_p[ len++ ] = 0x10; u16_to_u8hl( begin_reg, &buff_p[ len ] ); len += 2; u16_to_u8hl( num_regs, &buff_p[ len ] ); len += 2; buff_p[ len++ ] = num_regs * 2; while( num_regs-- ) { u16_to_u8hl( *src++, &buff_p[ len ] ); len += 2; } len += 2; crc16_put_crc( buff_p, len ); return len; } //////////////////////////////////////////////////////////////////////////////// // 0x10 = 16DEC u8 preset_multiple_regs_arr_p_vals( u8 *buff_p, u8 slv_addr, u16 begin_reg, u16 **src, u8 num_regs ) { u8 len = 0; buff_p[ len++ ] = slv_addr; buff_p[ len++ ] = 0x10; u16_to_u8hl( begin_reg, &buff_p[ len ] ); len += 2; u16_to_u8hl( num_regs, &buff_p[ len ] ); len += 2; buff_p[ len++ ] = num_regs * 2; while( num_regs-- ) { u16_to_u8hl( *(*src++), &buff_p[ len ] ); len += 2; } len += 2; crc16_put_crc( buff_p, len ); return len; } //////////////////////////////////////////////////////////////////////////////// bool preset_multiple_regs_verify_response( u8 *buff_p, u8 slv_addr, u16 begin_reg, u8 num_regs ) { if( buff_p[ 0 ] != slv_addr ) return false; if( buff_p[ 1 ] != 0x10 ) return false; if( u8hl_to_u16( &buff_p[2] ) != begin_reg ) return false; if( u8hl_to_u16( &buff_p[4] ) != num_regs ) return false; if( !crc16_verify_crc( buff_p, 8 ) ) return false; return true; } //////////////////////////////////////////////////////////////////////////////// u8 preset_multiple_regs_response( u8 *buff_p, u8 slv_addr, u16 begin_reg, u8 num_regs ) { u8 len = 1 + 1 + 2 + 2 + 2; buff_p[ 0 ] = slv_addr; buff_p[ 1 ] = 0x10; u16_to_u8hl( begin_reg, &buff_p[ 2 ] ); u16_to_u8hl( num_regs, &buff_p[ 4 ] ); crc16_put_crc( buff_p, len ); return len; } //////////////////////////////////////////////////////////////////////////////// // 0x05 = 5DEC u8 force_single_coil( u8 *buff_p, u8 slv_addr, u16 coil_addr, bool state ) { u8 *buff_p_hold = buff_p; *buff_p++ = slv_addr; *buff_p++ = 0x05; u16_to_u8hl( coil_addr, buff_p ); buff_p += 2; *buff_p++ = state ? 0xFF: 0x00; *buff_p++ = 0x00; crc16_put_crc( buff_p_hold, 8 ); return 8; } //////////////////////////////////////////////////////////////////////////////// // 0x05 = 5DEC u8 force_single_coil_arr_p_vals( u8 *buff_p, u8 slv_addr, u16 coil_addr, bool state ) { u8 *buff_p_hold = buff_p; *buff_p++ = slv_addr; *buff_p++ = 0x05; u16_to_u8hl( coil_addr, buff_p ); buff_p += 2; *buff_p++ = state ? 0xFF: 0x00; *buff_p++ = 0x00; crc16_put_crc( buff_p_hold, 8 ); return 8; } //////////////////////////////////////////////////////////////////////////////// bool force_single_coil_verify_response( u8 *buff_p, u8 slv_addr, u16 coil_addr, bool state ) { #ifdef SIMULATOR_DEBUG return true; #endif if( buff_p[ 0 ] != slv_addr ) return false; if( buff_p[ 1 ] != 0x05 ) return false; if( u8hl_to_u16( &buff_p[2] ) != coil_addr ) return false; if( state ) { if( u8hl_to_u16( &buff_p[4] ) != 0xFF00 ) return false; } else { if( u8hl_to_u16( &buff_p[4] ) != 0x0000 ) return false; } if( !crc16_verify_crc( buff_p, 8 ) ) return false; return true; } //////////////////////////////////////////////////////////////////////////////// // 0x01 = 1DEC u8 read_coil_status( u8 *buff_p, u8 slv_addr, u16 coil_start_addr, u16 count_coils ) { u8 *buff_p_hold = buff_p; *buff_p++ = slv_addr; *buff_p++ = 0x01; u16_to_u8hl( coil_start_addr, buff_p ); buff_p += 2; u16_to_u8hl( count_coils, buff_p ); buff_p += 2; crc16_put_crc( buff_p_hold, 8 ); return 8; } //////////////////////////////////////////////////////////////////////////////// bool read_coil_status_verify_response( u8 *buff_p, u8 slv_addr, bool *dest ) { #ifdef SIMULATOR_DEBUG // return true; #endif u8 byte_cnt = buff_p[ 2 ]; u8 i; if( buff_p[ 0 ] != slv_addr ) return false; if( buff_p[ 1 ] != 0x01 ) return false; if( !crc16_verify_crc( buff_p, 5 + byte_cnt ) ) return false; // *state = !!(buff_p[ 3 ] & (1 << 0)); buff_p += 3; while( byte_cnt-- ) { for( i = (1 << 0); i ; ) { if( (*buff_p) & i ) *dest++ = true; else *dest++ = false; i <<= 1; } buff_p++; } return true; } //////////////////////////////////////////////////////////////////////////////// bool read_coil_status_arr_p_vals_verify_response( u8 *buff_p, u8 slv_addr, bool **dest ) { u8 byte_cnt = buff_p[ 2 ]; u8 i; if( buff_p[ 0 ] != slv_addr ) return false; if( buff_p[ 1 ] != 0x01 ) return false; if( !crc16_verify_crc( buff_p, 5 + byte_cnt ) ) return false; buff_p += 3; while( byte_cnt-- ) { for( i = (1 << 0); i ; ) { if( (*buff_p) & i ) *(*dest++) = true; else *(*dest++) = false; i <<= 1; } buff_p++; } return true; } modbus_common.h #ifndef MODBUS_COMMON_H #define MODBUS_COMMON_H #include <globals.h> #include <protocol\modbus\defs.h> #define MODBUS_BUFF_BYTES (1+1+2+2+1+2*MODBUS_MAX_REGS+2) #ifdef __cplusplus extern "C" { #endif void u16_to_u8hl( u16 src, u8 *dest ); u16 u8hl_to_u16( u8 *src ); u8 read_holding_registers( u8 *buff_p, u8 slv_addr, u16 begin_reg, u8 num_regs ); bool read_holding_registers_verify_response( u8 *buff_p, u8 slv_addr, u8 num_regs, u16 *dest ); bool read_holding_registers_arr_p_vals_verify_response( u8 *buff_p, u8 slv_addr, u8 num_regs, u16 **dest ); u8 read_holding_registers_response( u8 *buff_p, u8 slv_addr, u16 *data_p, u16 begin_reg, u8 num_regs ); u8 preset_multiple_regs( u8 *buff_p, u8 slv_addr, u16 begin_reg, u16 *src, u8 num_regs ); bool preset_multiple_regs_verify_response( u8 *buff_p, u8 slv_addr, u16 begin_reg, u8 num_regs ); u8 preset_multiple_regs_arr_p_vals( u8 *buff_p, u8 slv_addr, u16 begin_reg, u16 **src, u8 num_regs ); u8 preset_multiple_regs_response( u8 *buff_p, u8 slv_addr, u16 begin_reg, u8 num_regs ); u8 force_single_coil( u8 *buff_p, u8 slv_addr, u16 coil_addr, bool state ); bool force_single_coil_verify_response( u8 *buff_p, u8 slv_addr, u16 coil_addr, bool state ); u8 force_multiple_coils_arr_p_vals( u8 *buff_p, u8 slv_addr, u16 begin_coil, bool **src, u8 num_coils ); bool force_multiple_coils_verify_response( u8 *buff_p, u8 slv_addr, u16 begin_coil, u8 num_coils ); u8 read_coil_status( u8 *buff_p, u8 slv_addr, u16 coil_start_addr, u16 count_coils ); bool read_coil_status_verify_response( u8 *buff_p, u8 slv_addr, bool *state ); bool read_coil_status_arr_p_vals_verify_response( u8 *buff_p, u8 slv_addr, bool **dest ); #ifdef __cplusplus } #endif #endif