【开源获奖案例】智能培养室

——来自迪文开发者论坛

        本期为大家推送迪文开发者论坛获奖开源案例——智能培养室。工程师通过Modbus协议实现了T5L智能屏控制加热、风机控温功能,还可调节电源功率实现模拟光照功能。系统可根据屏幕上设定的参数自动运行,并保存故障历史记录。

一、演示视频

【new4boys】视频已打包,欢迎围观!

完整开发资料含迪文屏DGUS工程资料与C51代码,获取方式:

1、前往迪文开发者论坛下载:

http://inforum.dwin.com.cn:20080/forum.php?mod=viewthread&tid=9586&extra=page%3D12

2、CSDN对应文章下留言获取。

二、UI素材展示


三、UI开发示例

四、C51代码设计

(1)主界面温度、湿度、高度等数据获取和更新,以及使用modbus rtu控制控温模块、电机、报警检测等各个从机的主要代码如下:

    主界面代码参考:

#include "main_win.h"#include "modbus.h"#include "sys_params.h"#include "func_handler.h"#include "uart2.h"#include <stdio.h>#include <string.h>#define TEMP_HUM_SLAVE_ADDR                       2#define TEMP_HUM_VAL_MAX_NUM                      2#define ALERT_BIT_MAX_NUM                         30#define ALERT_BYTE_NUM           (ALERT_BIT_MAX_NUM/8+((ALERT_BIT_MAX_NUM%8)!=0))#define GET_ALERT_BIT(val, pos)        ((val[pos/8]>>(pos%8))&0x01)typedef struct{    char date[17];    u8 desc;}ALERT;#define ALERT_TABLE_LEN                           20static u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};static u8 btn_addr[MAIN_WIN_BTN_MAX_NUM] = {50, 51, 52, 69, 53, 54, 55, 70, 56, 57, 58, 59};u16 main_win_val[MAIN_WIN_VAL_MAX_NUM];u16 temp_hum_val[TEMP_HUM_VAL_MAX_NUM] = {0};u16 date_val[MAIN_WIN_DATE_MAX_NUM] = {0};u8 alert_val[ALERT_BYTE_NUM] = {0};u8 old_alert_val[ALERT_BYTE_NUM] = {0};ALERT alert_table[ALERT_TABLE_LEN];u16 alert_num = 0;bit is_main_win = 0;void main_win_update(){}void main_win_disp_date(){    u8 len;    len = sprintf(common_buf, "%u:%u", (u16)date_val[3], (u16)date_val[4]);    common_buf[len+1] = 0;    sys_write_vp(MAIN_WIN_DATE_VP, common_buf, len/2+2);}void main_win_process_alert(){    u8 i;    for(i=0;i<ALERT_BIT_MAX_NUM;i++)    {        if(GET_ALERT_BIT(old_alert_val, i))            continue;        if(GET_ALERT_BIT(alert_val, i))        {            if(alert_num>=ALERT_TABLE_LEN)                alert_num = ALERT_TABLE_LEN-1;            alert_table[alert_num].desc = i+1;            sprintf(alert_table[alert_num].date, "%u/%u/%u %u:%u",                date_val[0], date_val[1], date_val[2], date_val[3], date_val[4]            );            alert_num++;        }    }    memcpy(old_alert_val, alert_val, sizeof(alert_val));}void main_win_disp_alert(){    u16 i;    u16 val;    u16 len = 0;    common_buf[0] = 0;    for(i=0;i<ALERT_TABLE_LEN;i++)    {        val = 0;        if(i<alert_num)        {            val = alert_table.desc;            len += sprintf(common_buf+len, "%s\r\n", alert_table.date);        }        sys_write_vp(ALERT_WIN_DESC_START_VP+i, (u8*)&val, 1);    }    common_buf[len+1] = 0;    sys_write_vp(ALERT_WIN_DATE_VP, common_buf, len/2+2);}void main_win_init(){    float fixed_val;    u8 i;    is_main_win = 1;
    main_win_val[5] = (u16)(temp_hum_val[0]/10.0+0.5f);    main_win_val[6] = (u16)(temp_hum_val[1]/10.0+0.5f);    for(i=0;i<MAIN_WIN_VAL_MAX_NUM;i++)    {        if(i==0)            continue;sys_write_vp(MAIN_WIN_WIND_SPEED_VP+MAIN_WIN_VAL_OFFSET*i, (u8*)&main_win_val, 1);    }    fixed_val = main_win_val[0]/WIND_SPEED_SCALE+FLOAT_FIX_VAL;    sys_write_vp(MAIN_WIN_WIND_SPEED_VP, (u8*)&fixed_val, 2);}void main_win_click_handler(u16 btn_val){    u8 index;    if(btn_val==0x0B)    {        main_win_disp_alert();        return;    }    index = btn_val-1;    btn_sta[index] = !btn_sta[index];    if((index==3)||(index==7))        btn_sta[index] = 1;    modbus_write_bit(btn_addr[index], btn_sta[index]?0xFF00:0x0000);    btn_val = btn_sta[index];sys_write_vp(MAIN_WIN_BTN_STA_START_VP+MAIN_WIN_BTN_STA_OFFSET*index, (u8*)&btn_val, 1);    if(index==9)        is_main_win = 0;    else if((index==3)||(index==7))    {        while(sys_get_touch_sta());        modbus_write_bit(btn_addr[index], 0x0000);    }}void main_win_msg_handler(u8 *msg,u16 msg_len){    u8 f_code = msg[MODBUS_RESPOND_POS_FUNC_CODE];    u8 data_len = msg[MODBUS_RESPOND_POS_DATA_LEN];    u8 i;    u8 offset;    msg_len = msg_len;    if(!is_main_win)        return;if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_VAL_MAX_NUM*2))    {        offset = MODBUS_RESPOND_POS_DATA;        for(i=0;i<MAIN_WIN_VAL_MAX_NUM;i++)        {            main_win_val = SYS_GET_U16(msg[offset], msg[offset+1]);            offset += 2;        }        main_win_update();    }else if((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))    {        offset = MODBUS_RESPOND_POS_DATA;        for(i=0;i<ALERT_BYTE_NUM;i++)        {            alert_val = msg[offset];            offset++;        }        main_win_process_alert();    }else if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))    {        offset = MODBUS_RESPOND_POS_DATA;        for(i=0;i<TEMP_HUM_VAL_MAX_NUM;i++)        {            temp_hum_val = SYS_GET_U16(msg[offset], msg[offset+1]);            offset += 2;            modbus_write_word(5+i, temp_hum_val);        }        main_win_update();    }else if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))    {        offset = MODBUS_RESPOND_POS_DATA;        for(i=0;i<MAIN_WIN_DATE_MAX_NUM;i++)        {            date_val = SYS_GET_U16(msg[offset], msg[offset+1]);            offset += 2;        }        main_win_disp_date();    }}void main_win_read_temp_hum(){    u8 old_slave_addr = SLAVE_ADDR;            sys_params.user_config[5] = TEMP_HUM_SLAVE_ADDR;    modbus_read_words(0, TEMP_HUM_VAL_MAX_NUM);    sys_params.user_config[5] = old_slave_addr;//还原}void main_win_handler(){    static u8 flag = 0;    if(is_main_win)    {        if(alert_read_period==ALERT_READ_PERIOD)        {            alert_read_period = 0;            modbus_read_bits(510, ALERT_BIT_MAX_NUM);            return;        }        if(date_update_period==DATE_UPDATE_PERIOD)        {            date_update_period = 0;            modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);            return;        }        flag = !flag;        if(flag)            modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);        else            main_win_read_temp_hum();    }}

    modbus rtu代码参考:

#include "modbus.h"#include "crc16.h"#include "sys_params.h"#define UART_INCLUDE                            "uart2.h"#define UART_INIT                               uart2_init#define UART_SEND_BYTES                         uart2_send_bytes#define UART_BAUD                               9600#define MODBUS_RECV_TIMEOUT                     (u8)(35000.0f/UART_BAUD+2)#define MODBUS_SEND_INTERVAL                    150#include UART_INCLUDEstatic bit is_modbus_recv_complete = 0;static u8 modbus_recv_buff[270];static u16 modbus_recv_len = 0;//接受的总字节长度static u8 modbus_recv_timeout = 0;//接受溢出时间static volatile u16 modbus_send_interval = 0;MODBUS_PACKET packet;void modbus_init(){    UART_INIT(UART_BAUD);}void modbus_send_bytes(u8 *bytes,u16 len){    UART_SEND_BYTES(bytes,len);}void modbus_recv_byte(u8 byte){    if(is_modbus_recv_complete)        return;    if(modbus_recv_len<sizeof(modbus_recv_buff))        modbus_recv_buff[modbus_recv_len++] = byte;}void modbus_check_recv_timeout(){    if(modbus_recv_timeout)    {        modbus_recv_timeout--;        if(modbus_recv_timeout==0)        {            is_modbus_recv_complete = 1;        }    }}u8 modbus_send_packet(u8 *packet){    u16 len;    u16 crc;    u8 func_code = packet[1];    while(modbus_send_interval);    if(func_code==MODBUS_FUNC_CODE_10)    {        ((MODBUS_10_PACKET*)packet)->byte_num = ((MODBUS_10_PACKET*)packet)->word_num*2;        len = 9+((MODBUS_10_PACKET*)packet)->byte_num;    }else if(func_code==MODBUS_FUNC_CODE_0F)    {        len = ((MODBUS_0F_PACKET*)packet)->bit_num;        ((MODBUS_0F_PACKET*)packet)->byte_num = len/8+(len%8?1:0);        len = 9+((MODBUS_0F_PACKET*)packet)->byte_num;    }else    {        len = sizeof(MODBUS_PACKET);    }    crc = crc16(packet,len-2);    packet[len-2] = (u8)(crc>>8);    packet[len-1] = (u8)crc;    modbus_send_bytes(packet,len);    modbus_send_interval = MODBUS_SEND_INTERVAL;    return 0;//成功}extern void modbus_msg_handler(u8 *msg,u16 msg_len);void modbus_handler(){    u16 crc;    if(!is_modbus_recv_complete)        return;    //校验crc值    crc = ((u16)modbus_recv_buff[modbus_recv_len-2]<<8)+modbus_recv_buff[modbus_recv_len-1];    if(crc16(modbus_recv_buff,modbus_recv_len-2)==crc)    {        modbus_msg_handler(modbus_recv_buff,modbus_recv_len);    }    modbus_recv_len = 0;    is_modbus_recv_complete = 0;        }u8 modbus_send_fcode(u8 fcode, u16 addr, u16 len){    packet.slave_addr = SLAVE_ADDR;    packet.func_code = fcode;//功能码    packet.start_addr = addr;//地址    packet.data_len = len;//写入的值    len = modbus_send_packet((u8*)&packet);    return len;}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值