[Ανοικτή πηγή]Ευφυής Αίθουσα Εκπαίδευσης

——Από το Φόρουμ προγραμματιστών DWIN

Σε αυτό το τεύχος, σας παρουσιάζουμε τη βραβευμένη υπόθεση ανοιχτού κώδικα του Φόρουμ προγραμματιστών DWIN - την αίθουσα έξυπνης καλλιέργειας.Οι μηχανικοί εφάρμοσαν την έξυπνη οθόνη T5L για τον έλεγχο των λειτουργιών θέρμανσης και ελέγχου θερμοκρασίας ανεμιστήρα μέσω του πρωτοκόλλου Modbus.Το τροφοδοτικό μπορεί επίσης να ρυθμιστεί για την προσομοίωση της λειτουργίας φωτισμού.Το σύστημα μπορεί να λειτουργήσει αυτόματα σύμφωνα με τις παραμέτρους που έχουν οριστεί στην οθόνη και να αποθηκεύσει τις εγγραφές του ιστορικού σφαλμάτων.

1.Οθόνη Υλικού UI

asvdfb (2)
asvdfb (1)

2.UI Design

asvdfb (3)

1.C51 Σχεδίαση

Οι κύριοι κωδικοί για την απόκτηση και την ενημέρωση δεδομένων όπως η θερμοκρασία, η υγρασία και το υψόμετρο στην κύρια διεπαφή και η χρήση του modbus rtu για τον έλεγχο των μονάδων ελέγχου θερμοκρασίας, των κινητήρων, της ανίχνευσης συναγερμού και άλλων βοηθητικών μηχανών είναι οι εξής

Αναφορά κώδικα κύριας διεπαφής:

#include "main_win.h"

#include "modbus.h"

#include "sys_params.h"

#include "func_handler.h"

#include "uart2.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 ημερομηνία[17];

u8 περιγραφ.

}ΣΥΝΑΓΕΡΜΟΣ;

#define ALERT_TABLE_LEN 20

στατικό u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};

στατικό 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;

για(i=0;i

{

if(GET_ALERT_BIT(old_alert_val, i))

να συνεχίσει;

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;

για(i=0;i

{

val = 0;

αν εγώ

{

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

για(i=0;i

{

αν(i==0)

να συνεχίσει;

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;

if(btn_val==0x0B)

{

main_win_disp_alert();

ΕΠΙΣΤΡΟΦΗ;

}

δείκτης = btn_val-1;

btn_sta[index] = !btn_sta[index];

if((ευρετήριο==3)||(ευρετήριο==7))

btn_sta[ευρετήριο] = 1;

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

btn_val = btn_sta[ευρετήριο];

sys_write_vp(MAIN_WIN_BTN_STA_START_VP+MAIN_WIN_BTN_STA_OFFSET*ευρετήριο, (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[ευρετήριο], 0x0000);

}

}

void main_win_msg_handler(u8 *msg,u16msg_len)

{

u8 f_code = msg[MODBUS_RESPOND_POS_FUNC_CODE];

u8 data_len = msg[MODBUS_RESPOND_POS_DATA_LEN];

u8 i;

μετατόπιση u8?

msg_len = msg_len;

if(!is_main_win)

ΕΠΙΣΤΡΟΦΗ;

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

{

μετατόπιση = MODBUS_RESPOND_POS_DATA;

για(i=0;i

{

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

μετατόπιση += 2;

}

main_win_update();

}άλλο εάν((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))

{

μετατόπιση = MODBUS_RESPOND_POS_DATA;

για(i=0;i

{

alert_val = msg[offset];

offset++;

}

main_win_process_alert();

}άλλο εάν((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))

{

μετατόπιση = MODBUS_RESPOND_POS_DATA;

για(i=0;i

{

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

μετατόπιση += 2;

modbus_write_word(5+i, temp_hum_val);

}

main_win_update();

}άλλο εάν((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))

{

μετατόπιση = MODBUS_RESPOND_POS_DATA;

για(i=0;i

{

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

μετατόπιση += 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;//Revert

}

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

ΕΠΙΣΤΡΟΦΗ;

}

if(date_update_period==DATE_UPDATE_PERIOD)

{

date_update_period = 0;

modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);

ΕΠΙΣΤΡΟΦΗ;

}

flag = !σημαία;

if (σημαία)

modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);

αλλού

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_INCLUDE

στατικό bit is_modbus_recv_complete = 0;

static u8 modbus_recv_buff[270];

static u16 modbus_recv_len = 0;//Συνολικό μήκος byte αποδεκτό

static u8 modbus_recv_timeout = 0;//Αποδοχή χρόνου υπερχείλισης

static volatile u16 modbus_send_interval = 0;

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

ΕΠΙΣΤΡΟΦΗ;

if(modbus_recv_len

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 = πακέτο[1];

while(modbus_send_interval);

if(func_code==MODBUS_FUNC_CODE_10)

{

((MODBUS_10_PACKET*)πακέτο)->αριθμός_byte = ((MODBUS_10_PACKET*)πακέτο)->λέξη_αριθμός*2;

len = 9+((MODBUS_10_PACKET*)πακέτο)->byte_num;

}άλλο εάν(func_code==MODBUS_FUNC_CODE_0F)

{

len = ((MODBUS_0F_PACKET*)πακέτο)->bit_num;

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

len = 9+((MODBUS_0F_PACKET*)πακέτο)->byte_num;

}αλλού

{

len = sizeof(MODBUS_PACKET);

}

crc = crc16 (πακέτο,len-2);

πακέτο[len-2] = (u8)(crc>>8);

πακέτο[len-1] = (u8)crc;

modbus_send_bytes (packet,len);

modbus_send_interval = MODBUS_SEND_INTERVAL;

επιστροφή 0;//Επιτυχία

}

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

void modbus_handler()

{

u16 crc;

if(!is_modbus_recv_complete)

ΕΠΙΣΤΡΟΦΗ;

//Έλεγχος τιμής 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 = adr;//Διεύθυνση

packet.data_len = len;//Η τιμή έχει γραφτεί

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

επιστροφή len?

}


Ώρα δημοσίευσης: Ιαν-12-2024