Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Modbus
freemodbus
使用free modubs,在通讯运行过程中修改通讯参数,系统报错
发布于 2021-08-23 18:42:01 浏览:959
订阅该版
首次初始化,free modubs运行正常,在通讯过程中,修改通讯参数,如从机地址、波特率,系统报错 ``` “(obj != object) assertion failed at function:rt_object_init, line number:328” ``` 请问大家,这可能是什么原因? ![image.png](https://oss-club.rt-thread.org/uploads/20210823/0b7f34a8beaa9488d0ac3e067cbd5c6a.png) 还有,是不是现在的程序框架初始化后,不允许运行过程中修改通讯参数?
查看更多
2
个回答
默认排序
按发布时间排序
出出啊
2021-08-24
恃人不如自恃,人之为己者不如己之自为也
修改 freemodbus 从机地址怎么会涉及到 `rt_object_init` ?程序里可能有内存溢出,导致系统对象树被破坏了。
Betrayer
2024-11-13
这家伙很懒,什么也没写!
```c /* * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2021-12-18 BruceOu first implementation */ #include
#include
#include
#include
#include "fal_cfg.h" #include "fal.h" #include "SHT40.h" #include "LCD.h" #include "mb.h" #include "user_mb_app.h" #include "button.h" #include "mb.h" #include "mb.h" #include "mbrtu.h" #include "mbframe.h" #include "port.h" #include "mbcrc.h" #include "mbport.h" #define GD32_FLASH_START_ADRESS ((uint32_t)0x08180000) //我的是1M,自己看芯片ROM大小 #define GD32_MODBUS_OFFSET ((uint32_t)0x00018000) //偏移地址 extern int flag; int flag = 0; /*变量*/ uint8_t Tab0[] = {0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00}; uint8_t Temperature_code[] = {0xDF,0x0E,0xEB,0xAF,0x3E,0xBD,0xFD,0X0F,0XFF,0xBF}; uint8_t Temperature_address[] = {0x0C,0X0E,0X10}; uint8_t Humidity_code[] = {0xFD,0xE0,0xBE,0xFA,0xE3,0xDB,0xDF,0XF0,0XFF,0xFB}; uint8_t Humidity_address[] = {0X03,0X05,0X07}; uint8_t Temperature_code_no_point [] ={0xD7,0X06,0XE3,0XA7,0X36,0XB5,0XF5,0X07,0XF7,0XB7}; uint8_t Humidity_code_no_point [] ={0X7D,0X60,0X3E,0X7A,0X63,0X5B,0X5F,0X70,0X7F,0X7B}; uint8_t Page_char[]={0x77,0x4f,0x6e,0x0f,0x4e,0x67,0x37,0x6d,0x0d,0x1A,0x1f,0x0F,0xA1,0xF1,0xF0}; float Temperature,Humidity; extern SHORT usSRegHoldBuf[S_REG_HOLDING_NREGS]; extern long int ustest[10]; /* defined the LED2 pin: PC0 */ #define LED2_PIN GET_PIN(B, 8) Key_id_flag KEY_ID = key_NULL;//按键返回标志枚举变量 Page_choose PAGE_ID = Main_page;//页面返回标志枚举变量 SET_TEST_MODE_Show PAGE_SHOW;//这个只是显示,这个显示应该跟modbus的寄存器相关,并且这个这只是初始化 /*这个值要用modbus的寄存器进行给*/ Page_number PAGE_NUMBER_SHOW = Page_NULL; extern uint16_t PAGE_ADD; int Semaphore_count = 0; int Semaphore_count_main_page = 0; int test_flag = 0; static uint32_t test_addr[32]; /*消息队列控制块*/ struct rt_messagequeue mq_init; /*消息队列中用到的放置消息的内存池*/ static rt_uint8_t msg_poll[2048]; rt_mq_t messageQueue; /*指向互斥量的指针*/ static rt_mutex_t dynamic_mutex = RT_NULL; /*堆栈空间*/ static char led_stack[256]; static char senor_stack[512]; static char lcd_stack[512]; static char modbus_send_stack[4096]; static char modbus_receive_stack[4096]; static char messagequeue_stack[1024]; static char key_stack[2048]; static char lcd_page_stack[1024]; static char modbus_init_stack[1024]; /*线程句柄*/ static struct rt_thread led_task; static struct rt_thread senor_task; static struct rt_thread lcd_task; static struct rt_thread modbus_send_task; static struct rt_thread modbus_receive_task; static struct rt_thread messagequeue_task; static struct rt_thread key_task; static struct rt_thread lcd_page_task; static struct rt_thread modbus_init_task; /* 备注 1:信号量的处理,在每一次按键进去都使得信号量加1了,所以要在每个获取信号量后加1Semaphore_count, 这样才能使得回退的时候有足够的释放信号量,不然就会卡死 */ static void hook_of_scheduler(struct rt_thread* from, struct rt_thread* to) { #if defined(RT_VERSION_CHECK) && (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 1)) rt_kprintf("from: %s --> to: %s \n", from->parent.name ,to->parent.name); #else rt_kprintf("from: %s --> to: %s \n", from->name , to->name); #endif } /*页面切换线程入口*/ static void lcd_page_entry(void *parameter) { while(1) { //rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);不能在这里加读取互斥量的信号,不然会一直卡着 if(PAGE_ID == Secondary_page) { switch(KEY_ID)//在设置页面 { case Key_set_short: { /* 1:获取信号量 2:直接释放信号量,让LCD线程工作 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);//获取信号量 Semaphore_count++;//每一个获得信号量的地方都要加 rt_kprintf("Semaphore_count = %d",Semaphore_count); KEY_ID = key_NULL;//让按键变成空 PAGE_ID = Main_page;//页面短按枚举变量 //PAGE_NUMBER_SHOW = Page_NULL; PAGE_ADD = 0; LCD_Clear();//清屏一下 for( ; Semaphore_count > 0 ; Semaphore_count-- ) { rt_mutex_release(dynamic_mutex);//释放信号量 rt_kprintf("Semaphore_count = %d",Semaphore_count); } rt_mutex_release(dynamic_mutex);//释放信号量 break; } case Key_set_long: { /* 1:锁住信号量,不让LCD线程工作 2:显示地址页面 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);//获取信号量 LCD_Clear();//清屏一下 Semaphore_count++;//每一个获得信号量的地方都要加 rt_kprintf("Semaphore_count = %d",Semaphore_count); //addr_dispaly(PAGE_SHOW,usSRegHoldBuf);//显示地址页面 Set_display(); KEY_ID = key_NULL;//让按键变成空,以免一直是这个状态进来 /*避免重复显示地址页*/ // if(PAGE_NUMBER_SHOW == Page_NULL) // { // PAGE_ADD += 1; // } break; } case Key_return_short: { /* 1:锁住信号量,不让LCD线程工作 2:显示地址页面 */ int i; uint16_t len,ret; rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);//获取信号量 Semaphore_count++;//每一个获得信号量的地方都要加 rt_kprintf("Semaphore_count = %d",Semaphore_count); KEY_ID = key_NULL;//让按键变成空 PAGE_ID = Main_page;//页面短按枚举变量 PAGE_NUMBER_SHOW = Page_NULL; PAGE_ADD = 0; LCD_Clear();//清屏一下 //fal_write("download"); //fal_read("download"); /*这里进行串口的初始化*/ /* 串口初始化中有一个线程他的优先级很低才10,假如说我的线程现在退出,那抢占的一定是 高优先级的,那么我初始化的线程就一定会卡死在那边,那要用互斥量吗? 还是说将他的优先级调高,抢在LCD前面?,也就是这个初始化的优先级,不能比按键,modbus高,但是 需要比LCD高? */ /* debug的时候这个甚至不需要我按键就可以直接到这里,为什么? */ //xMBPortSerialInit( usSRegHoldBuf[2], usSRegHoldBuf[3], 8, MB_PAR_NONE ); /*根本没有进去?*/ eMBDisable(); eMBInit(MB_RTU, usSRegHoldBuf[2], 0, usSRegHoldBuf[3], MB_PAR_NONE); eMBEnable(); /* 1.在这里直接关机 2.找出每个线程之间的关系 3.调整线程之间的优先级 4.用钩子函数初始化? */ //rt_thread_delay(10); 这里在页面切换的时候不止一次获得信号量,所以我们这里要计数几次就释放几次 */ for( ; Semaphore_count > 0 ; Semaphore_count-- ) { rt_mutex_release(dynamic_mutex);//释放信号量 rt_kprintf("Semaphore_count = %d\n",Semaphore_count); } rt_mutex_release(dynamic_mutex);//释放信号量 break; } // case Key_return_long: // { // /* // 1:锁住信号量,不让LCD线程工作 // 2:显示地址页面 // */ // rt_mutex_release(dynamic_mutex);//释放信号量 // rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);//获取信号量 // rt_mutex_release(dynamic_mutex);//释放信号量 // KEY_ID = key_NULL;//让按键变成空 // PAGE_ID = Main_page;//页面短按枚举变量 // break; // } case Key_turn_short: { /* 1:锁住信号量,不让LCD线程工作 2:判断切换页面信号进行切换页面 3:显示页面 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);//获取信号量 Semaphore_count++;//每次进来这个信号量计算加1 rt_kprintf("Semaphore_count = %d",Semaphore_count); KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 switch(PAGE_NUMBER_SHOW) { case ADDRESS: { addr_dispaly(PAGE_SHOW,usSRegHoldBuf);//显示地址页面 break; } case BAUDRATE: { baud_dispaly(PAGE_SHOW,usSRegHoldBuf);//波特率显示页面 break; } case TEMP_UPPER: { Upper_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度上限显示页面 break; } case HUM_UPPER: { Upper_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度上限显示页面 break; } case TEMP_LOWER: { Lower_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度下限显示页面 break; } case HUM_LOWER: { Lower_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度下限显示页面 break; } case Page_NULL: { break; } default:break; } break; } // case Key_turn_long: // { // /* // 1:直接释放信号量,让LCD线程工作 // 2:长按无反应吧 // */ // //rt_mutex_release(dynamic_mutex); // KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 // break; // } case key_up_short: { /* 1:锁住信号量,不让LCD线程工作 2:更改变量 3:显示页面 4:释放信号量 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); Semaphore_count++;//每次进来这个信号量计算加1 rt_kprintf("Semaphore_count = %d",Semaphore_count); KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 switch(PAGE_NUMBER_SHOW)//这里判断是处于什么页面 { case ADDRESS: { /* 1.首先将变量进行更改 2.再将变量给到modbus变量 3.进行显示 */ usSRegHoldBuf[2] = PAGE_SHOW.Device_Address_Show += 1;//首先将变量进行更改,再将变量给到modbus变量 addr_dispaly(PAGE_SHOW,usSRegHoldBuf);//显示地址页面 break; } case BAUDRATE: { /*判断当前的波特率*/ if (PAGE_SHOW.Device_baud_rate == 4800) { usSRegHoldBuf[3] = 9600; PAGE_SHOW.Device_baud_rate = 9600; } else if (PAGE_SHOW.Device_baud_rate == 9600) { PAGE_SHOW.Device_baud_rate = 2400; usSRegHoldBuf[3] = 2400; } else { PAGE_SHOW.Device_baud_rate = 4800; usSRegHoldBuf[3] = 4800; } baud_dispaly(PAGE_SHOW,usSRegHoldBuf);//波特率显示页面 break; } case TEMP_UPPER: { usSRegHoldBuf[4] = PAGE_SHOW.Upper_temperature_limit += 1; Upper_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度上限显示页面 break; } case HUM_UPPER: { usSRegHoldBuf[5] = PAGE_SHOW.Upper_humidity_limit += 1; Upper_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度上限显示页面 break; } case TEMP_LOWER: { usSRegHoldBuf[6] = PAGE_SHOW.Lower_temperature_limit += 1; Lower_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度下限显示页面 break; } case HUM_LOWER: { usSRegHoldBuf[7] = PAGE_SHOW.Lower_humidity_limit += 1; Lower_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度下限显示页面 break; } case Page_NULL: { break; } default:break; } break; } case key_up_long: { /* 1:锁住信号量,不让LCD线程工作 2:更改变量 3:显示页面 4:释放信号量 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); Semaphore_count++;//每次进来这个信号量计算加1 rt_kprintf("Semaphore_count = %d",Semaphore_count); KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 switch(PAGE_NUMBER_SHOW)//这里判断是处于什么页面 { case ADDRESS: { /* 1.首先将变量进行更改 2.再将变量给到modbus变量 3.进行显示 */ usSRegHoldBuf[2] = PAGE_SHOW.Device_Address_Show += 10;//首先将变量进行更改,再将变量给到modbus变量 addr_dispaly(PAGE_SHOW,usSRegHoldBuf);//显示地址页面 break; } case BAUDRATE: { /*判断当前的波特率*/ if (PAGE_SHOW.Device_baud_rate == 4800) { usSRegHoldBuf[3] = 9600; PAGE_SHOW.Device_baud_rate = 9600; } else if (PAGE_SHOW.Device_baud_rate == 9600) { PAGE_SHOW.Device_baud_rate = 2400; usSRegHoldBuf[3] = 2400; } else { PAGE_SHOW.Device_baud_rate = 4800; usSRegHoldBuf[3] = 4800; } baud_dispaly(PAGE_SHOW,usSRegHoldBuf);//波特率显示页面 break; } case TEMP_UPPER: { usSRegHoldBuf[4] = PAGE_SHOW.Upper_temperature_limit += 10; Upper_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度上限显示页面 break; } case HUM_UPPER: { usSRegHoldBuf[5] = PAGE_SHOW.Upper_humidity_limit += 10; Upper_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度上限显示页面 break; } case TEMP_LOWER: { usSRegHoldBuf[6] = PAGE_SHOW.Lower_temperature_limit += 10; Lower_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度下限显示页面 break; } case HUM_LOWER: { usSRegHoldBuf[7] = PAGE_SHOW.Lower_humidity_limit += 10; Lower_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度下限显示页面 break; } case Page_NULL: { break; } default:break; } break; } case key_down_short: { /* 1:锁住信号量,不让LCD线程工作 2:更改变量 3:显示页面 4:释放信号量 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); Semaphore_count++;//每次进来这个信号量计算加1 rt_kprintf("Semaphore_count = %d",Semaphore_count); KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 switch(PAGE_NUMBER_SHOW)//这里判断是处于什么页面 { case ADDRESS: { /* 1.首先将变量进行更改 2.再将变量给到modbus变量 3.进行显示 */ usSRegHoldBuf[2] = PAGE_SHOW.Device_Address_Show -= 1;//首先将变量进行更改,再将变量给到modbus变量 addr_dispaly(PAGE_SHOW,usSRegHoldBuf);//显示地址页面 break; } case BAUDRATE: { /*判断当前的波特率*/ if (PAGE_SHOW.Device_baud_rate == 4800) { usSRegHoldBuf[3] = 9600; PAGE_SHOW.Device_baud_rate = 9600; } else if (PAGE_SHOW.Device_baud_rate == 9600) { PAGE_SHOW.Device_baud_rate = 2400; usSRegHoldBuf[3] = 2400; } else { PAGE_SHOW.Device_baud_rate = 4800; usSRegHoldBuf[3] = 4800; } baud_dispaly(PAGE_SHOW,usSRegHoldBuf);//波特率显示页面 break; } case TEMP_UPPER: { usSRegHoldBuf[4] = PAGE_SHOW.Upper_temperature_limit -= 1; Upper_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度上限显示页面 break; } case HUM_UPPER: { usSRegHoldBuf[5] = PAGE_SHOW.Upper_humidity_limit -= 1; Upper_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度上限显示页面 break; } case TEMP_LOWER: { usSRegHoldBuf[6] = PAGE_SHOW.Lower_temperature_limit -= 1; Lower_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度下限显示页面 break; } case HUM_LOWER: { usSRegHoldBuf[7] = PAGE_SHOW.Lower_humidity_limit -= 1; Lower_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度下限显示页面 break; } case Page_NULL: { break; } default:break; } break; } case key_down_long: { /* 1:锁住信号量,不让LCD线程工作 2:更改变量 3:显示页面 4:释放信号量 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); Semaphore_count++;//每次进来这个信号量计算加1 rt_kprintf("Semaphore_count = %d",Semaphore_count); KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 switch(PAGE_NUMBER_SHOW)//这里判断是处于什么页面 { case ADDRESS: { /* 1.首先将变量进行更改 2.再将变量给到modbus变量 3.进行显示 */ usSRegHoldBuf[2] = PAGE_SHOW.Device_Address_Show -= 10;//首先将变量进行更改,再将变量给到modbus变量 addr_dispaly(PAGE_SHOW,usSRegHoldBuf);//显示地址页面 break; } case BAUDRATE: { /*判断当前的波特率*/ if (PAGE_SHOW.Device_baud_rate == 4800) { usSRegHoldBuf[3] = 9600; PAGE_SHOW.Device_baud_rate = 9600; } else if (PAGE_SHOW.Device_baud_rate == 9600) { PAGE_SHOW.Device_baud_rate = 2400; usSRegHoldBuf[3] = 2400; } else { PAGE_SHOW.Device_baud_rate = 4800; usSRegHoldBuf[3] = 4800; } baud_dispaly(PAGE_SHOW,usSRegHoldBuf);//波特率显示页面 break; } case TEMP_UPPER: { usSRegHoldBuf[4] = PAGE_SHOW.Upper_temperature_limit -= 10; Upper_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度上限显示页面 break; } case HUM_UPPER: { usSRegHoldBuf[5] = PAGE_SHOW.Upper_humidity_limit -= 10; Upper_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度上限显示页面 break; } case TEMP_LOWER: { usSRegHoldBuf[6] = PAGE_SHOW.Lower_temperature_limit -= 10; Lower_temperature_limit_display(PAGE_SHOW,usSRegHoldBuf);//温度下限显示页面 break; } case HUM_LOWER: { usSRegHoldBuf[7] = PAGE_SHOW.Lower_humidity_limit -= 10; Lower_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf);//湿度下限显示页面 break; } case Page_NULL: { break; } default:break; } break; } case key_NULL: { break; } } } else if(PAGE_ID == Main_page) { switch(KEY_ID) { case Key_set_short: { /* 1:通过短按按键对整个信号量的退出处理 */ LCD_Clear();//清屏一下 KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 for( ; Semaphore_count_main_page>-2 ; Semaphore_count_main_page-- ) { rt_mutex_release(dynamic_mutex);//释放信号量 rt_kprintf("Semaphore_count = %d\n",Semaphore_count_main_page); } rt_mutex_release(dynamic_mutex);//释放信号量 break; } case Key_return_short: { /* 1:通过短按按键对整个信号量的退出处理 */ LCD_Clear();//清屏一下 KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 for( ; Semaphore_count_main_page>-2 ; Semaphore_count_main_page-- ) { rt_mutex_release(dynamic_mutex);//释放信号量 rt_kprintf("Semaphore_count = %d\n",Semaphore_count_main_page); } rt_mutex_release(dynamic_mutex);//释放信号量 break; } case Key_turn_short: { /* 1:获取信号量 2:信号量参数变量自增 3:显示当前设备的地址和波特率 4:通过短按按键对整个信号量的退出处理 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); Semaphore_count_main_page++; LCD_Clear();//清屏一下 KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 usSRegHoldBuf[2] = PAGE_SHOW.Device_Address_Show; usSRegHoldBuf[3] = PAGE_SHOW.Device_baud_rate; addr_and_baud_display(PAGE_SHOW,usSRegHoldBuf); break; } case key_up_short: { /* 1:获取信号量 2:信号量参数变量自增 3:显示当前设置的温湿度上限 4:通过短按按键对整个信号量的退出处理 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); Semaphore_count_main_page++; LCD_Clear();//清屏一下 KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 usSRegHoldBuf[4] = PAGE_SHOW.Upper_temperature_limit; usSRegHoldBuf[5] = PAGE_SHOW.Upper_humidity_limit; up_temperature_and_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf); break; } case key_down_short: { /* 1:获取信号量 2:信号量参数变量自增 3:显示当前设置的温湿度下限 4:通过短按按键对整个信号量的退出处理 */ rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); Semaphore_count_main_page++; LCD_Clear();//清屏一下 KEY_ID = key_NULL;//让按键变成空,这样下一个Switch只进入一次 usSRegHoldBuf[6] = PAGE_SHOW.Lower_temperature_limit; usSRegHoldBuf[7] = PAGE_SHOW.Lower_humidity_limit; down_temperature_and_humidity_limit_display(PAGE_SHOW,usSRegHoldBuf); break; } case key_NULL: { break; } default : break; } } rt_thread_delay(100); } } /*按键检测线程入口*/ static void key_entry(void *parameter) { while(1) { Button_Process(); rt_thread_mdelay(10); } } /*modbus发送线程入口*/ static void modbus_send_entry(void *parameter) { SHORT *usRegHoldingBuf; usRegHoldingBuf = usSRegHoldBuf;//这里应该不是赋值,而是地址对地址,地址相同 rt_base_t level; int i = -1; float temperature_temp; float humidity_temp; while (1) { /*消息队列对象的句柄,消息内容,消息大小,指定的超时时间*/ rt_mq_recv(messageQueue,&temperature_temp,4,RT_WAITING_FOREVER); rt_mq_recv(messageQueue,&humidity_temp,4,RT_WAITING_FOREVER); //rt_kprintf("Recv data:%d\n",rep_queue); level = rt_hw_interrupt_disable(); /*在这里修改数组可以直接映射到user_mb_app.c的保持寄存器的值*/ usRegHoldingBuf[0] = (USHORT)(temperature_temp*100);//(USHORT)(rt_tick_get() / 100);//我就说之前的第三个寄存器怎么自己就加上去了//这里的tick是11~12这样的往上加 usRegHoldingBuf[1] = (USHORT)(humidity_temp*100); rt_hw_interrupt_enable(level); rt_thread_mdelay(1000); } } /*modbus接收线程入口*/ static void modbus_receive_entry(void *parameter) { /*这里进行串口的初始化*/ eMBInit(MB_RTU, usSRegHoldBuf[2], 0, usSRegHoldBuf[3], MB_PAR_NONE); eMBEnable(); while(1) { /* 这里面不能再次初始化,不然会卡死 */ eMBPoll(); rt_thread_mdelay(200); } } /*传感器线程入口*/ static void senor_entry(void *parameter) { /*循环方式为死循环*/ while(1) { SHT40_Measure(&Temperature,&Humidity); //rt_kprintf("Temperature is %d\n\r",Temperature); //rt_kprintf("Humidity is %d\n\r",Humidity); rt_mq_send_wait(messageQueue,&Temperature,4,RT_WAITING_FOREVER);//发送温度 rt_mq_send_wait(messageQueue,&Humidity,4,RT_WAITING_FOREVER); rt_thread_mdelay(1000); } /*这里的数据能否用邮箱传递到LCD线程当中*/ } /*LED灯线程入口*/ static void led_entry(void *parameter) { /* set LED2 pin mode to output */ rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT); while(1) { rt_pin_write(LED2_PIN, PIN_HIGH); rt_thread_mdelay(50); rt_pin_write(LED2_PIN, PIN_LOW); rt_thread_mdelay(50); } } /*lcd线程入口*/ static void lcd_entry(void *parameter) { float temperature_temp; float humidity_temp; LCD_Clear();//清屏一下 while(1) { rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); rt_mq_recv(messageQueue,&temperature_temp,4,RT_WAITING_FOREVER); rt_mq_recv(messageQueue,&humidity_temp,4,RT_WAITING_FOREVER); LCD_Temperature_Humidity_Show(temperature_temp,humidity_temp); rt_mutex_release(dynamic_mutex); rt_thread_mdelay(1000); } /*这里接受邮件的接受端*/ } int main(void) { /* 设置调度器钩子 */ //rt_scheduler_sethook(hook_of_scheduler); /*创建一个动态互斥量*/ dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_FIFO); /*初始化*/ fal_init(); key_init(); /*奇怪现象,当TM1621_init();和LCD_GPIO_Config();在board.c中的系统进入口初始化, 这个LCD屏幕就不会亮,但是再烧写之前不用系统的程序屏幕可以亮,然后再烧系统程序就可以亮了 1.必须在main中初始化一下 2.必须在board.c中初始化一下 否则1:烧录屏幕不亮 否则2:断电重启屏幕不亮 */ IIC_GPIO_INIT(); TM1621_init(); LCD_GPIO_Config(); /*消息队列名称,消息队列中一条消息的最大长度,单位字节,消息队列的最大个数,等待方式*/ messageQueue = rt_mq_create("mqFirst", 4, 10, RT_IPC_FLAG_FIFO); fal_read("download");//一进主函数就要读取flash一下给modbus的变量 /*页面初始化*/ PAGE_SHOW.Device_Address_Show = usSRegHoldBuf[2]; PAGE_SHOW.Device_baud_rate = usSRegHoldBuf[3]; PAGE_SHOW.Upper_temperature_limit = usSRegHoldBuf[4]; PAGE_SHOW.Upper_humidity_limit = usSRegHoldBuf[5]; PAGE_SHOW.Lower_temperature_limit = usSRegHoldBuf[6]; PAGE_SHOW.Lower_humidity_limit = usSRegHoldBuf[7]; rt_thread_init(&senor_task, "SHT40", senor_entry, (void*)1, &senor_stack[0], sizeof(senor_stack), 2, 20); rt_thread_startup(&senor_task); rt_thread_init(&led_task, "LED", led_entry, (void*)8, &led_stack[0], sizeof(led_stack), 9, 20); rt_thread_startup(&led_task); rt_thread_init(&lcd_task, "LCD", lcd_entry, (void*)3, &lcd_stack[0], sizeof(lcd_stack), 3, 20); rt_thread_startup(&lcd_task); rt_thread_init(&modbus_send_task, "modbus_send", modbus_send_entry, (void*)4, &modbus_send_stack[0], sizeof(modbus_send_stack), 5, 20); rt_thread_startup(&modbus_send_task); rt_thread_init(&modbus_receive_task, "modbus_receive", modbus_receive_entry, (void*)5, &modbus_receive_stack[0], sizeof(modbus_receive_stack), 6, 20); rt_thread_startup(&modbus_receive_task); rt_thread_init(&key_task, "key", key_entry, (void*)6, &key_stack[0], sizeof(key_stack), 7, 20); rt_thread_startup(&key_task); rt_thread_init(&lcd_page_task, "key", lcd_page_entry, (void*)7, &lcd_page_stack[0], sizeof(lcd_page_stack), 8, 20); rt_thread_startup(&lcd_page_task); return 0; } ``` 贴上代码给大家看看
撰写答案
登录
注册新账号
关注者
0
被浏览
959
关于作者
bblythe2016
这家伙很懒,什么也没写!
提问
19
回答
15
被采纳
0
关注TA
发私信
相关问题
1
ModbusRTU协议栈漏发送最后一个字节
2
3.0 增加freemodbus,编译不过
3
RT_THREAD上面的串口MODBUSRTU为啥没功能码?
4
关于 freemodbus 里存在的一点问题分享
5
请教如何使用组件里的FreeMODBUS
6
求一个FreeModbus的从机测试程序
7
FreeModbus的从机调试说明(含测试程序)
8
rtt_freemodbus
9
freemodbus怎么配置到uart
10
FreeModeBus从机调试问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
2
RT-Thread EtherKit开源以太网硬件正式发布
3
如何在master上的BSP中添加配置yml文件
4
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
5
RT-Thread 发布 EtherKit开源以太网硬件!
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
MicroPython
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
15
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部