Mengganti penyesuaian analog dengan digital pada catu daya laboratorium HY3005D

     Artikel ini akan membahas penggantian potensiometer standar dengan encoder mekanik EC11 (sensor sudut akumulasi) dalam unit catu daya Mastech HY3005D menggunakan mikrokontroler PIC16F1829 dan register geser 74HC595 yang menerapkan DAC pada matriks resistor R2R

Kata Pengantar


     Beberapa tahun yang lalu, saya membeli catu daya Mastech HY3005D. Belum lama ini ada masalah dengan regulasi tegangan - lapisan grafit rheostat aus dan pengaturan tegangan yang diperlukan menjadi tugas yang sulit. Tidak ada rheostat yang cocok, dan saya memutuskan untuk tidak membeli yang serupa, tetapi untuk mengubah metode penyesuaian.
     Tingkat tegangan dan arus keluaran diatur oleh tegangan referensi yang dipasok ke amplifier operasional. Dengan demikian, Anda dapat sepenuhnya menyingkirkan potensiometer dengan menggantinya dengan DAC yang mampu memberikan tegangan dalam kisaran yang diinginkan.
     Dalam katalog microchip, saya tidak dapat menemukan mikrokontroler yang cocok yang memiliki dua DAC, dan DAC eksternal tidak memiliki label harga yang kecil dan fungsi ekstra yang terlalu banyak. Oleh karena itu, saya memperoleh register geser 74HC595 dan resistor untuk matriks R2R. Mikrokontroler PIC16F1829 sudah tersedia.
     Agar dapat kembali ke sirkuit asli, semua perubahan diminimalkan - menggantikan unit penyesuaian yang dibuat pada papan terpisah.

Deskripsi pekerjaan


     Rangkaian ini didasarkan pada mikrokontroler PIC16F1829 yang beroperasi pada frekuensi 32 MHz. Frekuensi clock diatur oleh generator clock internal, menurut datasheet itu tidak terlalu akurat, tetapi untuk sirkuit ini tidak kritis. Keuntungan dari MK ini adalah adanya pull-up resistor pada semua input digital dan dua modul MSSP yang mengimplementasikan SPI. Semua 18 pin logika mikrokontroler digunakan.
     Pada empat register geser 74HC595dan matriks R2R mengimplementasikan dua DAC 16-bit. Keuntungan dari register ini termasuk adanya register shift dan register penyimpanan yang terpisah. Ini memungkinkan Anda untuk menulis data ke register tanpa merusak nilai output saat ini. Matriks R2R dipasang pada resistor dengan kesalahan 1%. Perlu dicatat bahwa pengukuran selektif menunjukkan kesalahan tidak lebih dari 10 ohm. Awalnya, itu direncanakan untuk menggunakan 3 register, tetapi ketika kabel papan tampaknya bagi saya bukan solusi yang baik, di samping itu, perlu untuk menambahkan camilan.
     Resistor pull-up yang terpasang pada MC diaktifkan pada semua input dan menyederhanakan sirkuit. Semua output dari encoders terhubung langsung ke terminal MK, total masing-masing 4 encoders memiliki dua output untuk sensor rotasi itu sendiri dan satu untuk tombol built-in. Sebanyak 12 kesimpulan MK digunakan untuk memproses input data. Bouncing kontak dihaluskan dengan kapasitas 100nF. Setelah mengubah nilai buffer arus dan tegangan 16-bit sesuai dengan data input dari enkoder, nilai-nilai tersebut ditransfer ke register geser 74HC595 melalui SPI. Untuk mengurangi waktu transfer data, dua modul SPI digunakan, yang memungkinkan data ditransmisikan secara bersamaan untuk arus dan tegangan. Setelah data ditransfer ke register, perintah dikirim untuk mentransfer data dari buffer shift ke buffer penyimpanan. Keluaran register terhubung ke matriks R2R yang bertindak sebagai pembagi untuk DAC.Tegangan keluaran dari matriks ditransmisikan ke input amplifier operasional.
     Tombol-tombol yang dibangun ke dalam enkoder menetapkan minimum (tombol enkoder untuk pengaturan halus) atau maksimum (tombol enkoder untuk pengaturan kasar), masing-masing, untuk arus atau tegangan.

Skema


     Di Internet, saya tidak menemukan skema yang sepenuhnya sesuai dengan skema saya, jadi saya mengambil tautan pertama. Membuat koreksi pada inkonsistensi yang terungkap dan kemudian menambahkan perubahan. Saya menggambar diagram blok penyesuaian di TinyCAD - unduh file HY3005D-regulator.dsn .

Asli


Setelah ditemukan ketidakakuratan


Skema terakhir setelah penyempurnaan

Unit portabel dengan penyesuaian (disorot dengan warna merah) ditempatkan dalam skema terpisah.

Voltmeter digital dengan tampilan di panel depan (tidak ada pada diagram) terhubung ke konektor J3.

Komponen yang Digunakan


     Di bawah ini adalah daftar komponen yang digunakan (kasing ditunjukkan dalam tanda kurung). Semua dibeli pada waktu yang berbeda di Cina. Penting untuk menggunakan LED dengan karakteristik yang sama dengan yang asli mereka berdiri seri di sirkuit keluaran amplifier operasional (saya mengambil yang sama yang berdiri di motherboard saya).
  • U1: PIC16F1829I / ML mikrokontroler (QFN)
  • U2 - U5: register geser 74HC595BQ (DHVQFN16 atau SOT-763)
  • U6: AMS1117 5V regulator tegangan linier (SOT-223)
  • RE1 - RE4: sensor sudut akumulasi mekanik EC11
  • Matriks R1, R2 dan R2R: resistor 1 dan 2 kΩ (SMD 0402)
  • C1 - C12, C14-C17: Kapasitor Keramik GRM21BR71E104KA01L 100nF (SMD 0805)
  • C13: tantalum kapasitor 22mkF 16V (tiv B)
  • D1, D2: voltase panel depan / LED saat ini


Biaya


     Saya membesarkan papan di Sprint Layout 6 - unduh file HY3005D-regulator.lay6 . Sayangnya, yang asli di mana saya membuat versi saya tidak dipertahankan, dalam format lay6 sudah dengan koreksi diidentifikasi selama perakitan:

  1. Saya menambahkan jumper di sebelah antarmuka firmware ke koneksi interupsi dari kendali arus lancar, karena pemantulan kontak kapasitas penyaringan mencegah pemasangan pengontrol
  2. Menambahkan jumper yang hilang untuk tanah di antara kedua sisi
  3. Memindahkan perakitan penstabil 5V ke sisi lain untuk mengurangi jumper
  4. Menambahkan kapasitor smoothing pada saluran listrik ( diskusi )

Foto setelah etsa dan pengeboran (versi pertama)



     Dibuat menggunakan film photoresist. Saya menderita untuk waktu yang lama dengan kabel register kecil. Dalam versi terakhir, ada kekurangan kecil yang harus dibersihkan setelah etsa. Namun secara umum, dewan gagal. Masih ada dua jumper yang cukup untuk menghubungkan tanah di sisi depan dan belakang.

Setelah memasukkan masalah yang diidentifikasi (versi kedua)


0 SMD 0805.

Foto setelah pembukaan dan pemasangan dilakukan


      . — . — 12.

     Seperti yang Anda lihat, perubahannya minimal, semua konektor lama tetap tidak berubah. Saya harus menambahkan makanan secara terpisah, karena satu-satunya tegangan yang masuk ke papan penyesuaian 2.5V tidak cocok untuk pembagi asli. Jika Anda melepaskan 2.5V zener diode (V5A) pada papan utama catu daya dan meletakkan jumper di tempat resistor (R1A), Anda dapat melakukannya tanpa tambahan pasokan daya 12V.

Firmware


Kode C untuk kompiler XC8. Dijahit PICkit 3 asli.

config.h
// PIC16F1829 Configuration Bit Settings

// 'C' source line config statements

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)


main.c
#include "config.h"

#define _XTAL_FREQ 32000000
#pragma intrinsic(_delay)
extern void _delay(unsigned long);
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))

#define TransferNotDone          !(SSP2STAT&0b00000001)

#define StoreAll                 LATA4
#define ResetAll                 LATC6

#define VoltageSharpCHA          RC1
#define VoltageSharpCHB          RC0
#define VoltageSharpBTN          RA2

#define VoltageSmoothCHA         RB5
#define VoltageSmoothCHB         RB4
#define VoltageSmoothBTN         RC2

#define CurrentSharpCHA          RC5
#define CurrentSharpCHB          RC4
#define CurrentSharpBTN          RC3

#define CurrentSmoothCHA         RA1
#define CurrentSmoothCHB         RA0
#define CurrentSmoothBTN         RA3

#define VoltageRateSharp         0x0100
#define VoltageRateSmooth        0x0010
#define CurrentRateSharp         0x0040
#define CurrentRateSmooth        0x0004

#define VoltageMax               0xC000
#define CurrentMax               0x5000
#define VoltageMin               0x0000
#define CurrentMin               0x0000

#define VoltageStart             0x1E00
#define CurrentStart             CurrentMax

unsigned short VoltageBuff;
unsigned short CurrentBuff;

void interrupt tc_int() {
};

void SendData() {
    SSP1BUF = VoltageBuff>>8;
    SSP2BUF = CurrentBuff>>8;
    while ( TransferNotDone );
    SSP1BUF = VoltageBuff;
    SSP2BUF = CurrentBuff;
    while ( TransferNotDone );
    StoreAll = 1;
    StoreAll = 0;
};

void main() {
    // Configure oscillator for 32MHz
    //             76543210
    OSCCON     = 0b11110000; //B1

    // Enable individual pull-ups
    //             76543210
    OPTION_REG = 0b01111111; //B1

    // Configure analog port (1 - enable, 0 - disable)
    //             76543210
    ANSELA     = 0b00000000; //B3
    ANSELB     = 0b00000000; //B3
    ANSELC     = 0b00000000; //B3

    // Reset latch
    //             76543210
    LATA       = 0b00000000; //B2
    LATB       = 0b00000000; //B2
    LATC       = 0b00000000; //B2

    // Alternate pin function (set SDO2 on RA5)
    //             76543210
    APFCON0    = 0b00000000; //B2
    APFCON1    = 0b00100000; //B2

    // Configure digital port (1 - input, 0 - output)
    //             76543210
    TRISA      = 0b00001111; //B1
    TRISB      = 0b00110000; //B1
    TRISC      = 0b00111111; //B1

    // Configure input level (1 - CMOS, 0 - TTL)
    INLVLA     = 0b11000000; //B7
    INLVLB     = 0b00001111; //B7
    INLVLC     = 0b00000000; //B7

    // Configure individual pull-ups (1 - enable, 0 - disable)
    //             76543210
    WPUA       = 0b00111111; //B4
    WPUB       = 0b11110000; //B4
    WPUC       = 0b11111111; //B4

    ResetAll = 0;
    ResetAll = 1;

    // Configure SPI in master mode
    //             76543210
  //SSP1ADD    = 0b00000000; //B4
    SSP1STAT   = 0b01000000; //B4
    SSP1CON3   = 0b00000000; //B4
    SSP1CON1   = 0b00100000; //B4
  //SSP1ADD    = 0b00000000; //B4
    SSP2STAT   = 0b01000000; //B4
    SSP2CON3   = 0b00000000; //B4
    SSP2CON1   = 0b00100000; //B4

    VoltageBuff = VoltageStart;
    CurrentBuff = CurrentStart;
    __delay_ms(50);
    SendData();

    while ( 1 ) {
        if ( !VoltageSharpCHA ) {
            if ( VoltageSharpCHB ) { VoltageBuff-=VoltageRateSharp; if ( VoltageBuff > VoltageMax ) VoltageBuff = VoltageMin; }
                              else { VoltageBuff+=VoltageRateSharp; if ( VoltageBuff > VoltageMax ) VoltageBuff = VoltageMax; }
            while ( !VoltageSharpCHA );
            SendData();
        }

        if ( !VoltageSmoothCHA ) {
            if ( VoltageSmoothCHB ) { VoltageBuff-=VoltageRateSmooth; if ( VoltageBuff > VoltageMax ) VoltageBuff = VoltageMin; }
                               else { VoltageBuff+=VoltageRateSmooth; if ( VoltageBuff > VoltageMax ) VoltageBuff = VoltageMax; }
            while ( !VoltageSmoothCHA ); 
            SendData();
        }

        if ( !CurrentSharpCHA ) {
            if ( CurrentSharpCHB ) { CurrentBuff-=CurrentRateSharp; if ( CurrentBuff > CurrentMax ) CurrentBuff = CurrentMin; }
                              else { CurrentBuff+=CurrentRateSharp; if ( CurrentBuff > CurrentMax ) CurrentBuff = CurrentMax; }
            while ( !CurrentSharpCHA );
            SendData();
        }

        if ( !CurrentSmoothCHA ) {
            if ( CurrentSmoothCHB ) { CurrentBuff-=CurrentRateSmooth; if ( CurrentBuff > CurrentMax ) CurrentBuff = CurrentMin; }
                               else { CurrentBuff+=CurrentRateSmooth; if ( CurrentBuff > CurrentMax ) CurrentBuff = CurrentMax; }
            while ( !CurrentSmoothCHA );
            SendData();
        }

        if ( !VoltageSharpBTN  ) { VoltageBuff = VoltageMax; while ( !VoltageSharpBTN  ); SendData(); }
        if ( !VoltageSmoothBTN ) { VoltageBuff = VoltageMin; while ( !VoltageSmoothBTN ); SendData(); }
        if ( !CurrentSharpBTN  ) { CurrentBuff = CurrentMax; while ( !CurrentSharpBTN  ); SendData(); }
        if ( !CurrentSmoothBTN ) { CurrentBuff = CurrentMin; while ( !CurrentSmoothBTN ); SendData(); }
    };
}


     Untuk nilai minimum, VoltageMin dan CurrentMin diatur ke 1, karena pada 0 di buffer, penyesuaian berhenti bekerja sampai saya mengerti di mana masalahnya. Tarif * Nilai * dipilih banyak dan paling nyaman menurut saya. Untuk metode SendData, saya tidak melewatkan variabel sebagai parameter untuk menyimpan instruksi dan memori mesin. Mode Low Voltage Firmware (LVP) harus dimatikan, jika tidak, RA3 tidak akan berfungsi sebagai input digital. Interupsi tidak digunakan, metode tc_int ada dalam kode sehingga kompiler menempatkan blok utama di awal ROM.
     Untuk firmware, cukup untuk menghapus jumper, sambungkan PICkit 3 (atau programmer lain) dan lakukan firmware. Pada versi pertama tidak ada jumper pada CLK dan DAT, jadi saya harus melepas kapasitor smoothing, flash mereka dan kemudian solder kembali.
UPD:Setelah memasang kapasitas tambahan pada saluran listrik, masalah keluarnya penghitung dari posisi nol menghilang. Saya juga harus mengubah arah rotasi. Rupanya, suara dari penyearah AMS1117 mencegah pengakuan yang benar dari keadaan enkoder. Selain itu, saya menambahkan pengaturan nilai awal, sekarang tegangan default diatur ke 5 volt (arus masih maksimum). Sebelum pengiriman data pertama, penundaan 50ms dimasukkan ke dalam register (nilai penundaan diambil dengan margin besar) untuk menunggu modul SPI diinisialisasi.

Karakteristik tegangan keluaran


     Setelah perakitan akhir perangkat, pengukuran tegangan dilakukan antara kontak J4.1 - J4.2 (pengaturan tegangan) dan J4.1 - J4.7 (pengaturan saat ini). Menurut data yang diperoleh, grafik (di bawah di bawah spoiler) dari dependensi nilai / tegangan untuk DAC diplot.
Grafik



Nilai-nilai yang dihitung dari tegangan diperoleh dengan rumus (U * D) / (2 ^ K), di mana
U adalah tegangan pada output register, dengan mempertimbangkan pembagi di sirkuit utama (untuk DAC saat ini - 4950mV, untuk tegangan DAC - 3550mV);
D adalah nilai desimal dari penghitung DAC;
Kedalaman bit K - DAC (16 bit)

Apa yang bisa diperbaiki


  • menambahkan nilai penghematan waktu
  • ikat nilai standar ke tombol enkoder, misalnya, untuk tegangan: 3.3; 5.0; 7.5; 12V
  • untuk melindungi terhadap nilai yang tidak diketahui pada saat startup, lebih baik untuk menghubungkan MR ke 1, dan tarik OE melalui resistor ke 1 dan reset ke 0 setelah menginisialisasi MK.
  • ganti DAC dengan PWM dengan rantai penghalus ( LampTester disarankan di sini )

Source: https://habr.com/ru/post/id391617/


All Articles