——Do Foro de desenvolvedores de DWIN
Neste número, presentámosvos o caso de código aberto galardoado do Foro de Desenvolvedores de DWIN: a sala de cultivo intelixente. Os enxeñeiros implementaron a pantalla intelixente T5L para controlar as funcións de calefacción e control da temperatura do ventilador a través do protocolo Modbus. A fonte de alimentación tamén se pode axustar para simular a función de iluminación. O sistema pode funcionar automaticamente segundo os parámetros configurados na pantalla e gardar rexistros do historial de fallos.
1. Visualización de materiais da IU
2. Deseño da interface de usuario
Deseño 1.C51
Os códigos principais para adquirir e actualizar datos como temperatura, humidade e altitude na interface principal e usar Modbus RTU para controlar módulos de control de temperatura, motores, detección de alarmas e outras máquinas escravas son os seguintes:
Referencia do código da interface principal:
#include "main_win.h"
#incluír "modbus.h"
#incluír "sys_params.h"
#incluír "func_handler.h"
#incluír "uart2.h"
#incluír
#incluír
#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)
estrutura typedef{
data do carácter[17];
u8 desc;
}ALERTA;
#define ALERT_TABLE_LONG 20
estático u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};
estático u8 btn_addr[NÚMERO_MÁXIMO_DE_BOTN_DAS_PRINCIPAIS] = {50, 51, 52, 69, 53, 54, 55, 70, 56, 57, 58, 59};
u16 valor_principal_de_vinha[VAL_PRINCIPAL_DE_VINHA_MAX_NUM];
u16 valor_humididade_temperatura[VAL_HUMIDIDADE_TEMP_MAX_NUM] = {0};
u16 data_val[MAIN_WIN_DATE_MAX_NUM] = {0};
u8 alert_val[ALERT_BYTE_NUM] = {0};
u8 val_de_alerta_antiga[ALERTA_BYTE_NUM] = {0};
ALERTA táboa_alertas[ALERT_TABLE_LONG];
u16 núm_alerta = 0;
bit é_principal_win = 0;
actualización_de_main_win() baleira
{
}
baleiro data_de_disposición_de_main_win()
{
só sub-8;
len = sprintf(buf_común, "%u:%u", (u16)val_data[3], (u16)val_data[4]);
buf_común[len+1] = 0;
sys_write_vp(MAIN_WIN_DATE_VP, common_buf, len/2+2);
}
baleiro alerta_de_proceso_de_viña_principal()
{
u8 i;
para (i=0;i
{
se(GET_ALERT_BIT(val_de_alerta_antigo, i))
continuar;
se(OBTER_ALERTA_BIT(alerta_val, i))
{
se (número_de_alerta>=LONGITUDE_DA_TABELA_DE_ALERTAS)
núm_alerta = ALERT_TABLE_LEN-1;
táboa_de_alertas[número_de_alertas].desc = i+1;
sprintf(táboa_de_alertas[número_de_alertas].data, "%u/%u/%u %u:%u",
data_val[0], data_val[1], data_val[2], data_val[3], data_val[4]
);
número_de_alerta++;
}
}
memcpy(val_de_alerta_antigo, val_de_alerta, tamaño_de(val_de_alerta));
}
baleiro alerta_de_disposición_de_main_win()
{
en16 e;
muro sub-16;
só u16 = 0;
buf_común[0] = 0;
para (i=0;i
{
valor = 0;
se (i
{
val = táboa_de_alertas.desc;
len += sprintf(buf_común+len, "%s\r\n", táboa_de_alertas.data);
}
sys_write_vp(ALERT_WIN_DESC_START_VP+i, (u8*)&val, 1);
}
buf_común[len+1] = 0;
sys_write_vp(ALERT_WIN_DATE_VP, common_buf, len/2+2);
}
baleiro main_win_init()
{
float fixo_val;
u8 i;
é_win_principal = 1;
val_principal_de_venta[5] = (u16)(val_humedad_temperatura[0]/10.0+0.5f);
val_principal_de_venta[6] = (u16)(val_humedad_temperatura[1]/10.0+0.5f);
para (i=0;i
{
se (i==0)
continuar;
sys_write_vp(MAIN_WIN_WIND_SPEED_VP+MAIN_WIN_VAL_OFFSET*i, (u8*)&main_win_val, 1);
}
valor_fixo = valor_principal_de_win[0]/ESCALA_VELOCIDADE_VENTO+VAL_FLOTANTE_FIXO;
sys_write_vp(MAIN_WIN_WIND_SPEED_VP, (u8*)&val_fixo, 2);
}
baleiro main_win_click_handler(u16 btn_val)
{
índice u8;
se (val_boto==0x0B)
{
alerta_de_disposición_de_vínculos_principais();
retorno;
}
índice = btn_val-1;
btn_sta[índice] = !btn_sta[índice];
se((índice==3)||(índice==7))
btn_sta[índice] = 1;
modbus_write_bit(btn_addr[índice], btn_sta[índice]?0xFF00:0x0000);
btn_val = btn_sta[índice];
sys_write_vp(MAIN_WIN_BTN_STA_START_VP+MAIN_WIN_BTN_STA_OFFSET*índice, (u8*)&btn_val, 1);
se (índice==9)
é_win_principal = 0;
se non, se ((índice==3)||(índice==7))
{
mentres(sys_get_touch_sta());
modbus_write_bit(btn_addr[índice], 0x0000);
}
}
baleiro controlador_de_mensaxes_de_main_win(u8 *mensaxe,u16 lonxitude_mensaxe)
{
u8 código_f = mensaxe[CODIGO_FUNCIÓN_POS_RESPOND_MODBUS];
u8 lonxitude_datos = mensaxe[LEN_DATOS_MODBUS_RESPOND_POS];
u8 i;
desprazamento u8;
msg_len = msg_len;
se(!é_gaña_principal)
retorno;
se ((código_f==CODIGO_FUNCIÓN_MODBUS_03)&&(len_datos==VAL_PRINCIPAL_DE_VINHA_MAX_NUM*2))
{
desprazamento = MODBUS_RESPOND_POS_DATA;
para (i=0;i
{
valor_principal_de_win = SYS_GET_U16(mensaxe[desprazamento], mensaxe[desprazamento+1]);
desprazamento += 2;
}
actualización_de_principal_win();
}senón se((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))
{
desprazamento = MODBUS_RESPOND_POS_DATA;
para (i=0;i
{
alert_val = msg[offset];
desprazamento++;
}
alerta_do_proceso_de_viña_principal();
}senón se((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))
{
desprazamento = MODBUS_RESPOND_POS_DATA;
para (i=0;i
{
valor_humididade_temp = SYS_GET_U16(mensaxe[desprazamento], mensaxe[desprazamento+1]);
desprazamento += 2;
modbus_write_word(5+i, temp_hum_val);
}
actualización_de_principal_win();
}senón se((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))
{
desprazamento = MODBUS_RESPOND_POS_DATA;
para (i=0;i
{
data_val = SYS_GET_U16(mensaxe[desprazamento], mensaxe[desprazamento+1]);
desprazamento += 2;
}
data_de_display_de_principal_win();
}
}
baleiro main_win_read_temp_hum()
{
u8 dirección_escrava_vella = dirección_ESCRAVO;
sys_params.user_config[5] = TEMP_HUM_SLAVE_ADDR;
modbus_read_words(0, TEMP_HUM_VAL_MAX_NUM);
sys_params.user_config[5] = dirección_escrava_antiga;//Reverter
}
baleiro controlador_de_viñas_principais()
{
indicador u8 estático = 0;
se(é_principal_gaña)
{
se (período_de_lectura_de_alerta==PERÍODO_DE_LECTURA_DE_ALERTA)
{
período_de_lectura_de_alerta = 0;
modbus_read_bits(510, ALERT_BIT_MAX_NUM);
retorno;
}
se (período_de_actualización_da_data==PERÍODO_DE_ACTUALIZACIÓN_DA_DATA)
{
período_de_actualización_da_data = 0;
modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);
retorno;
}
bandeira = !bandeira;
se (bandeira)
modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);
outra cousa
main_win_read_temp_hum();
}
}
referencia do código Modbus RTU:
#incluír "modbus.h"
#incluír "crc16.h"
#incluír "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
#incluír UART_INCLUDE
bit estático is_modbus_recv_complete = 0;
estático u8 modbus_recv_buff[270];
static u16 modbus_recv_len = 0;//Lonxitude total dos bytes aceptados
static u8 modbus_recv_timeout = 0;//Aceptar o tempo de desbordamento
estático volátil u16 modbus_send_interval = 0;
Paquete MODBUS_PACKET;
baleiro modbus_init()
{
UART_INICIO(UART_BAUD);
}
baleiro modbus_send_bytes(u8 *bytes,u16 lonxitude)
{
UART_SEND_BYTES(bytes,len);
}
baleiro modbus_recv_byte(u8 byte)
{
se (está_recibida_de_modbus_completa)
retorno;
se (longitude_recepcion_modbus
modbus_recv_buff[modbus_recv_len++] = byte;
}
tempo_de_espera_de_modbus_check_recv() baleiro
{
se (tempo_de_espera_recepción_modbus)
{
tempo_espera_recepción_modbus--;
se (tempo_de_espera_recepción_modbus==0)
{
is_modbus_recv_complete = 1;
}
}
}
u8 modbus_send_packet(u8 *paquete)
{
só sub-16;
CRC sub-16;
u8 código_función = paquete[1];
mentres(intervalo_envío_modbus);
se (código_función==CÓDIGO_FUNCIÓN_MODBUS_10)
{
((MODBUS_10_PACKET*)paquete)->número_de_bytes = ((MODBUS_10_PACKET*)paquete)->número_de_palabras*2;
len = 9+((MODBUS_10_PACKET*)paquete)->número_de_bytes;
}senón se(código_función==CODIGO_FUNCIÓN_MODBUS_0F)
{
len = ((MODBUS_0F_PACKET*)paquete)->número_de_bits;
((MODBUS_0F_PACKET*)paquete)->número_de_bytes = len/8+(len%8?1:0);
len = 9+((MODBUS_0F_PACKET*)paquete)->número_de_bytes;
}senón
{
lonxitude = tamaño de(PAQUETE_MODBUS);
}
crc = crc16(paquete,len-2);
paquete[len-2] = (u8)(crc>>8);
paquete[len-1] = (u8)crc;
modbus_send_bytes(paquete,len);
intervalo_envío_modbus = INTERVALO_ENVÍO_MODBUS;
devolver 0; //Éxito
}
extern void modbus_msg_handler(u8 *msg,u16 msg_len);
baleiro modbus_handler()
{
CRC sub-16;
se (!é_recepción_de_modbus_completa)
retorno;
//Comprobar o valor do CRC
crc = ((u16)buff_recepción_modbus[len_recepción_modbus-2]
se(crc16(buff_recepción_modbus,lenda_recepción_modbus-2)==crc)
{
manexador_msg_modbus(buff_recepción_modbus,lenda_recepción_modbus);
}
modbus_recv_len = 0;
is_modbus_recv_complete = 0;
}
código_f de envío_modbus_u8(código_f u8, enderezo_u16, lonxitude_u16)
{
paquete.dirección_escrava = ENDEREZO_ESCRAVO;
paquete.func_code = fcode;//Código da función
paquete.addr_inicial = addr;//Enderezo
paquete.len_datos = len;//Valor escrito
len = modbus_send_packet((u8*)&packet);
devolver lonxitude;
}
Data de publicación: 12 de xaneiro de 2024




