Compare commits
No commits in common. "master" and "main" have entirely different histories.
116
README.md
116
README.md
@ -1,115 +1,3 @@
|
|||||||
# Преобразователь 3.3В → 24В для входа TX01
|
# Quartus
|
||||||
|
|
||||||
## Назначение
|
Мигаем светодиодом
|
||||||
|
|
||||||
Преобразователь уровня сигнала с GPIO микроконтроллера 3.3В (STM32F407) на дискретный вход 24В (TX01) с инверсией логики. Подходит для подключения ПЛИС/МК к промышленным входам 24В. [web:10]
|
|
||||||
|
|
||||||
## Схема
|
|
||||||
|
|
||||||
```text
|
|
||||||
+24V (внешний источник)
|
|
||||||
GPIO pin_10 │
|
|
||||||
│ ┌┴┐
|
|
||||||
│ │ │ R3 = 4.7kΩ
|
|
||||||
│ └┬┘
|
|
||||||
│ │
|
|
||||||
│ ├──────────► TX01 (вход 24V)
|
|
||||||
│ │
|
|
||||||
└─[ 10kΩ ]─┬[B] │
|
|
||||||
│ │
|
|
||||||
┌┴┐ ┌──┴──┐
|
|
||||||
R2 │ │ │ C │
|
|
||||||
100kΩ │ │ │ NPN │ Q1: BC547B / 2N2222A / 2N3904
|
|
||||||
└┬┘ │ Q1 │
|
|
||||||
│ │ E │
|
|
||||||
GND └──┬──┘
|
|
||||||
│ │
|
|
||||||
─┴─ GND
|
|
||||||
GND │
|
|
||||||
│
|
|
||||||
GND ─────────────┴──────────── GND (общий)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Принцип работы
|
|
||||||
|
|
||||||
R1 (10kΩ) и R2 (100kΩ) образуют резистивный делитель напряжения на базе транзистора. [web:8]
|
|
||||||
|
|
||||||
- При GPIO = 3.3В на базе формируется около 3.0В (до открытия перехода база‑эмиттер). [web:8]
|
|
||||||
- При \(V_{BE} \approx 0.7В\) транзистор открывается и входит в насыщение, коллектор притягивается к GND. [web:8]
|
|
||||||
- Избыток напряжения рассеивается на делителе R1–R2. [web:8]
|
|
||||||
|
|
||||||
Выход TX01 подтянут к +24В через R3 (4.7kΩ):
|
|
||||||
|
|
||||||
- Когда транзистор закрыт, TX01 ≈ 24В (логическая 1 для входа 24В). [web:8]
|
|
||||||
- Когда транзистор открыт, TX01 ≈ 0.2В (насыщение, логический 0). [web:8]
|
|
||||||
|
|
||||||
## Таблица состояний
|
|
||||||
|
|
||||||
| GPIO PA5 | Транзистор | TX01 | Логика TX01 |
|
|
||||||
|----------|------------|--------|-------------|
|
|
||||||
| 0В | Закрыт | ~24В | HIGH |
|
|
||||||
| 3.3В | Открыт | ~0.2В | LOW |
|
|
||||||
|
|
||||||
Инверсия логики:
|
|
||||||
|
|
||||||
- LOW на GPIO → HIGH на TX01
|
|
||||||
- HIGH на GPIO → LOW на TX01
|
|
||||||
|
|
||||||
## Расчеты
|
|
||||||
|
|
||||||
Ток базы при GPIO = 3.3В:
|
|
||||||
|
|
||||||
\[
|
|
||||||
I_b = \frac{V_{in} - V_{BE}}{R1 + R2}
|
|
||||||
\]
|
|
||||||
|
|
||||||
\[
|
|
||||||
I_b = \frac{3.3V - 0.7V}{110k\Omega} \approx 24\ \mu A
|
|
||||||
\]
|
|
||||||
|
|
||||||
Ток коллектора (при подтяжке 24В через 4.7kΩ):
|
|
||||||
|
|
||||||
\[
|
|
||||||
I_c = \frac{24V}{4.7k\Omega} \approx 5.1\ mA
|
|
||||||
\]
|
|
||||||
|
|
||||||
Требуемый коэффициент усиления:
|
|
||||||
|
|
||||||
\[
|
|
||||||
\beta = \frac{I_c}{I_b} \approx \frac{5.1mA}{24\mu A} \approx 212
|
|
||||||
\]
|
|
||||||
|
|
||||||
Подходящие транзисторы (по \(h_{FE}\) в активном режиме, с запасом для насыщения): [web:8][web:9]
|
|
||||||
|
|
||||||
- BC547B: \(hFE \approx 200–450\) [web:8]
|
|
||||||
- 2N2222A: \(hFE \approx 100–300\) [web:9]
|
|
||||||
- 2N3904: \(hFE \approx 100–300\) [web:9]
|
|
||||||
|
|
||||||
## Назначение элементов
|
|
||||||
|
|
||||||
- R1 (10kΩ)
|
|
||||||
- Ограничивает ток базы.
|
|
||||||
- Формирует верхнее плечо делителя напряжения.
|
|
||||||
|
|
||||||
- R2 (100kΩ)
|
|
||||||
- Обеспечивает разряд базы при выключении.
|
|
||||||
- Не дает базе и GPIO «плавать».
|
|
||||||
- Ускоряет выключение транзистора.
|
|
||||||
- Формирует нижнее плечо делителя.
|
|
||||||
|
|
||||||
- R3 (4.7kΩ)
|
|
||||||
- Pull‑up к +24В для входа TX01.
|
|
||||||
- Ограничивает ток коллектора транзистора.
|
|
||||||
- Формирует уровень HIGH на входе 24В.
|
|
||||||
|
|
||||||
- Q1 (NPN: BC547B / 2N2222A / 2N3904)
|
|
||||||
- Работает как ключ в насыщении. [web:8][web:9]
|
|
||||||
- Коммутирует вход TX01 на землю.
|
|
||||||
- Обеспечивает развязку 3.3В GPIO и 24В линии.
|
|
||||||
|
|
||||||
## Особенности применения
|
|
||||||
|
|
||||||
- Требуется общий GND между STM32/ПЛИС и источником 24В. [web:10]
|
|
||||||
- Логика инверсная, это нужно учесть в прошивке. [web:10]
|
|
||||||
- Ток через вход TX01 ≈ 5 mА при 24В, что подходит для большинства промышленных дискретных входов. [web:8]
|
|
||||||
- Схема подходит для частот от единиц герц до десятков килогерц (ограничения по R1/R2 и паразитным емкостям). [web:8]
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
@startuml
|
|
||||||
start
|
|
||||||
|
|
||||||
:posedge clk;
|
|
||||||
|
|
||||||
'--- Step timer ---
|
|
||||||
if (step_cnt >= (freq_idx == 1 ? STEP_2SEC_MAX : STEP_4SEC_MAX)) then (yes)
|
|
||||||
:step_cnt := 0;
|
|
||||||
if (freq_idx == 5) then (yes)
|
|
||||||
:freq_idx := 0;
|
|
||||||
else (no)
|
|
||||||
:freq_idx := freq_idx + 1;
|
|
||||||
endif
|
|
||||||
else (no)
|
|
||||||
:step_cnt := step_cnt + 1;
|
|
||||||
endif
|
|
||||||
|
|
||||||
'--- Recalculate half-period ---
|
|
||||||
:max_count := calc_max_count(freq_idx);
|
|
||||||
|
|
||||||
'--- Blink generation for led ---
|
|
||||||
if (max_count == 0) then (0 Hz)
|
|
||||||
:blink_cnt := 0;
|
|
||||||
note right
|
|
||||||
led_base сохраняет предыдущее
|
|
||||||
значение (нет мигания)
|
|
||||||
end note
|
|
||||||
else (f > 0)
|
|
||||||
if (blink_cnt >= max_count) then (toggle)
|
|
||||||
:blink_cnt := 0;
|
|
||||||
:led_base := ~led_base;
|
|
||||||
else (count)
|
|
||||||
:blink_cnt := blink_cnt + 1;
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
'--- 1 Hz generation for pin ---
|
|
||||||
if (pin_cnt >= PIN_1HZ_HALF_MAX) then (toggle)
|
|
||||||
:pin_cnt := 0;
|
|
||||||
:pin_base := ~pin_base;
|
|
||||||
else (count)
|
|
||||||
:pin_cnt := pin_cnt + 1;
|
|
||||||
endif
|
|
||||||
|
|
||||||
'--- Outputs (combinational) ---
|
|
||||||
:led = ~led_base;
|
|
||||||
:pin = pin_base;
|
|
||||||
:pin_10 = led;
|
|
||||||
|
|
||||||
stop
|
|
||||||
@enduml
|
|
||||||
BIN
UML/activity.png
BIN
UML/activity.png
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB |
@ -1,66 +0,0 @@
|
|||||||
@startuml
|
|
||||||
[*] --> F0 : reset/power-up
|
|
||||||
|
|
||||||
state "Blink frequency\nstates" as BlinkFreq {
|
|
||||||
state F0
|
|
||||||
state F10
|
|
||||||
state F20
|
|
||||||
state F30
|
|
||||||
state F40
|
|
||||||
state F50
|
|
||||||
}
|
|
||||||
|
|
||||||
' --- Notes ---
|
|
||||||
|
|
||||||
note right of F0
|
|
||||||
freq_idx = 0
|
|
||||||
f = 0 Hz (LED заморожен)
|
|
||||||
step_cnt считает до STEP_4SEC_MAX
|
|
||||||
end note
|
|
||||||
|
|
||||||
note right of F10
|
|
||||||
freq_idx = 1
|
|
||||||
f = 10 Hz
|
|
||||||
max_count = F_CLK/(2*10)-1
|
|
||||||
step_cnt считает до STEP_2SEC_MAX
|
|
||||||
end note
|
|
||||||
|
|
||||||
note right of F20
|
|
||||||
freq_idx = 2
|
|
||||||
f = 20 Hz
|
|
||||||
max_count = F_CLK/(2*20)-1
|
|
||||||
step_cnt считает до STEP_4SEC_MAX
|
|
||||||
end note
|
|
||||||
|
|
||||||
note right of F30
|
|
||||||
freq_idx = 3
|
|
||||||
f = 30 Hz
|
|
||||||
max_count = F_CLK/(2*30)-1
|
|
||||||
step_cnt считает до STEP_4SEC_MAX
|
|
||||||
end note
|
|
||||||
|
|
||||||
note right of F40
|
|
||||||
freq_idx = 4
|
|
||||||
f = 40 Hz
|
|
||||||
max_count = F_CLK/(2*40)-1
|
|
||||||
step_cnt считает до STEP_4SEC_MAX
|
|
||||||
end note
|
|
||||||
|
|
||||||
note right of F50
|
|
||||||
freq_idx = 5
|
|
||||||
f = 50 Hz
|
|
||||||
max_count = F_CLK/(2*50)-1
|
|
||||||
step_cnt считает до STEP_4SEC_MAX
|
|
||||||
end note
|
|
||||||
|
|
||||||
' --- Transitions ---
|
|
||||||
|
|
||||||
F0 --> F10 : step_cnt >= STEP_4SEC_MAX
|
|
||||||
F10 --> F20 : step_cnt >= STEP_2SEC_MAX
|
|
||||||
F20 --> F30 : step_cnt >= STEP_4SEC_MAX
|
|
||||||
F30 --> F40 : step_cnt >= STEP_4SEC_MAX
|
|
||||||
F40 --> F50 : step_cnt >= STEP_4SEC_MAX
|
|
||||||
F50 --> F0 : step_cnt >= STEP_4SEC_MAX
|
|
||||||
|
|
||||||
F0 --> [*] : external reset
|
|
||||||
@enduml
|
|
||||||
BIN
UML/state.png
BIN
UML/state.png
Binary file not shown.
|
Before Width: | Height: | Size: 43 KiB |
153
blink.v
153
blink.v
@ -1,122 +1,55 @@
|
|||||||
module blink #(
|
module blink #(
|
||||||
// Input clock frequency in Hz
|
// Выбор частоты мигания (F_BLINK), Гц:
|
||||||
parameter integer F_CLK = 50_000_000 // 50 MHz
|
// 1 -> 1
|
||||||
|
// 2.5 -> 25 (см. ниже, делим на 10)
|
||||||
|
// 5 -> 5
|
||||||
|
// 10 -> 10
|
||||||
|
parameter integer MODE = 4 // по умолчанию 1 Гц
|
||||||
)(
|
)(
|
||||||
input wire clk,
|
input wire clk, // 50 MHz
|
||||||
output wire led,
|
output reg led,
|
||||||
output wire pin,
|
output reg pin,
|
||||||
output wire pin_10
|
output reg pin_10
|
||||||
);
|
);
|
||||||
|
|
||||||
//---------------------------------------------------------
|
localparam integer F_CLK = 50_000_000;
|
||||||
// Step duration:
|
|
||||||
// - for 0.5 Hz : 2 s
|
|
||||||
// - for others : 4 s
|
|
||||||
//---------------------------------------------------------
|
|
||||||
localparam integer STEP_2SEC_MAX = (F_CLK * 2) - 1;
|
|
||||||
localparam integer STEP_4SEC_MAX = (F_CLK * 4) - 1;
|
|
||||||
|
|
||||||
// Step timer counter
|
// Предрасчитанные MAX_COUNT для половины периода:
|
||||||
reg [31:0] step_cnt = 32'd0;
|
//
|
||||||
|
// 1 Гц: T=1 c → T/2=0.5 c → 25_000_000
|
||||||
|
// 2.5 Гц: T=0.4 c → T/2=0.2 c → 10_000_000
|
||||||
|
// 5 Гц: T=0.2 c → T/2=0.1 c → 5_000_000
|
||||||
|
// 10 Гц: T=0.1 c → T/2=0.05 c → 2_500_000
|
||||||
|
|
||||||
// Frequency index: 0..5 → 0, 10, 20, 30, 40, 50 Hz
|
localparam integer MAX_1HZ = 25_000_000 - 1;
|
||||||
reg [2:0] freq_idx = 3'd0;
|
localparam integer MAX_2_5HZ = 10_000_000 - 1;
|
||||||
|
localparam integer MAX_5HZ = 5_000_000 - 1;
|
||||||
|
localparam integer MAX_10HZ = 2_500_000 - 1;
|
||||||
|
|
||||||
// Half-period counter and current half-period length in clock cycles
|
// Выбор MAX_COUNT по MODE
|
||||||
reg [31:0] blink_cnt = 32'd0;
|
// MODE:
|
||||||
reg [31:0] max_count = 32'd0;
|
// 1 -> 1 Гц
|
||||||
|
// 2 -> 2.5 Гц
|
||||||
|
// 3 -> 5 Гц
|
||||||
|
// 4 -> 10 Гц
|
||||||
|
localparam integer MAX_COUNT =
|
||||||
|
(MODE == 1) ? MAX_1HZ :
|
||||||
|
(MODE == 2) ? MAX_2_5HZ :
|
||||||
|
(MODE == 3) ? MAX_5HZ :
|
||||||
|
(MODE == 4) ? MAX_10HZ :
|
||||||
|
MAX_1HZ; // по умолчанию 1 Гц
|
||||||
|
|
||||||
// Base LED signal (before output inversion)
|
reg [25:0] cnt; // хватает до > 33 млн (2^25 = 33_554_432)
|
||||||
reg led_base = 1'b0;
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
always @(posedge clk) begin
|
||||||
// 1 Hz generator for pin: divider from F_CLK
|
if (cnt >= MAX_COUNT) begin
|
||||||
// Period 1 Hz = 1 s, half-period = 0.5 s
|
cnt <= 0;
|
||||||
//---------------------------------------------------------
|
led <= ~led;
|
||||||
localparam integer PIN_1HZ_HALF_MAX = (F_CLK / 2) - 1;
|
pin <= led;
|
||||||
|
pin_10 <= led;
|
||||||
reg [31:0] pin_cnt = 32'd0;
|
end else begin
|
||||||
reg pin_base = 1'b0;
|
cnt <= cnt + 1;
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Function to calculate half-period in clock cycles
|
|
||||||
//---------------------------------------------------------
|
|
||||||
function [31:0] calc_max_count;
|
|
||||||
input [2:0] idx;
|
|
||||||
integer f;
|
|
||||||
begin
|
|
||||||
// Frequency in Hz: 0, 10, 20, 30, 40, 50
|
|
||||||
f = idx * 10;
|
|
||||||
if (f == 0) begin
|
|
||||||
// Special case: 0 Hz → no blinking
|
|
||||||
calc_max_count = 32'd0;
|
|
||||||
end else begin
|
|
||||||
// Half-period: F_CLK / (2 * f)
|
|
||||||
calc_max_count = (F_CLK / (2 * f)) - 1;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
endfunction
|
end
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Main process: step timing, frequency selection,
|
|
||||||
// blink generation
|
|
||||||
//---------------------------------------------------------
|
|
||||||
always @(posedge clk) begin
|
|
||||||
//-----------------------------------------------------
|
|
||||||
// Step timer: change frequency every 2 or 4 seconds
|
|
||||||
//-----------------------------------------------------
|
|
||||||
if (step_cnt >= (freq_idx == 3'd1 ? STEP_2SEC_MAX : STEP_4SEC_MAX)) begin
|
|
||||||
step_cnt <= 32'd0;
|
|
||||||
|
|
||||||
// Cycle through 0→1→2→3→4→5→0...
|
|
||||||
if (freq_idx == 3'd5)
|
|
||||||
freq_idx <= 3'd0;
|
|
||||||
else
|
|
||||||
freq_idx <= freq_idx + 3'd1;
|
|
||||||
end else begin
|
|
||||||
step_cnt <= step_cnt + 32'd1;
|
|
||||||
end
|
|
||||||
|
|
||||||
//-----------------------------------------------------
|
|
||||||
// Recalculate half-period for current frequency
|
|
||||||
//-----------------------------------------------------
|
|
||||||
max_count <= calc_max_count(freq_idx);
|
|
||||||
|
|
||||||
//-----------------------------------------------------
|
|
||||||
// Blink generation for led
|
|
||||||
//-----------------------------------------------------
|
|
||||||
if (max_count == 32'd0) begin
|
|
||||||
// 0 Hz: hold current state, no blinking
|
|
||||||
blink_cnt <= 32'd0;
|
|
||||||
// led_base keeps its last value
|
|
||||||
end else begin
|
|
||||||
if (blink_cnt >= max_count) begin
|
|
||||||
blink_cnt <= 32'd0;
|
|
||||||
led_base <= ~led_base;
|
|
||||||
end else begin
|
|
||||||
blink_cnt <= blink_cnt + 32'd1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
//-----------------------------------------------------
|
|
||||||
// 1 Hz generation for pin (independent of freq_idx)
|
|
||||||
//-----------------------------------------------------
|
|
||||||
if (pin_cnt >= PIN_1HZ_HALF_MAX) begin
|
|
||||||
pin_cnt <= 32'd0;
|
|
||||||
pin_base <= ~pin_base;
|
|
||||||
end else begin
|
|
||||||
pin_cnt <= pin_cnt + 32'd1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Outputs:
|
|
||||||
// led = inverted base signal (variable frequency)
|
|
||||||
// pin = 1 Hz
|
|
||||||
// pin_10 = inverted pin
|
|
||||||
//---------------------------------------------------------
|
|
||||||
assign led = ~led_base;
|
|
||||||
assign pin = pin_base;
|
|
||||||
assign pin_10 = led;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
Loading…
Reference in New Issue
Block a user