[Sumber Terbuka]Bilik Latihan Pintar

——Dari Forum Pembangun DWIN

Dalam isu ini, kami memperkenalkan kepada anda kes sumber terbuka yang memenangi anugerah Forum Pembangun DWIN - bilik penanaman pintar.Jurutera melaksanakan skrin pintar T5L untuk mengawal pemanasan dan fungsi kawalan suhu kipas melalui protokol Modbus.Bekalan kuasa juga boleh dilaraskan untuk mensimulasikan fungsi pencahayaan.Sistem boleh berjalan secara automatik mengikut parameter yang ditetapkan pada skrin dan menyimpan rekod sejarah kesalahan.

1. Paparan Bahan UI

asvdfb (2)
asvdfb (1)

2. Reka bentuk UI

asvdfb (3)

1.C51 Reka Bentuk

Kod utama untuk memperoleh dan mengemas kini data seperti suhu, kelembapan dan ketinggian pada antara muka utama, dan menggunakan modbus rtu untuk mengawal modul kawalan suhu, motor, pengesanan penggera dan mesin hamba lain adalah seperti berikut.

Rujukan kod antara muka utama:

#include "main_win.h"

#include "modbus.h"

#include "sys_params.h"

#include "func_handler.h"

#include "uart2.h"

#termasuk

#termasuk

#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{

tarikh char[17];

u8 desc;

}AMARAN;

#define ALERT_TABLE_LEN 20

statik u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};

statik 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;

batal main_win_update()

{

}

batal 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);

}

batal main_win_process_alert()

{

u8 i;

untuk(i=0;i

{

if(GET_ALERT_BIT(old_alert_val, i))

teruskan;

jika(GET_ALERT_BIT(alert_val, i))

{

if(alert_num>=ALERT_TABLE_LEN)

angka_makluman = ALERT_TABLE_LEN-1;

alert_table[alert_num].desc = i+1;

sprintf(alert_table[alert_num].tarikh, "%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));

}

batal main_win_disp_alert()

{

u16 i;

u16 val;

u16 len = 0;

common_buf[0] = 0;

untuk(i=0;i

{

val = 0;

jika saya

{

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);

}

batal 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);

untuk(i=0;i

{

jika(i==0)

teruskan;

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);

}

batal main_win_click_handler(u16 btn_val)

{

indeks u8;

if(btn_val==0x0B)

{

main_win_disp_alert();

kembali;

}

indeks = btn_val-1;

btn_sta[indeks] = !btn_sta[indeks];

jika((indeks==3)||(indeks==7))

btn_sta[indeks] = 1;

modbus_write_bit(btn_addr[index], btn_sta[index]?0xFF00:0x0000);

btn_val = btn_sta[indeks];

sys_write_vp(MAIN_WIN_BTN_STA_START_VP+MAIN_WIN_BTN_STA_OFFSET*indeks, (u8*)&btn_val, 1);

jika(indeks==9)

is_main_win = 0;

else if((index==3)||(index==7))

{

while(sys_get_touch_sta());

modbus_write_bit(btn_addr[index], 0x0000);

}

}

batal 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 mengimbangi;

msg_len = msg_len;

jika(!is_main_win)

kembali;

if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_VAL_MAX_NUM*2))

{

offset = MODBUS_RESPOND_POS_DATA;

untuk(i=0;i

{

main_win_val = SYS_GET_U16(msg[offset], msg[offset+1]);

mengimbangi += 2;

}

main_win_update();

}lain jika((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))

{

offset = MODBUS_RESPOND_POS_DATA;

untuk(i=0;i

{

alert_val = msg[offset];

mengimbangi++;

}

main_win_process_alert();

}lain jika((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))

{

offset = MODBUS_RESPOND_POS_DATA;

untuk(i=0;i

{

temp_hum_val = SYS_GET_U16(msg[offset], msg[offset+1]);

mengimbangi += 2;

modbus_write_word(5+i, temp_hum_val);

}

main_win_update();

}lain jika((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))

{

offset = MODBUS_RESPOND_POS_DATA;

untuk(i=0;i

{

date_val = SYS_GET_U16(msg[offset], msg[offset+1]);

mengimbangi += 2;

}

main_win_disp_date();

}

}

batal 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;//Revert

}

batal main_win_handler()

{

bendera u8 statik = 0;

if(is_main_win)

{

jika(tempoh_baca_maklum==TEMPOH_BACA_JAGA)

{

amaran_tempoh_baca = 0;

modbus_read_bits(510, ALERT_BIT_MAX_NUM);

kembali;

}

jika(tarikh_kemas kini_tempoh==DATE_UPDATE_PERIOD)

{

tarikh_kemas kini_tempoh = 0;

modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);

kembali;

}

bendera = !bendera;

jika (bendera)

modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);

lain

main_win_read_temp_hum();

}

}

rujukan kod 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_bait

#define UART_BAUD 9600

#define MODBUS_RECV_TIMEOUT (u8)(35000.0f/UART_BAUD+2)

#define MODBUS_SEND_INTERVAL 150

#include UART_INCLUDE

bit statik ialah_modbus_recv_complete = 0;

modbus_recv_buff u8 statik[270];

statik u16 modbus_recv_len = 0;//Jumlah panjang bait diterima

statik u8 modbus_recv_timeout = 0;//Terima masa limpahan

statik tidak menentu u16 modbus_send_interval = 0;

paket MODBUS_PACKET;

batal modbus_init()

{

UART_INIT(UART_BAUD);

}

batal modbus_send_bait(u8 *bait,u16 len)

{

UART_SEND_BYTES(bait,len);

}

batal modbus_recv_bait(u8 bait)

{

if(is_modbus_recv_complete)

kembali;

jika(modbus_recv_len

modbus_recv_buff[modbus_recv_len++] = bait;

}

batal modbus_check_recv_timeout()

{

jika(modbus_recv_timeout)

{

modbus_recv_timeout--;

jika(modbus_recv_timeout==0)

{

is_modbus_recv_complete = 1;

}

}

}

u8 modbus_send_packet(u8 *packet)

{

u16 len;

u16 crc;

u8 func_code = paket[1];

while(modbus_send_interval);

if(func_code==MODBUS_FUNC_CODE_10)

{

((MODBUS_10_PACKET*)paket)->byte_num = ((MODBUS_10_PACKET*)paket)->word_num*2;

len = 9+((MODBUS_10_PACKET*)paket)->byte_num;

} else if(func_code==MODBUS_FUNC_CODE_0F)

{

len = ((MODBUS_0F_PACKET*)paket)->bit_num;

((MODBUS_0F_PACKET*)paket)->byte_num = len/8+(len%8?1:0);

len = 9+((MODBUS_0F_PACKET*)paket)->byte_num;

}lain

{

len = saiz(MODBUS_PACKET);

}

crc = crc16(paket,len-2);

paket[len-2] = (u8)(crc>>8);

paket[len-1] = (u8)crc;

modbus_send_bait(paket,len);

modbus_send_interval = MODBUS_SEND_INTERVAL;

kembali 0; // Berjaya

}

extern void modbus_msg_handler(u8 *msg,u16 msg_len);

batal modbus_handler()

{

u16 crc;

if(! is_modbus_recv_complete)

kembali;

//Semak nilai 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; // Kod fungsi

packet.start_addr = addr;//Alamat

packet.data_len = len;//Nilai ditulis

len = modbus_send_packet((u8*)&packet);

kembali len;

}


Masa siaran: Jan-12-2024