——El Forumo pri Programistoj de DWIN
En ĉi tiu numero, ni prezentas al vi la premiitan malfermfontan kazon de la Forumo por Programistoj DWIN - la inteligenta kultivadĉambro.Inĝenieroj efektivigis la inteligentan ekranon T5L por kontroli funkciojn de hejtado kaj ventumila temperaturkontrolo per la Modbus-protokolo.La nutrado ankaŭ povas esti ĝustigita por simuli la lumfunkcion.La sistemo povas aŭtomate funkcii laŭ la parametroj fiksitaj sur la ekrano kaj konservi mishistoriajn rekordojn.
1.UI Materiala Ekrano
2.UI-Dezajno
1.C51 Dezajno
La ĉefaj kodoj por akiri kaj ĝisdatigi datumojn kiel temperaturo, humideco kaj alteco sur la ĉefa interfaco, kaj uzi modbus rtu por kontroli temperaturkontrolajn modulojn, motorojn, alarm-detekton kaj aliajn sklavajn maŝinojn estas jenaj.
Referenco pri ĉefa interfaco:
#include "main_win.h"
#include "modbus.h"
#include "sys_params.h"
#include "func_handler.h"
#include "uart2.h"
#inkluzivi
#inkluzivi
#difini TEMP_HUM_SLAVE_ADDR 2
#difini TEMP_HUM_VAL_MAX_NUM 2
#difini ALERT_BIT_MAX_NUM 30
#difini ALERT_BYTE_NUM (ALERT_BIT_MAX_NUM/8+((ALERT_BIT_MAX_NUM%8)!=0))
#difini GET_ALERT_BIT(val, pos) ((val[pos/8]>>(pos%8))&0x01)
typedef struktur {
char dato[17];
u8 desc;
}ALERTO;
#define ALERT_TABLE_LEN 20
statika u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};
statika 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 dato_val[MAIN_WIN_DATE_MAX_NUM] = {0};
u8 alert_val[ALERT_BYTE_NUM] = {0};
u8 old_alert_val[ALERT_BYTE_NUM] = {0};
ALERT tabelo_alerta[ALERT_TABLE_LEN];
u16 alert_num = 0;
bito is_main_win = 0;
malplena ĉefa_gajno_ĝisdatigo ()
{
}
malplena ĉefa_gajno_disp_dato ()
{
u8 len;
len = sprintf(komuna_buf, "%u:%u", (u16)date_val[3], (u16)date_val[4]);
komuna_buf[len+1] = 0;
sys_write_vp(MAIN_WIN_DATE_VP, common_buf, len/2+2);
}
malplenigi ĉefa_gajno_procezo_alert()
{
u8 i;
por(i=0;i
{
if(GET_ALERT_BIT(malnova_alerta_val, i))
daŭrigi;
if(GET_ALERT_BIT(alerto_val, i))
{
if(alerta_num>=ALERT_TABLE_LEN)
alert_num = ALERT_TABLE_LEN-1;
atentiga_tabelo[alerto_num].desc = i+1;
sprintf(alerta_tablo[alerta_num].dato, "%u/%u/%u %u:%u",
dato_val[0], dato_val[1], dato_val[2], dato_val[3], dato_val[4]
);
alarm_num++;
}
}
memcpy(malnova_alerta_val, alert_val, sizeof(alerta_val));
}
void main_win_disp_alert ()
{
u16 i;
u16 val;
u16 len = 0;
komuna_buf[0] = 0;
por(i=0;i
{
val = 0;
se mi
{
val = alert_table.desc;
len += sprintf(komuna_buf+len, "%s\r\n", alert_table.date);
}
sys_write_vp(ALERT_WIN_DESC_START_VP+i, (u8*)&val, 1);
}
komuna_buf[len+1] = 0;
sys_write_vp(ALERT_WIN_DATE_VP, common_buf, len/2+2);
}
void main_win_init ()
{
flosi fiksita_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);
por(i=0;i
{
se (i==0)
daŭrigi;
sys_write_vp(MAIN_WIN_WIND_SPEED_VP+MAIN_WIN_VAL_OFFSET*i, (u8*)&main_win_val, 1);
}
fiksita_val = ĉefa_gajno_val[0]/VENTO_SPEED_SCALE+FLOAT_FIX_VAL;
sys_write_vp(MAIN_WIN_WIND_SPEED_VP, (u8*)&fixed_val, 2);
}
malplenigi main_win_click_handler (u16 btn_val)
{
u8 indekso;
se (btn_val==0x0B)
{
ĉefa_win_disp_alert();
reveni;
}
indekso = btn_val-1;
btn_sta[indekso] = !btn_sta[indekso];
se((indekso==3)||(indekso==7))
btn_sta[indekso] = 1;
modbus_write_bit(btn_addr[indekso], btn_sta[indekso]?0xFF00:0x0000);
btn_val = btn_sta[indekso];
sys_write_vp(MAIN_WIN_BTN_STA_START_VP+MAIN_WIN_BTN_STA_OFFSET*indekso, (u8*)&btn_val, 1);
se(indekso==9)
is_main_win = 0;
alie se((indekso==3)||(indekso==7))
{
dum(sys_get_touch_sta());
modbus_write_bit (btn_addr[indekso], 0x0000);
}
}
void main_win_msg_handler (u8 *msg,u16 msg_len)
{
u8 f_kodo = msg[MODBUS_RESPOND_POS_FUNC_CODE];
u8 data_len = msg[MODBUS_RESPOND_POS_DATA_LEN];
u8 i;
u8 ofseto;
msg_len = msg_len;
se(!estas_ĉefa_venko)
reveni;
if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_VAL_MAX_NUM*2))
{
ofseto = MODBUS_RESPOND_POS_DATA;
por(i=0;i
{
main_win_val = SYS_GET_U16(msg[offset], msg[offset+1]);
ofseto += 2;
}
ĉefa_gajno_ĝisdatigo();
}else if((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))
{
ofseto = MODBUS_RESPOND_POS_DATA;
por(i=0;i
{
alert_val = msg[offset];
ofseto++;
}
ĉefa_gajna_procezo_alerto();
}else if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))
{
ofseto = MODBUS_RESPOND_POS_DATA;
por(i=0;i
{
temp_hum_val = SYS_GET_U16(msg[offset], msg[offset+1]);
ofseto += 2;
modbus_skribi_vorton(5+i, temp_hum_val);
}
ĉefa_gajno_ĝisdatigo();
}else if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))
{
ofseto = MODBUS_RESPOND_POS_DATA;
por(i=0;i
{
dato_val = SYS_GET_U16(msg[offset], msg[offset+1]);
ofseto += 2;
}
ĉefa_gajno_disp_dato();
}
}
void main_win_read_temp_hum ()
{
u8 old_slave_addr = SLAVE_ADDR;
sys_params.user_config[5] = TEMP_HUM_SLAVE_ADDR;
modbus_legeblaj_vortoj (0, TEMP_HUM_VAL_MAX_NUM);
sys_params.user_config[5] = old_slave_addr;//Reverti
}
malplenigi ĉefa_gajna_traktilo ()
{
statika u8 flago = 0;
se (estas_ĉefa_venki)
{
if(alerta_lega_periodo==ALERT_READ_PERIODO)
{
atentiga_legita_periodo = 0;
modbus_read_bits (510, ALERT_BIT_MAX_NUM);
reveni;
}
if(dato_ĝisdatiga_periodo==DATO_ĝisdatigita_PERIODO)
{
dato_ĝisdatigo_periodo = 0;
modbus_read_words (180, MAIN_WIN_DATE_MAX_NUM);
reveni;
}
flago = !flago;
se (flago)
modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);
alie
ĉefa_gajno_legi_temp_hum ();
}
}
Referenco de kodo 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
#difini MODBUS_RECV_TIMEOUT (u8)(35000.0f/UART_BAUD+2)
#define MODBUS_SEND_INTERVAL 150
#include UART_INCLUDE
statika bito is_modbus_recv_complete = 0;
statika u8 modbus_recv_buff[270];
static u16 modbus_recv_len = 0;//Suma longo de bajtoj akceptitaj
static u8 modbus_recv_timeout = 0;//Akceptu superfluan tempon
statika volatila u16 modbus_send_interval = 0;
MODBUS_PACKET pako;
malplena modbus_init()
{
UART_INIT(UART_BAUD);
}
malplena modbus_send_bytes (u8 *bajtoj, u16 len)
{
UART_SEND_BYTES(bajtoj,len);
}
malplena modbus_recv_bajto (u8 bajto)
{
if(estas_modbus_recv_kompleta)
reveni;
if(modbus_recv_len
modbus_recv_buff[modbus_recv_len++] = bajto;
}
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 *pako)
{
u16 len;
u16 crc;
u8 func_code = pako[1];
dum(modbus_send_intervalo);
if(func_code==MODBUS_FUNC_CODE_10)
{
((MODBUS_10_PACKET*)pako)->bajto_num = ((MODBUS_10_PACKET*)pako)->vorto_num*2;
len = 9+((MODBUS_10_PACKET*)pako)->byte_num;
}else if(func_code==MODBUS_FUNC_CODE_0F)
{
len = ((MODBUS_0F_PACKET*)pako)->bit_num;
((MODBUS_0F_PACKET*)pako)->byte_num = len/8+(len%8?1:0);
len = 9+((MODBUS_0F_PACKET*)pako)->byte_num;
}alie
{
len = grandeco de (MODBUS_PACKET);
}
crc = crc16(pako,len-2);
pako[len-2] = (u8)(crc>>8);
pako[len-1] = (u8)crc;
modbus_send_bytes(pako,len);
modbus_send_interval = MODBUS_SEND_INTERVAL;
redonu 0;//Sukceso
}
extern void modbus_msg_handler(u8 *msg,u16 msg_len);
malplena modbus_handler ()
{
u16 crc;
se(!estas_modbus_recv_kompleta)
reveni;
//Kontrolu crc-valoron
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 = fkodo;//Funkcia kodo
packet.start_addr = addr;//Adreso
packet.data_len = len;//Valoro skribita
len = modbus_send_packet((u8*)&pako);
return len;
}
Afiŝtempo: Jan-12-2024