——來自迪文開發(fā)者論壇
本期為大家推送迪文開發(fā)者論壇獲獎(jiǎng)開源案例——智能培養(yǎng)室。工程師通過Modbus協(xié)議實(shí)現(xiàn)了T5L智能屏控制加熱、風(fēng)機(jī)控溫功能,還可調(diào)節(jié)電源功率實(shí)現(xiàn)模擬光照功能。系統(tǒng)可根據(jù)屏幕上設(shè)定的參數(shù)自動(dòng)運(yùn)行,并保存故障歷史記錄。
UI素材展示
?
UI開發(fā)示例
C51代碼設(shè)計(jì)
(1)主界面溫度、濕度、高度等數(shù)據(jù)獲取和更新,以及使用modbus rtu控制控溫模塊、電機(jī)、報(bào)警檢測(cè)等各個(gè)從機(jī)的主要代碼如下:
主界面代碼參考:
#include "main_win.h"#include "modbus.h"#include "sys_params.h"
#include "func_handler.h"
#include "uart2.h"#include #include #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;#defineALERT_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 { 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 { val = 0; if(i { 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 { 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 = 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_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 = 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 { 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;//接受的總字節(jié)長(zhǎng)度
static u8 modbus_recv_timeout = 0;//接受溢出時(shí)間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 { 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; //校驗(yàn)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;}
-
電源
+關(guān)注
關(guān)注
185文章
18985瀏覽量
264548 -
ModBus協(xié)議
+關(guān)注
關(guān)注
3文章
191瀏覽量
35424 -
迪文屏
+關(guān)注
關(guān)注
3文章
89瀏覽量
6072 -
智能屏幕
+關(guān)注
關(guān)注
0文章
76瀏覽量
3866
發(fā)布評(píng)論請(qǐng)先 登錄
復(fù)旦大學(xué)計(jì)算與智能創(chuàng)新學(xué)院深耕開源人才評(píng)價(jià)改革,入選校級(jí)教育評(píng)價(jià)改革優(yōu)秀成果
中軟國(guó)際開源鴻蒙智慧會(huì)議室打造空間管理新時(shí)代
華科大網(wǎng)安學(xué)院開源工坊人才培養(yǎng)新模式的主要成果
普華基礎(chǔ)軟件出席開源車用操作系統(tǒng)人才培養(yǎng)啟動(dòng)儀式
學(xué)以致用 虛位以待|玄鐵RV學(xué)院課程正式上線,玄鐵與PLCT實(shí)驗(yàn)室邀您創(chuàng)“芯”未來
PLCT實(shí)驗(yàn)室持續(xù)開放100名 RT-Thread 實(shí)習(xí)名額|甲辰計(jì)劃開源實(shí)習(xí)聯(lián)合培養(yǎng)
開源鴻蒙人才培養(yǎng)賦能課程共建正式啟動(dòng)
誠邁科技攜多款鴻志智能終端亮相2025開放原子開源生態(tài)大會(huì)
【開源獲獎(jiǎng)案例】AI智能交互新方案:基于T5L智能屏的AI DeepSeek大模型
全國(guó)首個(gè)985高校開源鴻蒙微專業(yè)落地!深開鴻與華中科技大學(xué)聯(lián)合培養(yǎng)智能信息系統(tǒng)人才
deepin社區(qū)助力高校開源人才培養(yǎng)
開放原子與北京高校探索開源人才培養(yǎng)新路徑
深開鴻與深信大聯(lián)合培養(yǎng)的首批開源鴻蒙工程師完成KCA認(rèn)證考試
【開源獲獎(jiǎng)案例】基于T5L智能屏的音樂播放與歌詞顯示方案
【開源獲獎(jiǎng)案例】基于T5L智能屏的零食機(jī)
【開源獲獎(jiǎng)案例】智能培養(yǎng)室
評(píng)論