——Са ДВИН форума за програмере
У овом броју представљамо вам награђивани случај отвореног кода ДВИН Девелопер Форума – собу за паметну култивацију.Инжењери су имплементирали Т5Л паметни екран за контролу функција грејања и контроле температуре вентилатора преко Модбус протокола.Напајање се такође може подесити да симулира функцију осветљења.Систем може аутоматски да ради према параметрима постављеним на екрану и да сачува записе историје грешака.
1.Приказ материјала УИ
2.УИ дизајн
1.Ц51 Дизајн
Главни кодови за прикупљање и ажурирање података као што су температура, влажност и надморска висина на главном интерфејсу и коришћење модбус рту за контролу модула за контролу температуре, мотора, детекције аларма и других подређених машина су следећи
Референца кода главног интерфејса:
#инцлуде "маин_вин.х"
#инцлуде "модбус.х"
#инцлуде "сис_парамс.х"
#инцлуде "фунц_хандлер.х"
#инцлуде "уарт2.х"
#инцлуде
#инцлуде
#дефине ТЕМП_ХУМ_СЛАВЕ_АДДР 2
#дефине ТЕМП_ХУМ_ВАЛ_МАКС_НУМ 2
#дефине АЛЕРТ_БИТ_МАКС_НУМ 30
#дефине АЛЕРТ_БИТЕ_НУМ (АЛЕРТ_БИТ_МАКС_НУМ/8+((АЛЕРТ_БИТ_МАКС_НУМ%8)!=0))
#дефине ГЕТ_АЛЕРТ_БИТ(вал, поз) ((вал[пос/8]>>(пос%8))&0к01)
типедеф струцт{
цхар дате[17];
у8 десц;
}АЛЕРТ;
#дефине АЛЕРТ_ТАБЛЕ_ЛЕН 20
статички у8 бтн_ста[МАИН_ВИН_БТН_МАКС_НУМ] = {0};
статички у8 бтн_аддр[МАИН_ВИН_БТН_МАКС_НУМ] = {50, 51, 52, 69, 53, 54, 55, 70, 56, 57, 58, 59};
у16 маин_вин_вал[МАИН_ВИН_ВАЛ_МАКС_НУМ];
у16 темп_хум_вал[ТЕМП_ХУМ_ВАЛ_МАКС_НУМ] = {0};
у16 дате_вал[МАИН_ВИН_ДАТЕ_МАКС_НУМ] = {0};
у8 алерт_вал[АЛЕРТ_БИТЕ_НУМ] = {0};
у8 олд_алерт_вал[АЛЕРТ_БИТЕ_НУМ] = {0};
АЛЕРТ алерт_табле[АЛЕРТ_ТАБЛЕ_ЛЕН];
у16 алерт_нум = 0;
бит ис_маин_вин = 0;
воид маин_вин_упдате()
{
}
воид маин_вин_дисп_дате()
{
у8 лен;
лен = спринтф(цоммон_буф, "%у:%у", (у16)дате_вал[3], (у16)дате_вал[4]);
цоммон_буф[лен+1] = 0;
сис_врите_вп(МАИН_ВИН_ДАТЕ_ВП, цоммон_буф, лен/2+2);
}
воид маин_вин_процесс_алерт()
{
у8 и;
фор(и=0;и
{
иф(ГЕТ_АЛЕРТ_БИТ(олд_алерт_вал, и))
Настави;
иф(ГЕТ_АЛЕРТ_БИТ(алерт_вал, и))
{
иф(алерт_нум>=АЛЕРТ_ТАБЛЕ_ЛЕН)
алерт_нум = АЛЕРТ_ТАБЛЕ_ЛЕН-1;
алерт_табле[алерт_нум].десц = и+1;
спринтф(алерт_табле[алерт_нум].дате, "%у/%у/%у %у:%у",
дате_вал[0], дате_вал[1], дате_вал[2], дате_вал[3], дате_вал[4]
);
алерт_нум++;
}
}
мемцпи(олд_алерт_вал, алерт_вал, сизеоф(алерт_вал));
}
воид маин_вин_дисп_алерт()
{
у16 и;
у16 вал;
у16 лен = 0;
цоммон_буф[0] = 0;
фор(и=0;и
{
вал = 0;
ако (и
{
вал = алерт_табле.десц;
лен += спринтф(цоммон_буф+лен, "%с\р\н", алерт_табле.дате);
}
сис_врите_вп(АЛЕРТ_ВИН_ДЕСЦ_СТАРТ_ВП+и, (у8*)&вал, 1);
}
цоммон_буф[лен+1] = 0;
сис_врите_вп(АЛЕРТ_ВИН_ДАТЕ_ВП, цоммон_буф, лен/2+2);
}
воид маин_вин_инит()
{
флоат фикед_вал;
у8 и;
ис_маин_вин = 1;
маин_вин_вал[5] = (у16)(темп_хум_вал[0]/10.0+0.5ф);
маин_вин_вал[6] = (у16)(темп_хум_вал[1]/10.0+0.5ф);
фор(и=0;и
{
иф(и==0)
Настави;
сис_врите_вп(МАИН_ВИН_ВИНД_СПЕЕД_ВП+МАИН_ВИН_ВАЛ_ОФФСЕТ*и, (у8*)&маин_вин_вал, 1);
}
фикед_вал = маин_вин_вал[0]/ВИНД_СПЕЕД_СЦАЛЕ+ФЛОАТ_ФИКС_ВАЛ;
сис_врите_вп(МАИН_ВИН_ВИНД_СПЕЕД_ВП, (у8*)&фикед_вал, 2);
}
воид маин_вин_цлицк_хандлер(у16 бтн_вал)
{
у8 индекс;
иф(бтн_вал==0к0Б)
{
маин_вин_дисп_алерт();
повратак;
}
индекс = бтн_вал-1;
бтн_ста[индекс] = !бтн_ста[индекс];
иф((индекс==3)||(индекс==7))
бтн_ста[индекс] = 1;
модбус_врите_бит(бтн_аддр[индек], бтн_ста[индек]?0кФФ00:0к0000);
бтн_вал = бтн_ста[индекс];
сис_врите_вп(МАИН_ВИН_БТН_СТА_СТАРТ_ВП+МАИН_ВИН_БТН_СТА_ОФФСЕТ*индек, (у8*)&бтн_вал, 1);
иф(индекс==9)
ис_маин_вин = 0;
иначе иф((индек==3)||(индек==7))
{
вхиле(сис_гет_тоуцх_ста());
модбус_врите_бит(бтн_аддр[индекс], 0к0000);
}
}
воид маин_вин_мсг_хандлер(у8 *мсг,у16 мсг_лен)
{
у8 ф_цоде = мсг[МОДБУС_РЕСПОНД_ПОС_ФУНЦ_ЦОДЕ];
у8 дата_лен = мсг[МОДБУС_РЕСПОНД_ПОС_ДАТА_ЛЕН];
у8 и;
у8 оффсет;
мсг_лен = мсг_лен;
иф(!ис_маин_вин)
повратак;
иф((ф_цоде==МОДБУС_ФУНЦ_ЦОДЕ_03)&&(дата_лен==МАИН_ВИН_ВАЛ_МАКС_НУМ*2))
{
оффсет = МОДБУС_РЕСПОНД_ПОС_ДАТА;
фор(и=0;и
{
маин_вин_вал = СИС_ГЕТ_У16(мсг[оффсет], мсг[оффсет+1]);
оффсет += 2;
}
маин_вин_упдате();
}елсе иф((ф_цоде==МОДБУС_ФУНЦ_ЦОДЕ_01)&&(дата_лен==АЛЕРТ_БИТЕ_НУМ))
{
оффсет = МОДБУС_РЕСПОНД_ПОС_ДАТА;
фор(и=0;и
{
алерт_вал = мсг[оффсет];
оффсет++;
}
маин_вин_процесс_алерт();
}елсе иф((ф_цоде==МОДБУС_ФУНЦ_ЦОДЕ_03)&&(дата_лен==ТЕМП_ХУМ_ВАЛ_МАКС_НУМ*2))
{
оффсет = МОДБУС_РЕСПОНД_ПОС_ДАТА;
фор(и=0;и
{
темп_хум_вал = СИС_ГЕТ_У16(мсг[оффсет], мсг[оффсет+1]);
оффсет += 2;
модбус_врите_ворд(5+и, темп_хум_вал);
}
маин_вин_упдате();
}елсе иф((ф_цоде==МОДБУС_ФУНЦ_ЦОДЕ_03)&&(дата_лен==МАИН_ВИН_ДАТЕ_МАКС_НУМ*2))
{
оффсет = МОДБУС_РЕСПОНД_ПОС_ДАТА;
фор(и=0;и
{
дате_вал = СИС_ГЕТ_У16(мсг[оффсет], мсг[оффсет+1]);
оффсет += 2;
}
маин_вин_дисп_дате();
}
}
воид маин_вин_реад_темп_хум()
{
у8 олд_славе_аддр = СЛАВЕ_АДДР;
сис_парамс.усер_цонфиг[5] = ТЕМП_ХУМ_СЛАВЕ_АДДР;
модбус_реад_вордс(0, ТЕМП_ХУМ_ВАЛ_МАКС_НУМ);
сис_парамс.усер_цонфиг[5] = олд_славе_аддр;//Врати
}
воид маин_вин_хандлер()
{
статичка у8 застава = 0;
иф(ис_маин_вин)
{
иф(алерт_реад_период==АЛЕРТ_РЕАД_ПЕРИОД)
{
алерт_реад_период = 0;
модбус_реад_битс(510, АЛЕРТ_БИТ_МАКС_НУМ);
повратак;
}
иф(дате_упдате_период==ДАТЕ_УПДАТЕ_ПЕРИОД)
{
дате_упдате_период = 0;
модбус_реад_вордс(180, МАИН_ВИН_ДАТЕ_МАКС_НУМ);
повратак;
}
флаг = !флаг;
ако (застава)
модбус_реад_вордс(0, МАИН_ВИН_ВАЛ_МАКС_НУМ);
друго
маин_вин_реад_темп_хум();
}
}
Модбус рту код референца:
#инцлуде "модбус.х"
#инцлуде "црц16.х"
#инцлуде "сис_парамс.х"
#дефине УАРТ_ИНЦЛУДЕ "уарт2.х"
#дефине УАРТ_ИНИТ уарт2_инит
#дефине УАРТ_СЕНД_БИТЕС уарт2_сенд_битес
#дефине УАРТ_БАУД 9600
#дефине МОДБУС_РЕЦВ_ТИМЕОУТ (у8)(35000.0ф/УАРТ_БАУД+2)
#дефине МОДБУС_СЕНД_ИНТЕРВАЛ 150
#инцлуде УАРТ_ИНЦЛУДЕ
статички бит ис_модбус_рецв_цомплете = 0;
статички у8 модбус_рецв_буфф[270];
статиц у16 модбус_рецв_лен = 0;//Прихваћена укупна дужина бајтова
статиц у8 модбус_рецв_тимеоут = 0;//Прихвати време преливања
статиц волатиле у16 модбус_сенд_интервал = 0;
МОДБУС_ПАЦКЕТ пакет;
воид модбус_инит()
{
УАРТ_ИНИТ(УАРТ_БАУД);
}
воид модбус_сенд_битес(у8 *бајтова,у16 лен)
{
УАРТ_СЕНД_БИТЕС(бајтови,лен);
}
воид модбус_рецв_бите(у8 бајт)
{
иф(ис_модбус_рецв_цомплете)
повратак;
иф(модбус_рецв_лен
модбус_рецв_буфф[модбус_рецв_лен++] = бајт;
}
воид модбус_цхецк_рецв_тимеоут()
{
иф(модбус_рецв_тимеоут)
{
модбус_рецв_тимеоут--;
иф(модбус_рецв_тимеоут==0)
{
ис_модбус_рецв_цомплете = 1;
}
}
}
у8 модбус_сенд_пацкет(у8 *пацкет)
{
у16 лен;
у16 црц;
у8 фунц_цоде = пакет[1];
вхиле(модбус_сенд_интервал);
иф(фунц_цоде==МОДБУС_ФУНЦ_ЦОДЕ_10)
{
((МОДБУС_10_ПАЦКЕТ*)пацкет)->бите_нум = ((МОДБУС_10_ПАЦКЕТ*)пацкет)->ворд_нум*2;
лен = 9+((МОДБУС_10_ПАЦКЕТ*)пацкет)->бите_нум;
}елсе иф(фунц_цоде==МОДБУС_ФУНЦ_ЦОДЕ_0Ф)
{
лен = ((МОДБУС_0Ф_ПАЦКЕТ*)пакет)->бит_нум;
((МОДБУС_0Ф_ПАЦКЕТ*)пацкет)->бите_нум = лен/8+(лен%8?1:0);
лен = 9+((МОДБУС_0Ф_ПАЦКЕТ*)пацкет)->бите_нум;
}друго
{
лен = сизеоф(МОДБУС_ПАЦКЕТ);
}
црц = црц16(пакет,лен-2);
пакет[лен-2] = (у8)(црц>>8);
пацкет[лен-1] = (у8)црц;
модбус_сенд_битес(пацкет,лен);
модбус_сенд_интервал = МОДБУС_СЕНД_ИНТЕРВАЛ;
ретурн 0;//Успех
}
екстерн воид модбус_мсг_хандлер(у8 *мсг,у16 мсг_лен);
воид модбус_хандлер()
{
у16 црц;
иф(!ис_модбус_рецв_цомплете)
повратак;
//Провери црц вредност
црц = ((у16)модбус_рецв_буфф[модбус_рецв_лен-2]<<8)+модбус_рецв_буфф[модбус_рецв_лен-1];
иф(црц16(модбус_рецв_буфф,модбус_рецв_лен-2)==црц)
{
модбус_мсг_хандлер(модбус_рецв_буфф,модбус_рецв_лен);
}
модбус_рецв_лен = 0;
ис_модбус_рецв_цомплете = 0;
}
у8 модбус_сенд_фцоде(у8 фцоде, у16 аддр, у16 лен)
{
пацкет.славе_аддр = СЛАВЕ_АДДР;
пацкет.фунц_цоде = фцоде;//Код функције
пацкет.старт_аддр = аддр;//Адреса
пацкет.дата_лен = лен;//Написана вредност
лен = модбус_сенд_пацкет((у8*)&пацкет);
ретурн лен;
}
Време поста: Јан-12-2024