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 |
147
blink.v
147
blink.v
@ -1,122 +1,55 @@
|
||||
module blink #(
|
||||
// Input clock frequency in Hz
|
||||
parameter integer F_CLK = 50_000_000 // 50 MHz
|
||||
// Выбор частоты мигания (F_BLINK), Гц:
|
||||
// 1 -> 1
|
||||
// 2.5 -> 25 (см. ниже, делим на 10)
|
||||
// 5 -> 5
|
||||
// 10 -> 10
|
||||
parameter integer MODE = 4 // по умолчанию 1 Гц
|
||||
)(
|
||||
input wire clk,
|
||||
output wire led,
|
||||
output wire pin,
|
||||
output wire pin_10
|
||||
input wire clk, // 50 MHz
|
||||
output reg led,
|
||||
output reg pin,
|
||||
output reg pin_10
|
||||
);
|
||||
|
||||
//---------------------------------------------------------
|
||||
// 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;
|
||||
localparam integer F_CLK = 50_000_000;
|
||||
|
||||
// Step timer counter
|
||||
reg [31:0] step_cnt = 32'd0;
|
||||
// Предрасчитанные MAX_COUNT для половины периода:
|
||||
//
|
||||
// 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
|
||||
reg [2:0] freq_idx = 3'd0;
|
||||
localparam integer MAX_1HZ = 25_000_000 - 1;
|
||||
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
|
||||
reg [31:0] blink_cnt = 32'd0;
|
||||
reg [31:0] max_count = 32'd0;
|
||||
// Выбор MAX_COUNT по MODE
|
||||
// MODE:
|
||||
// 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 led_base = 1'b0;
|
||||
reg [25:0] cnt; // хватает до > 33 млн (2^25 = 33_554_432)
|
||||
|
||||
//---------------------------------------------------------
|
||||
// 1 Hz generator for pin: divider from F_CLK
|
||||
// Period 1 Hz = 1 s, half-period = 0.5 s
|
||||
//---------------------------------------------------------
|
||||
localparam integer PIN_1HZ_HALF_MAX = (F_CLK / 2) - 1;
|
||||
|
||||
reg [31:0] pin_cnt = 32'd0;
|
||||
reg pin_base = 1'b0;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// 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
|
||||
endfunction
|
||||
|
||||
//---------------------------------------------------------
|
||||
// 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;
|
||||
if (cnt >= MAX_COUNT) begin
|
||||
cnt <= 0;
|
||||
led <= ~led;
|
||||
pin <= led;
|
||||
pin_10 <= led;
|
||||
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;
|
||||
cnt <= cnt + 1;
|
||||
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
|
||||
Loading…
Reference in New Issue
Block a user