(XT Mini Mod bus) C 언어 내 장 형 Mod bus 프로토 콜 스 택 , 마스터 , 슬 레이 브 예 제 소 스 코드

유료 ¥6.99유료 ¥6.99

이 콘텐츠는 회원/유료 시스템과 연동되어 있으며, 잠금 해제 후 전체 자료를 보거나 첨부파일을 다운로드할 수 있습니다.

보기解锁방식
(XT Mini Mod bus) C 언어 내 장 형 Mod bus 프로토 콜 스 택 , 마스터 , 슬 레이 브 예 제 소 스 코드

X T iny Mod bus 는 리 소 스가 제한 된 임 베 디 드 시스템을 위해 설계 된 경 량 C 언어 임 베 디 드 Mod bus 프로토 콜 스 택 입니다 . Mod bus R TU 및 Mod bus AS C II 전송 모 드를 지원 하며 마스터 및 슬 레이 브 기능을 제공합니다 .이 문서 에서는 X T iny Mod bus 의 아 키 텍 처 특성 , API 인터페 이스 , 마이 그레이 션 방법 및 전체 마스터 슬 레이 브 샘플 소 스 코드를 자세히 설명 합니다 .

X T iny Mod bus 개 요

X T iny Mod bus 는 최소 리 소 스 소비 로 완전한 Mod bus 프로토 콜 기능을 제공하기 위해 설계 되었습니다 .순 수한 C 언어로 작성 되었으며 운영 체 제에 의존 하지 않으며 51 MC U , AV R , S TM 32, MS P 430 및 기타 임 베 디 드 플랫폼 으로 쉽게 이 식 할 수 있습니다 .

1. 1 핵심 특징

  • 超轻量级
  • 主슬레이브一体
  • 双프로토콜支持
  • 无操作系统依赖
  • 기능 코드完整
  • 可裁剪설정
  • 中断驱动
  • CRC 검증

1. 2 자원 사용 량

자료
Flash(代码)
RAM(全局변수)
栈空间
수신缓冲区
보내기缓冲区

2. 문서 구조

X T iny Mod bus /
- - x t iny _ mod bus . h          / / 마스터 헤 더 파일 , API 선언 및 구성 매 크 로
- - x t iny _ mod bus . c          / / 핵심 프로토 콜 구현
- - x t iny _ mod bus _ port . h     플랫폼 포 팅 인터페 이스 (사 용 자 구현)
- - x t iny _ mod bus _ conf ig . h   / / 프로 파 일 (기 능 자 르기)
예 제 / ex amples
    - - - slave _ demo . c        / / 슬 레이 브 예 제
    - - master _ demo . c       / / 기본 스테 이션 예 제
    st m 32 _ port . c        S TM 32 마이 그레이 션 예 제

III . 구성 옵션

xt iny _ mod bus _ conf ig . h 에서 매 크 로를 통해 구성 기능을 정의 합니다 .

/ / 마스터 기능 활성화 (주 석 이 제거 되면 슬 레이 브 만 컴 파 일)
# define X MB _ en ab le _ MAS TER        1

/ / 슬 레이 브 기능 활성화
# define X MB _ EN AB LE _ S LA VE         1

프로토 콜 모 드 : 1 = R TU , 0 = AS C II
# define X MB _ R TU _ MO DE             1

/ / 버 퍼 크기
# define X MB _ BU F _ S IZ E             64

/ / 슬 레이 브 주소 (1 - 24 7)
# define X MB _ S LA VE _ AD DR           1

지원 되는 기능 코드 (필 요한 주 석을 제거 하면 코드 볼 륨 을 줄 일 수 있음)
# define X MB _ FC _ READ _ CO IL S        1   // 0 x 01
# define X MB _ FC _ READ _ IN PU TS       1   // 0 x 02
# define X MB _ FC _ READ _ H OL D ING S     1   // 0 x 03
# define X MB _ FC _ READ _ IN P UT _ REG ETS   1   // 0 x 04
X MB _ FC _ W R ITE _ CO IL 정의        1   // 0 x 05
# define X MB _ FC _ W R ITE _ REG IS TER    1   // 0 x 06
# define X MB _ FC _ W R ITE _ CO IL S       1   // 0 x 0 f
# define X MB _ FC _ W R ITE _ REG IS TER S   1   0 x 10

/ / 데이터 영역 크기
# define X mb _ co ils _ num            16 / / 코 일 수
# define X mb _ input _ num           16 / / 단 속 입력 수 량
# define X MB _ H OL D ING S _ N UM         32 / / 레 지 스터 수 를 유지 합니다 .
# define X MB _ IN P UT _ REG S _ N UM       16 / / 입력 레 지 스터 수

프레 임 시간 초 과 시간 (문 자 간 격 , ms)
# define X MB _ FR AME _ TIM EO UT        5

플랫폼 이 식 인터페 이스

X T iny Mod bus 는 콜 백 함 수를 통해 하드 웨어 플랫폼 과 분리 되어 사용자는 다음 인터페 이 스를 구현 할 수 있습니다 .

x t iny _ mod bus _ port . h

직 렬 포 트 초기 화 (바 트 속도 , 데이터 비트 , 중지 비트 , 체크 비트)
vo id x mb _ port _ u art _ init (u int 32 _ t baud rate);

/ / 바 이트 를 보내 다
vo id x mb _ port _ u art _ send _ by te (u int 8 _ t by te);

/ / 수신 인터 럽 트 사용 가능 / 사용 안 함
vo id x mb _ port _ u art _ r x _ enable (u int 8 _ t enable);

/ / 전송 완료 인터 럽 트 활성화 / 비 활 성 화
vo id x mb _ port _ u art _ tx _ enable (u int 8 _ t enable);

/ / 시스템 밀 리 초 카운 트 가져 오 기 (타 임 초 과 감지 용)
u int 32 _ t x mb _ port _ get _ ti ck (vo id);

/ / 임 계 영역 으로 들어가 기 (중 단 끄 기)
vo id x mb _ port _ enter _ critical (vo id);

/ / 임 계 영역 종료 (개 인 인터 럽 트)
vo id x mb _ port _ exit _ critical (vo id);

/ / RS 48 5 송 수 신 제어 (1 = 전송 , 0 = 수신)
vo id x mb _ port _ rs 48 5 _ dir (u int 8 _ t tx);

4. 1 S TM 32 마이 그레이 션 예

< code>// stm32_port.c
#include "stm32f10x.h"
#include "xtiny_modbus.h"

static volatile uint32_t sys_tick = 0;

// SysTick中断,1ms一次
void SysTick_Handler(void) {
    sys_tick++;
}

void xmb_port_uart_init(uint32_t baudrate) {
    GPIO_InitTypeDef GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    
    // TX: PA9  复用推挽출력
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    // RX: PA10 浮空입력
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    // RS485方向控制: PA8
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    USART_InitStruct.USART_BaudRate = baudrate;
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_Parity = USART_Parity_No;
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(USART1, &USART_InitStruct);
    
    // 使能수신中断
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    
    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);
    
    USART_Cmd(USART1, ENABLE);
}

void xmb_port_uart_send_byte(uint8_t byte) {
    USART_Send데이터(USART1, byte);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

void xmb_port_uart_rx_enable(uint8_t enable) {
    if (enable) USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    else USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
}

void xmb_port_uart_tx_enable(uint8_t enable) {
    if (enable) USART_ITConfig(USART1, USART_IT_TC, ENABLE);
    else USART_ITConfig(USART1, USART_IT_TC, DISABLE);
}

uint32_t xmb_port_get_tick(void) {
    return sys_tick;
}

void xmb_port_enter_critical(void) {
    __disable_irq();
}

void xmb_port_exit_critical(void) {
    __enable_irq();
}

void xmb_port_rs485_dir(uint8_t tx) {
    if (tx) GPIO_SetBits(GPIOA, GPIO_Pin_8);
    else GPIO_초기화Bits(GPIOA, GPIO_Pin_8);
}

// 시리얼 포트中断服务程序
void USART1_IRQHandler(void) {
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        uint8_t byte = USART_Receive데이터(USART1);
        xmb_uart_rx_isr(byte);  // 交给프로토콜栈处理
    }
    if (USART_GetITStatus(USART1, USART_IT_TC) != RESET) {
        USART_지우기ITPendingBit(USART1, USART_IT_TC);
        xmb_uart_tx_isr();     // 通知프로토콜栈보내기完成
    }
}

五、슬레이브모드完整예제

// slave_demo.c
#include "xtiny_modbus.h"
#include <stdint.h>

// 적용데이터区(用户可直接读写)
uint8_t  coils[XMB_COILS_NUM];           // 코일 상태
uint8_t  inputs[XMB_INPUTS_NUM];         // 이산 입력
uint16_t holdings[XMB_HOLDINGS_NUM];     // 유지 레지스터
uint16_t input_regs[XMB_INPUT_REGS_NUM]; // 입력 레지스터

int main(void) {
    // 初始化系统时钟、GPIO等
    SystemInit();
    SysTick_Config(SystemCoreClock / 1000);  // 1ms SysTick
    
    // 初始化Modbus슬레이브
    xmb_slave_init(9600, XMB_SLAVE_ADDR);
    
    // 회원가입데이터区回调(或直接使用全局数组)
    xmb_slave_set_coils(coils);
    xmb_slave_set_inputs(inputs);
    xmb_slave_set_holdings(holdings);
    xmb_slave_set_input_regs(input_regs);
    
    // 初始化一些데이터
    holdings[0] = 100;  // 온도
    holdings[1] = 50;   // 湿度
    
    while (1) {
        // 主循环中调用프로토콜栈处理
        xmb_slave_poll();
        
        // 用户적용代码
        // 例如:읽기센서更新到input_regs
        // input_regs[0] = read_adc();
        
        // 更新코일 상태到实际출력
        // for (i=0; i<8; i++) set_relay(i, coils[i]);
    }
}

// 写코일回调(可选,用于执行实际动作)
void xmb_callback_write_coil(uint16_t addr, uint8_t value) {
    // 当마스터写코일时调用
    // 例如:控制릴레이
    // set_relay(addr, value);
}

// 写레지스터回调(可选)
void xmb_callback_write_register(uint16_t addr, uint16_t value) {
    // 当마스터写유지 레지스터时调用
    // 例如:更新设定值
    // if (addr == 0) set_temperature(value);
}

六、마스터모드完整예제

// master_demo.c
#include "xtiny_modbus.h"
#include <stdio.h>

int main(void) {
    uint8_t  coils[8];
    uint16_t regs[10];
    int16_t  rc;
    
    SystemInit();
    SysTick_Config(SystemCoreClock / 1000);
    
    // 初始化Modbus마스터
    xmb_master_init(9600);
    
    while (1) {
        // 읽기슬레이브1的8个코일 상태
        rc = xmb_master_read_coils(1, 0, 8, coils);
        if (rc == XMB_OK) {
            printf("읽기成功:");
            for (int i = 0; i < 8; i++) printf("%d ", coils[i]);
            printf("\n");
        } else {
            printf("읽기失败,错误码:%d\n", rc);
        }
        
        // 읽기슬레이브1的10个유지 레지스터
        rc = xmb_master_read_holdings(1, 0, 10, regs);
        if (rc == XMB_OK) {
            printf("레지스터:");
            for (int i = 0; i < 10; i++) printf("%d ", regs[i]);
            printf("\n");
        }
        
        // 写单个코일:控制第1路릴레이吸合
        rc = xmb_master_write_coil(1, 0, 1);
        if (rc == XMB_OK) printf("写코일成功\n");
        
        // 写单个레지스터
        rc = xmb_master_write_register(1, 0, 1234);
        if (rc == XMB_OK) printf("写레지스터成功\n");
        
        // 写多个코일
        uint8_t coil_vals[4] = {1, 0, 1, 0};
        xmb_master_write_coils(1, 0, 4, coil_vals);
        
        // 写多个레지스터
        uint16_t reg_vals[3] = {100, 200, 300};
        xmb_master_write_registers(1, 0, 3, reg_vals);
        
        // 延时1秒
        delay_ms(1000);
    }
}

// 错误码설명
// XMB_OK           = 0   成功
// XMB_ERR_TIMEOUT  = -1  超时
// XMB_ERR_CRC      = -2  CRC 검증错误
// XMB_ERR_EXCEPT   = -3  슬레이브异常响应
// XMB_ERR_ADDR     = -4  주소不일치
// XMB_ERR_BUSY     = -5  总线忙

七、51单片机移植要点

  • 缓冲区大小:51单片机RAM有限,建议将XMB_BUF_SIZE设为32
  • 레지스터 수량:코일和레지스터 수량不宜过多,建议各16个
  • 晶振选择:使用11.0592MHz晶振保证9600bps准确
  • 中断优先级:시리얼 포트中断优先级设为最高,避免丢바이트
  • 帧超时:51单片机无SysTick,可用定时器0实现1ms计时
  • 변수存储:大数组定义为x데이터或i데이터,避免占用直接寻址区
  • CRC表:CRC16查表法占用256바이트ROM,51单片机可接受

7.1 51单片机定时器实现ms计时

// 51单片机1ms定时器(11.0592MHz)
static uint16_t xmb_tick = 0;

void timer0_init(void) {
    TMOD |= 0x01;   // 定时器0모드1
    TH0 = 0xFC;     // 1ms初值
    TL0 = 0x67;
    ET0 = 1;        // 使能定时器0中断
    TR0 = 1;        // 启动定时器0
    EA = 1;
}

void timer0_isr(void) interrupt 1 {
    TH0 = 0xFC;
    TL0 = 0x67;
    xmb_tick++;
}

uint32_t xmb_port_get_tick(void) {
    return xmb_tick;
}

八、常见문제

  • 通讯无响应:检查슬레이브 주소、통신 속도、패리티是否一致,A/B线是否接反
  • CRC错误:确认晶振频率准确,시리얼 포트 설정正确,检查是否有干扰
  • 只能收不能发:检查RS485方向控制引脚,确认DE/RE接在一起
  • 데이터丢包:增大缓冲区,提高시리얼 포트中断优先级,减少关中断时间
  • 마스터超时:추가超时时间,确认슬레이브响应速度,检查总线负载
  • 多슬레이브冲突:确保每个슬레이브 주소唯一,总线两端接120Ω终端电阻
  • 编译报错:确认설정宏定义正确,移植인터페이스전체实现

九、与其他Modbus프로토콜栈对比

td>
프로토콜栈代码体积RAM占用마스터슬레이브适用平台
XTinyModbus~5KB~120B支持
FreeModbus
uModbus
libmodbus
mnModbus

X T iny Mod bus 는 매우 적은 자원 소비 와 간 결 한 API 설계 로 51 MC U 와 같은 매우 제한 된 자 원을 가진 임 베 디 드 시스템에 특히 적합 합니다 . X T Mod iny bus 는 매우 작은 하드 웨어 에서 Mod bus 통신 을 구현 해야 하는 프로젝트에 이상 적입니다 .이 문서 에서 제공 되는 코 드는 프로젝트 개발 에 직접 사용할 수 있으며 실제 제품에 통합 하기 전에 테스트 보 드 에서 통신 을 검 증 하는 것이 좋습니다 .

실제 프로젝트에 이 자료를 활용하시겠습니까?

도구 센터에서 프레임 분석, CRC 검증, 장비 디버깅을 진행하거나 요청을 제출하여 선정 및 연동 제안을 받아보세요.

엔지니어 회원

이 글을 실행 가능한 디버깅 자료로 활용하세요

가입하면 고급 프레임 분석, 자료 패키지 다운로드, 코드 예제, 엔지니어링 사례, 우선 기술 지원을 이용할 수 있어 실제 프로젝트 납품에 적합합니다.

고급 도구 무제한 이용
자료 패키지와 코드 패키지
완전한 엔지니어링 사례 라이브러리
우선 기술 지원 채널

《“(XT Mini Mod bus) C 언어 내 장 형 Mod bus 프로토 콜 스 택 , 마스터 , 슬 레이 브 예 제 소 스 코드”》 有 1 条评论

답글 작성

이메일 주소는 공개되지 않습니다. 必填项已用 * 标注