Gitee

https://gitee.com/WangXi_Chn/RttOs_ModuleLib

开发环境

CubeMX
MDK5 IDE
STM32F429IGT6 芯片
正点原子开发板 阿波罗
STM32F103C8T6 芯片
Stm32最小系统板
RT-Thread操作系统
面向对象模块接口设计

硬件条件

  • 两块板通过串口线连接,同时正点原子开发板为最小系统板供电,共地
  • 实现一个光电正交脉冲编码器数据读取功能
  • 通过最小系统板读取编码器信息,再通过串口将该编码器信息发送至开发板

    核心思想

  • 模块实现串口设备的初始化

  • 对发送数据的协议打包和协议拆包
  • 固定帧头帧尾和计算校验帧,保证数据可靠性
  • 添加包数据功能指示帧

    帧格式

    | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 5 | 8 | 9 | 10 | | :—-: | :—-: | :—-: | :—-: | :—-: | :—-: | :—-: | :—-: | :—-: | :—-: | :—-: | | 0xA5 | 0x5A | 0x00 | 0x01 | 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x01 | 0xAA |

  • 红色:固定帧格式,帧头帧尾,只有接收到帧头才开始接收,只有接收到帧尾才结束接收

  • 青色:目标器件的ID,用来标识信息想要发送于谁
  • 紫色:我的器件ID,与使用的外设有关,用来标识信息来源于谁
  • 蓝色:功能指示帧(也可视为帧ID),通过宏定义(M0_D1)规定,0x01意为功能0的第1个数据,0x12(M0_D2)意为功能1的第2个数据,由通信双方规定和解释
  • 绿色:数据内容,支持一个int类型数据传输,5-8分别对应高8位和低8位
  • 橙色:校验帧,将ID和数据(即2~8),每8位求和计算结果的低八位作为校验帧,接收到一帧数据时会先验证,验证未通过数据会被丢弃

    源文件

    Module_BSPCommunicate.h

    ```c /*
    • Copyright (c) 2020 - ~, HIT_HERO Team *
    • BSP COMMUNICATE MODULE HEAD FILE
    • Used in RT-Thread Operate System *
    • Change Logs:
    • Date Author Notes Mail
    • 2020-08-25 WangXi first version WangXi_chn@foxmail.com
    • Note */

      include

      include

      include

ifndef MODULE_BSPCOMMUNICATE_H

define MODULE_BSPCOMMUNICATE_H

typedef enum PACKETID { M0_D1 = 0x01, M0_D2 = 0x02,

  1. M1_D1 = 0x11,
  2. M1_D2 = 0x12,

}PacketID;

struct _MODULE_BSPCOMMUNICATE { / Property / char * Property_UartDevName;

  1. /* Value */
  2. rt_device_t Value_uart_dev;
  3. rt_uint8_t Value_sendData[9];
  4. rt_uint8_t Value_feedData[9];
  5. //User data means define begin--------------------------------------------------------
  6. rt_int32_t Value_RotaryEncoder;
  7. //User data means define end--------------------------------------------------------
  8. /* Method */
  9. void (*Method_Init)(struct _MODULE_BSPCOMMUNICATE *module);
  10. void (*Method_Send)(struct _MODULE_BSPCOMMUNICATE *module,PacketID funcflag,rt_int32_t param);
  11. void (*Method_Feed)(struct _MODULE_BSPCOMMUNICATE *module);
  12. void (*Method_Encode)(struct _MODULE_BSPCOMMUNICATE *module,PacketID funcflag,rt_int32_t param);
  13. void (*Method_Decode)(struct _MODULE_BSPCOMMUNICATE *module);
  14. rt_err_t (*Method_Handle)(rt_device_t dev, rt_size_t size);

}; typedef struct _MODULE_BSPCOMMUNICATE MODULE_BSPCOMMUNICATE;

rt_err_t Module_BspCommunicate_Config(MODULE_BSPCOMMUNICATE *module);

endif

/** (C) COPYRIGHT 2020 WANGXI **END OF FILE**/

  1. <a name="LJBUe"></a>
  2. ## Module_BSPCommunicate.c
  3. ```c
  4. /*
  5. * Copyright (c) 2020 - ~, HIT_HERO Team
  6. *
  7. * BSP COMMUNICATE MODULE SOUCE FILE
  8. * Used in RT-Thread Operate System
  9. *
  10. * Change Logs:
  11. * Date Author Notes Mail
  12. * 2020-08-25 WangXi first version WangXi_chn@foxmail.com
  13. */
  14. #include "Module_BSPCommunicate.h"
  15. static void Module_BspCommunicateInit(MODULE_BSPCOMMUNICATE *module);
  16. static void Module_BspCommunicateSend(MODULE_BSPCOMMUNICATE *module,PacketID funcflag,rt_int32_t param);
  17. static void Module_BspCommunicateFeed(MODULE_BSPCOMMUNICATE *module);
  18. static void Module_BspCommunicateEncode(MODULE_BSPCOMMUNICATE *module,PacketID funcflag,rt_int32_t param);
  19. static void Module_BspCommunicateDecode(MODULE_BSPCOMMUNICATE *module);
  20. static rt_err_t Module_BspCommunicateHandle(rt_device_t dev, rt_size_t size);
  21. static struct rt_semaphore uartBspCommunicate_sem;
  22. /* Global Method */
  23. rt_err_t Module_BspCommunicate_Config(MODULE_BSPCOMMUNICATE *module)
  24. {
  25. if( module->Method_Init ==NULL &&
  26. module->Method_Handle ==NULL &&
  27. module->Method_Send ==NULL &&
  28. module->Method_Feed ==NULL &&
  29. module->Method_Encode ==NULL &&
  30. module->Method_Decode ==NULL
  31. ){
  32. /* Link the Method */
  33. module->Method_Init = Module_BspCommunicateInit;
  34. module->Method_Handle = Module_BspCommunicateHandle;
  35. module->Method_Send = Module_BspCommunicateSend;
  36. module->Method_Feed = Module_BspCommunicateFeed;
  37. module->Method_Encode = Module_BspCommunicateEncode;
  38. module->Method_Decode = Module_BspCommunicateDecode;
  39. }
  40. else{
  41. rt_kprintf("Warning: Module BspCommunicate is Configed twice\n");
  42. return RT_ERROR;
  43. }
  44. /* Device Init */
  45. module->Method_Init(module);
  46. return RT_EOK;
  47. }
  48. static void Module_BspCommunicateInit(MODULE_BSPCOMMUNICATE *module)
  49. {
  50. module->Value_uart_dev = rt_device_find(module->Property_UartDevName);
  51. if (!module->Value_uart_dev)
  52. {
  53. rt_kprintf("find %s failed!\n", module->Value_uart_dev);
  54. return;
  55. }
  56. rt_sem_init(&uartBspCommunicate_sem, "uartBspCommunicate_sem", 0, RT_IPC_FLAG_FIFO);
  57. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */
  58. /* step2:修改串口配置参数 */
  59. config.baud_rate = BAUD_RATE_9600; //修改波特率为 9600
  60. config.data_bits = DATA_BITS_8; //数据位 8
  61. config.stop_bits = STOP_BITS_1; //停止位 1
  62. config.bufsz = 128; //修改缓冲区 buff size 为 128
  63. config.parity = PARITY_NONE; //无奇偶校验位
  64. /* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */
  65. rt_device_control(module->Value_uart_dev, RT_DEVICE_CTRL_CONFIG, &config);
  66. rt_device_open(module->Value_uart_dev, RT_DEVICE_FLAG_DMA_RX);
  67. rt_device_set_rx_indicate(module->Value_uart_dev, module->Method_Handle);
  68. }
  69. static void Module_BspCommunicateSend(MODULE_BSPCOMMUNICATE *module,PacketID packetID,rt_int32_t param)
  70. {
  71. module->Method_Encode(module,packetID,param);
  72. rt_device_write( module->Value_uart_dev, 0,
  73. &(module->Value_sendData),
  74. sizeof(module->Value_sendData));
  75. }
  76. static void Module_BspCommunicateFeed(MODULE_BSPCOMMUNICATE *module)
  77. {
  78. rt_uint8_t ch;
  79. rt_uint8_t i = 0;
  80. while (1)
  81. {
  82. while (rt_device_read(module->Value_uart_dev, -1, &ch, 1) == 0)
  83. {
  84. rt_sem_control(&uartBspCommunicate_sem, RT_IPC_CMD_RESET, RT_NULL);
  85. rt_sem_take(&uartBspCommunicate_sem, RT_WAITING_FOREVER);
  86. }
  87. if((rt_uint8_t)ch == 0xAA)
  88. {
  89. /* get the frame end flag and start encode the frame */
  90. module->Method_Decode(module);
  91. i = 0;
  92. continue;
  93. }
  94. i = (i >= 9-1) ? 9-1 : i;
  95. module->Value_feedData[i++] = ch;
  96. }
  97. }
  98. static rt_err_t Module_BspCommunicateHandle(rt_device_t dev, rt_size_t size)
  99. {
  100. rt_sem_release(&uartBspCommunicate_sem);
  101. return RT_EOK;
  102. }
  103. static void Module_BspCommunicateEncode(MODULE_BSPCOMMUNICATE *module,PacketID packetID,rt_int32_t param)
  104. {
  105. module->Value_sendData[0] = 0xA5;
  106. module->Value_sendData[1] = 0x5A;
  107. module->Value_sendData[2] = packetID;
  108. module->Value_sendData[3] = (rt_uint8_t)((param&0xFF000000)>>24);
  109. module->Value_sendData[4] = (rt_uint8_t)((param&0x00FF0000)>>16);
  110. module->Value_sendData[5] = (rt_uint8_t)((param&0x0000FF00)>>8);
  111. module->Value_sendData[6] = (rt_uint8_t)((param&0x000000FF));
  112. module->Value_sendData[7] = (rt_uint8_t)((module->Value_sendData[2])+
  113. (module->Value_sendData[3])+(module->Value_sendData[4])+
  114. (module->Value_sendData[5])+(module->Value_sendData[6]));
  115. module->Value_sendData[8] = 0xAA;
  116. }
  117. static void Module_BspCommunicateDecode(MODULE_BSPCOMMUNICATE *module)
  118. {
  119. if( (rt_uint8_t)(module->Value_feedData[0])==0xA5 &&
  120. (rt_uint8_t)(module->Value_feedData[1])==0x5A &&
  121. (rt_uint8_t)((module->Value_feedData[2])+
  122. (module->Value_feedData[3])+(module->Value_feedData[4])+
  123. (module->Value_feedData[5])+(module->Value_feedData[6]))
  124. ==(module->Value_feedData[7]))
  125. {
  126. //Split the data
  127. rt_int32_t Date = ((module->Value_feedData[3])<<24) + ((module->Value_feedData[4])<<16)
  128. +((module->Value_feedData[5])<<8) + ((module->Value_feedData[6]));
  129. //User data Translate begin-----------------------------------------------------------------------------
  130. switch(module->Value_feedData[2])
  131. {
  132. case M0_D1:
  133. module->Value_RotaryEncoder = Date;
  134. break;
  135. case M0_D2:
  136. break;
  137. case M1_D1:
  138. break;
  139. case M1_D2:
  140. break;
  141. }
  142. //User data Translate end-----------------------------------------------------------------------------
  143. }
  144. else
  145. {
  146. return;
  147. }
  148. }
  149. /************************ (C) COPYRIGHT 2020 WANGXI **************END OF FILE****/

使用(发送方)main

  1. #include <rtthread.h>
  2. #include <rtdevice.h>
  3. #include <board.h>
  4. #include <stdlib.h>
  5. #include "Module_BSPCommunicate.h"
  6. #define PULSE_ENCODER_DEV_NAME "pulse4" /* 脉冲编码器名称 */
  7. MODULE_BSPCOMMUNICATE dev_BspCommunicate =
  8. {
  9. .Property_UartDevName = "uart2",
  10. };
  11. int main(void)
  12. {
  13. rt_err_t ret = RT_EOK;
  14. rt_device_t pulse_encoder_dev = RT_NULL; /* 脉冲编码器设备句柄 */
  15. /* 查找脉冲编码器设备 */
  16. pulse_encoder_dev = rt_device_find(PULSE_ENCODER_DEV_NAME);
  17. if (pulse_encoder_dev == RT_NULL)
  18. {
  19. rt_kprintf("pulse encoder sample run failed! can't find %s device!\n", PULSE_ENCODER_DEV_NAME);
  20. return RT_ERROR;
  21. }
  22. /* 以只读方式打开设备 */
  23. ret = rt_device_open(pulse_encoder_dev, RT_DEVICE_OFLAG_RDONLY);
  24. if (ret != RT_EOK)
  25. {
  26. rt_kprintf("open %s device failed!\n", PULSE_ENCODER_DEV_NAME);
  27. return ret;
  28. }
  29. rt_pin_mode(GET_PIN(B, 6), PIN_MODE_INPUT_PULLUP);
  30. rt_pin_mode(GET_PIN(B, 7), PIN_MODE_INPUT_PULLUP);
  31. rt_pin_mode(GET_PIN(C, 13), PIN_MODE_OUTPUT);
  32. //初始化串口板级通信模块
  33. Module_BspCommunicate_Config(&dev_BspCommunicate);
  34. while(1)
  35. {
  36. rt_thread_mdelay(1);
  37. //发送指示灯点亮
  38. rt_pin_write(GET_PIN(C, 13), PIN_LOW);
  39. /* 读取脉冲编码器计数值 */
  40. rt_device_read(pulse_encoder_dev, 0, &(dev_BspCommunicate.Value_RotaryEncoder), 1);
  41. if(abs(dev_BspCommunicate.Value_RotaryEncoder)>20000)
  42. {
  43. /* 读到了错误数据清空脉冲编码器计数值 */
  44. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_CLEAR_COUNT, RT_NULL);
  45. }
  46. //发送数据,指示包功能为M0_D1
  47. dev_BspCommunicate.Method_Send(&dev_BspCommunicate,M0_D1,dev_BspCommunicate.Value_RotaryEncoder);
  48. //发送指示灯熄灭
  49. rt_pin_write(GET_PIN(C, 13), PIN_HIGH);
  50. }
  51. }
  • 即发送方需要发送数据时,仅需调用模块的Send方法即可

    使用(接收方)main

    ```c /*
    • Copyright (c) 2020 - ~, HIT_HERO Team *
    • MAIN SOUCE FILE
    • Used in RT-Thread Operate System *
    • Change Logs:
    • Date Author Notes Mail
    • 2020-08-08 WangXi first version WangXi_chn@foxmail.com
    • 2020-08-13 WangXi second version WangXi_chn@foxmail.com *
    • Note:
    • Used for friction gear shot Rugby /

include

include

include

include “Module_LED.h”

include “Module_DjiC610620Group.h”

include “Module_BlueToothHC06.h”

include “Module_BSPCommunicate.h”

/ Module param list ———————————————————————————————————————————— / MODULE_LED dev_led_state = {
.pin = GET_PIN(B, 0), .LED_TIME_CYCLE = 4000, .LED_TIME_OUTPUT = 200 };

MODULE_BSPCOMMUNICATE dev_BspCommunicate = { .Property_UartDevName = “uart3”, };

/ thread entry list ———————————————————————————————————————————— / static void led_shine_entry(void *parameter) { while (1) { rt_thread_mdelay(1);
dev_led_state.Handle(&dev_led_state);
} }

static void bspCommnicate_entry(void *parameter) { dev_BspCommunicate.Method_Feed(&dev_BspCommunicate); }

int main(void) { / Config module ———————————————————————————————————————————— / Module_Led_Config(&dev_led_state);
dev_led_state.Set(&dev_led_state,9);

  1. Module_BspCommunicate_Config(&dev_BspCommunicate);
  2. /* Enable task thread ---------------------------------------------------------------------------------------- */
  3. /* system running shine led thread */
  4. rt_thread_t led_thread = rt_thread_create("ledshine", led_shine_entry, RT_NULL,
  5. 512, RT_THREAD_PRIORITY_MAX - 3, 20);
  6. if (led_thread != RT_NULL){
  7. rt_thread_startup(led_thread);
  8. }
  9. /* bsp communicate thread */
  10. rt_thread_t bspCommnicate_thread = rt_thread_create("bspCommnicate", bspCommnicate_entry, RT_NULL,
  11. 512, RT_THREAD_PRIORITY_MAX - 6, 20);
  12. if (bspCommnicate_thread != RT_NULL){
  13. rt_thread_startup(bspCommnicate_thread);
  14. }

}

/** (C) COPYRIGHT 2020 WANGXI **END OF FILE**/

  1. - 即接收方仅需在一个线程中调用模块的Feed方法即可
  2. - 而对接收数据的解释需要在模块的Decode方法中编辑
  3. - 建议通过添加模块的结构体成员,在Decode方法中对包ID所对应的结构体成员赋值
  4. - 这样做的好处是,可以保证模块与模块之间相互分离,所有的数据交互仅在main下进行,尽可能降低耦合
  5. <a name="TaPm9"></a>
  6. # 版本更新
  7. - 去除对数据解释部分,仅实现透明传输功能
  8. - 解释由上层封装,应用程序规定和解释(根据传输的帧ID即功能指示子节)
  9. - 在帧中加入了自身ID对方ID的说明和识别
  10. - 添加了对JC24B无线透传模块的使用选项和驱动
  11. - 更大程度上降低耦合,提升模块复用效率
  12. <a name="VO21Y"></a>
  13. ## Module_UartCom.h
  14. ```c
  15. /*
  16. * Copyright (c) 2020 - ~, HIT_HERO Team
  17. *
  18. * UARTCOM MODULE HEAD FILE
  19. * Used in RT-Thread Operate System
  20. *
  21. * Change Logs:
  22. * Date Author Notes Mail
  23. * 2020-08-25 WangXi first version WangXi_chn@foxmail.com
  24. * 2020-09-06 WangXi second version WangXi_chn@foxmail.com
  25. * Note
  26. */
  27. #ifndef _MODULE_UARTCOM_H_
  28. #define _MODULE_UARTCOM_H_
  29. #include <rtthread.h>
  30. #include <rtdevice.h>
  31. #include <board.h>
  32. #define UARTCOM_FRAME_LENGTH 11
  33. typedef rt_uint8_t UARTCOM_MYID;
  34. typedef rt_uint8_t UARTCOM_NETID;
  35. typedef rt_uint8_t UARTCOM_AIMID;
  36. typedef rt_uint8_t UARTCOM_GETID;
  37. typedef rt_uint8_t UARTCOM_PACKETID;
  38. typedef enum{
  39. SIMPLEUART = 0,
  40. JC24B,
  41. }UARTCOM_DEVICE;
  42. struct _MODULE_UARTCOM
  43. {
  44. /* Property */
  45. char * Property_UartDevName;
  46. rt_uint32_t Property_BaudRate;
  47. UARTCOM_MYID Property_MyID;
  48. UARTCOM_NETID Property_NetID;
  49. UARTCOM_DEVICE Property_Device;
  50. rt_base_t Property_JC24BsetPin; /*!< Only used when Property_Device is JC24B as set pin. >
  51. This parameter is defined by function @ref GET_PIN(GPIOPORT, GPIO_PIN_NUM) */
  52. /* Value */
  53. rt_device_t Value_uart_dev;
  54. rt_uint8_t Value_sendData[UARTCOM_FRAME_LENGTH];
  55. rt_uint8_t Value_feedData[UARTCOM_FRAME_LENGTH];
  56. UARTCOM_AIMID Value_AimID;
  57. UARTCOM_GETID Value_GetID;
  58. /* Method */
  59. void (*Method_Init)(struct _MODULE_UARTCOM *module);
  60. void (*Method_Send)(struct _MODULE_UARTCOM *module,UARTCOM_PACKETID packetID,rt_int32_t param);
  61. void (*Method_Feed)(struct _MODULE_UARTCOM *module,UARTCOM_PACKETID* packetID,rt_int32_t* param);
  62. void (*Method_Encode)(struct _MODULE_UARTCOM *module,UARTCOM_PACKETID packetID,rt_int32_t param);
  63. void (*Method_Decode)(struct _MODULE_UARTCOM *module,UARTCOM_PACKETID* packetID,rt_int32_t* param);
  64. rt_err_t (*Method_Handle)(rt_device_t dev, rt_size_t size);
  65. };
  66. typedef struct _MODULE_UARTCOM MODULE_UARTCOM;
  67. rt_err_t Module_UartCom_Config(MODULE_UARTCOM *module);
  68. #endif
  69. /************************ (C) COPYRIGHT 2020 WANGXI **************END OF FILE****/

Module_UartCom.c

  1. /*
  2. * Copyright (c) 2020 - ~, HIT_HERO Team
  3. *
  4. * UARTCOM MODULE SOUCE FILE
  5. * Used in RT-Thread Operate System
  6. *
  7. * Change Logs:
  8. * Date Author Notes Mail
  9. * 2020-08-25 WangXi first version WangXi_chn@foxmail.com
  10. * 2020-09-06 WangXi second version WangXi_chn@foxmail.com
  11. */
  12. #include "Module_UartCom.h"
  13. static void Module_UartComInit(MODULE_UARTCOM *module);
  14. static void Module_UartComSend(MODULE_UARTCOM *module,rt_uint8_t packetID,rt_int32_t param);
  15. static void Module_UartComFeed(MODULE_UARTCOM *module,rt_uint8_t* packetID,rt_int32_t* param);
  16. static void Module_UartComEncode(MODULE_UARTCOM *module,rt_uint8_t packetID,rt_int32_t param);
  17. static void Module_UartComDecode(MODULE_UARTCOM *module,rt_uint8_t* packetID,rt_int32_t* param);
  18. static rt_err_t Module_UartComHandle(rt_device_t dev, rt_size_t size);
  19. static struct rt_semaphore uartCom_sem;
  20. static void Module_UartComJC24BConfig(MODULE_UARTCOM *module);
  21. /* Global Method */
  22. rt_err_t Module_UartCom_Config(MODULE_UARTCOM *module)
  23. {
  24. if( module->Method_Init ==NULL &&
  25. module->Method_Handle ==NULL &&
  26. module->Method_Send ==NULL &&
  27. module->Method_Feed ==NULL &&
  28. module->Method_Encode ==NULL &&
  29. module->Method_Decode ==NULL
  30. ){
  31. /* Link the Method */
  32. module->Method_Init = Module_UartComInit;
  33. module->Method_Handle = Module_UartComHandle;
  34. module->Method_Send = Module_UartComSend;
  35. module->Method_Feed = Module_UartComFeed;
  36. module->Method_Encode = Module_UartComEncode;
  37. module->Method_Decode = Module_UartComDecode;
  38. }
  39. else{
  40. rt_kprintf("Warning: Module uart Communication is Configed twice\n");
  41. return RT_ERROR;
  42. }
  43. /* Device Init */
  44. module->Method_Init(module);
  45. return RT_EOK;
  46. }
  47. static void Module_UartComInit(MODULE_UARTCOM *module)
  48. {
  49. module->Value_uart_dev = rt_device_find(module->Property_UartDevName);
  50. if (!module->Value_uart_dev)
  51. {
  52. rt_kprintf("find %s failed!\t\n", module->Value_uart_dev);
  53. return;
  54. }
  55. rt_sem_init(&uartCom_sem, "uartCom_sem", 0, RT_IPC_FLAG_FIFO);
  56. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */
  57. /* step2:修改串口配置参数 */
  58. if(module->Property_BaudRate == 9600)
  59. {
  60. config.baud_rate = BAUD_RATE_9600; //修改波特率为 9600
  61. }
  62. else if(module->Property_BaudRate == 115200)
  63. {
  64. config.baud_rate = BAUD_RATE_115200; //修改波特率为 115200
  65. }
  66. else
  67. {
  68. rt_kprintf("warning: Uartcom's baudrate %d set failed, will be default value 115200\t\n",module->Property_BaudRate);
  69. }
  70. config.data_bits = DATA_BITS_8; //数据位 8
  71. config.stop_bits = STOP_BITS_1; //停止位 1
  72. config.bufsz = 128; //修改缓冲区 buff size 为 128
  73. config.parity = PARITY_NONE; //无奇偶校验位
  74. /* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */
  75. rt_device_control(module->Value_uart_dev, RT_DEVICE_CTRL_CONFIG, &config);
  76. rt_device_open(module->Value_uart_dev, RT_DEVICE_FLAG_DMA_RX);
  77. rt_device_set_rx_indicate(module->Value_uart_dev, module->Method_Handle);
  78. if(module->Property_Device == JC24B)
  79. {
  80. Module_UartComJC24BConfig(module);
  81. }
  82. }
  83. static void Module_UartComSend(MODULE_UARTCOM *module,rt_uint8_t packetID,rt_int32_t param)
  84. {
  85. module->Method_Encode(module,packetID,param);
  86. rt_device_write( module->Value_uart_dev, 0,
  87. &(module->Value_sendData),
  88. sizeof(module->Value_sendData));
  89. }
  90. static void Module_UartComFeed(MODULE_UARTCOM *module,rt_uint8_t* packetID,rt_int32_t* param)
  91. {
  92. rt_uint8_t ch;
  93. rt_uint8_t i = 0;
  94. while (1)
  95. {
  96. while (rt_device_read(module->Value_uart_dev, -1, &ch, 1) == 0)
  97. {
  98. rt_sem_control(&uartCom_sem, RT_IPC_CMD_RESET, RT_NULL);
  99. rt_sem_take(&uartCom_sem, RT_WAITING_FOREVER);
  100. }
  101. if((rt_uint8_t)ch == 0xAA)
  102. {
  103. /* get the frame end flag and start encode the frame */
  104. module->Method_Decode(module,packetID,param);
  105. i = 0;
  106. continue;
  107. }
  108. i = (i >= UARTCOM_FRAME_LENGTH-1) ? UARTCOM_FRAME_LENGTH-1 : i;
  109. module->Value_feedData[i++] = ch;
  110. }
  111. }
  112. static rt_err_t Module_UartComHandle(rt_device_t dev, rt_size_t size)
  113. {
  114. rt_sem_release(&uartCom_sem);
  115. return RT_EOK;
  116. }
  117. static void Module_UartComEncode(MODULE_UARTCOM *module,rt_uint8_t packetID,rt_int32_t param)
  118. {
  119. module->Value_sendData[0] = 0xA5;
  120. module->Value_sendData[1] = 0x5A;
  121. module->Value_sendData[2] = module->Value_AimID;
  122. module->Value_sendData[3] = module->Property_MyID;
  123. module->Value_sendData[4] = packetID;
  124. module->Value_sendData[5] = (rt_uint8_t)((param&0xFF000000)>>24);
  125. module->Value_sendData[6] = (rt_uint8_t)((param&0x00FF0000)>>16);
  126. module->Value_sendData[7] = (rt_uint8_t)((param&0x0000FF00)>>8);
  127. module->Value_sendData[8] = (rt_uint8_t)((param&0x000000FF));
  128. module->Value_sendData[9] = (rt_uint8_t)((module->Value_sendData[2])+
  129. (module->Value_sendData[3])+(module->Value_sendData[4])+
  130. (module->Value_sendData[5])+(module->Value_sendData[6])+
  131. (module->Value_sendData[7])+(module->Value_sendData[8]));
  132. module->Value_sendData[10] = 0xAA;
  133. }
  134. static void Module_UartComDecode(MODULE_UARTCOM *module,rt_uint8_t* packetID,rt_int32_t* param)
  135. {
  136. if( (rt_uint8_t)(module->Value_feedData[0])== 0xA5 &&
  137. (rt_uint8_t)(module->Value_feedData[1])== 0x5A &&
  138. (rt_uint8_t)(module->Value_feedData[2])== module->Property_MyID &&
  139. (rt_uint8_t)((module->Value_feedData[2])+
  140. (module->Value_feedData[3])+(module->Value_feedData[4])+
  141. (module->Value_feedData[5])+(module->Value_feedData[6])+
  142. (module->Value_feedData[7])+(module->Value_feedData[8]))
  143. ==(module->Value_feedData[9]))
  144. {
  145. //Split the data
  146. module->Value_GetID = module->Value_sendData[3];
  147. rt_int32_t Date = ((module->Value_feedData[5])<<24) + ((module->Value_feedData[6])<<16)
  148. +((module->Value_feedData[7])<<8) + ((module->Value_feedData[8]));
  149. *packetID = module->Value_feedData[4];
  150. param[*packetID] = Date;
  151. }
  152. else
  153. {
  154. return;
  155. }
  156. }
  157. static void Module_UartComJC24BConfig(MODULE_UARTCOM *module)
  158. {
  159. char Config_data[18];
  160. rt_pin_mode(module->Property_JC24BsetPin, PIN_MODE_OUTPUT);
  161. rt_pin_write(module->Property_JC24BsetPin, PIN_LOW);
  162. //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
  163. //AA 5A 00 00 00 10 00 00 00 04 00 1F 00 01 00 12 00 06
  164. //0xaa 0x5a 模块ID 组网ID 0x00 RF功率 0x00 波特率 0x00 RF信道 0x00 速率 0x00 0x12 0x00 和校验
  165. rt_thread_mdelay(1);
  166. Config_data[0] = 0xAA;
  167. Config_data[1] = 0x5A;
  168. Config_data[2] = 0x00;
  169. Config_data[3] = module->Property_MyID;
  170. Config_data[4] = 0x00;
  171. Config_data[5] = module->Property_NetID;
  172. Config_data[6] = 0x00;
  173. Config_data[7] = 0x00;
  174. Config_data[8] = 0x00;
  175. Config_data[9] = 0x04;
  176. Config_data[10] = 0x00;
  177. Config_data[11] = 0x1F;
  178. Config_data[12] = 0x00;
  179. Config_data[13] = 0x01;
  180. Config_data[14] = 0x00;
  181. Config_data[15] = 0x12;
  182. Config_data[16] = 0x00;
  183. for(int i = 0;i<17;i++)
  184. Config_data[17] += Config_data[i];
  185. rt_device_write( module->Value_uart_dev, 0,
  186. Config_data, sizeof(Config_data));
  187. rt_thread_mdelay(1);
  188. rt_pin_write(module->Property_JC24BsetPin, PIN_HIGH);
  189. }
  190. /************************ (C) COPYRIGHT 2020 WANGXI **************END OF FILE****/

JC24B无线串口模块资料

物联电子JC24B无线透传模块规格书V1.0.zip

辅助工具

  • 为方便检查帧格式是否正确
  • 以及与串口助手进行数据对比等
  • 用C#窗体设计了一个简易协议帧的生成器

    使用

  • 运行.exe文件

image.png

  • 输入项默认均为0
  • 输入项不可为空否则会报格式错误
  • 以十六进制填入目标系统ID和自身系统ID,以及帧的功能指示ID(帧ID)
  • 以整形int格式填入要传输的数据
  • 点击生成按键,或者直接敲击回车键
  • 即可在帧内容中自动生成
  • 支持复制粘贴
  • 帧头帧尾以及校验计算自动进行
  • 二维码为该篇文章的地址

    执行文件

    BspComProtocolMaker.rar

    源文件

    简易协议帧生成器.rar