//---------------------------------------------------------------------------
// Проект 49. Расчёт стабилизатора напряжения
// Параметрический на стабилитроне и интегральный на LM317:
// балластный резистор, делитель, потери мощности.
//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
double BallastResistor(double Uin, double Uz, double Iload, double Iz)
{
    double totalCurrent = Iload + Iz;
    if (totalCurrent <= 0) return 0;
    return (Uin - Uz) / totalCurrent;
}
//---------------------------------------------------------------------------
double Lm317Output(double R1, double R2)
{
    if (R1 <= 0) return 0;
    return 1.25 * (1.0 + R2 / R1);
}
//---------------------------------------------------------------------------
double Lm317R2(double Uout, double R1)
{
    if (Uout < 1.25) return 0;
    return R1 * (Uout / 1.25 - 1.0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonZenerClick(TObject *Sender)
{
    double Uin, Uz, Iload, Iz;
    try {
        Uin = StrToFloat(EditUin->Text); Uz = StrToFloat(EditUz->Text);
        Iload = StrToFloat(EditIload->Text) / 1000; Iz = StrToFloat(EditIz->Text) / 1000;
    } catch (...) { MemoResult->Text = "Проверьте числа"; return; }
    if (Uin <= Uz) { MemoResult->Text = "Входное напряжение должно быть выше напряжения стабилизации"; return; }
    double R = BallastResistor(Uin, Uz, Iload, Iz);
    double Pr = (Uin - Uz) * (Iload + Iz);
    double Pz = Uz * Iz;
    double IzMax = (Uin - Uz) / R;
    double PzMax = Uz * IzMax;
    MemoResult->Lines->Clear();
    MemoResult->Lines->Add("Параметрический стабилизатор на стабилитроне");
    MemoResult->Lines->Add("");
    MemoResult->Lines->Add("Балластный резистор: " + FormatFloat("0.#", R) + " Ом");
    MemoResult->Lines->Add("   мощность на нём:  " + FormatFloat("0.###", Pr) + " Вт");
    MemoResult->Lines->Add("");
    MemoResult->Lines->Add("Стабилитрон в рабочем режиме: " + FormatFloat("0.###", Pz) + " Вт");
    MemoResult->Lines->Add("Без нагрузки (худший случай): " + FormatFloat("0.###", PzMax) + " Вт");
    MemoResult->Lines->Add("   ток через стабилитрон:     " + FormatFloat("0.#", IzMax * 1000) + " мА");
    MemoResult->Lines->Add("");
    MemoResult->Lines->Add("Стабилитрон выбирайте с запасом по мощности");
    MemoResult->Lines->Add("не меньше " + FormatFloat("0.##", PzMax * 1.5) + " Вт.");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonLm317Click(TObject *Sender)
{
    double Uin, Uout, Iload, R1;
    try {
        Uin = StrToFloat(EditUin317->Text); Uout = StrToFloat(EditUout->Text);
        Iload = StrToFloat(EditIout->Text) / 1000; R1 = StrToFloat(EditR1->Text);
    } catch (...) { MemoResult->Text = "Проверьте числа"; return; }
    if (Uout < 1.25) { MemoResult->Text = "LM317 не выдаёт напряжение ниже 1,25 В"; return; }
    if (Uin < Uout + 3.0) { MemoResult->Text = "Входное напряжение должно быть выше выходного минимум на 3 В"; return; }
    double R2 = Lm317R2(Uout, R1);
    double Uact = Lm317Output(R1, R2);
    double Pdis = (Uin - Uout) * Iload;
    MemoResult->Lines->Clear();
    MemoResult->Lines->Add("Стабилизатор на LM317");
    MemoResult->Lines->Add("");
    MemoResult->Lines->Add("R1 (на выводе ADJ): " + FormatFloat("0.#", R1) + " Ом");
    MemoResult->Lines->Add("R2 (расчётный):     " + FormatFloat("0.#", R2) + " Ом");
    MemoResult->Lines->Add("Реальное выходное:  " + FormatFloat("0.###", Uact) + " В");
    MemoResult->Lines->Add("");
    MemoResult->Lines->Add("Падение на микросхеме: " + FormatFloat("0.##", Uin - Uout) + " В");
    MemoResult->Lines->Add("Рассеиваемая мощность: " + FormatFloat("0.##", Pdis) + " Вт");
    if (Pdis > 1.0) MemoResult->Lines->Add("Нужен радиатор — посчитайте его в проекте 48.");
}
//---------------------------------------------------------------------------
