Monitor overclocking

Overclocking prosesor atau memori dapat dimengerti, tetapi mengapa melakukan overclock pada lampu latar monitor?



Ini tentang 23-inch Samsung SyncMaster BX2340 (dirilis pada Januari 2011) dengan LED backlight. Seiring waktu, ia mulai memperhatikan bahwa bekerja untuknya melelahkan, dan berkonsentrasi semakin sulit. Dan tidak hanya berfungsi, baca saja, misalnya. Monitor itu sendiri tetap sama, tetapi menjadi lebih sulit bagi saya. Dan untuk layar lain itu bekerja dengan sangat baik.

Setelah di Internet saya membaca tentang perasaan subjektif pengguna ponsel dengan layar OLED dengan kecepatan refresh 240 Hz. Keluhan lelah dan sakit kepala. Dan ada referensi (tanpa bukti) studi tentang pengaruh frekuensi redup cahaya latar pada tubuh: meskipun mata tidak melihat berkedip pada 240 Hz, otak meresponnya. Cahaya konstan atau dengan frekuensi lebih dari 3 kHz tidak memuat otak dengan cara ini.

Kemudian di YouTube saya mendapat video tentang membuat kembali lampu latar monitor untuk arus searah. Intervensi dalam skema tersebut adalah kardinal. Di bawah video ada komentar tentang perubahan warna pada arus rendah pada kabel. Dan lampu latar saya bekerja pada 10-25%, karena ruangannya cukup gelap. UPD : Dalam video, penulis hanya memiliki satu karangan LED, dan saya punya 4.

Diputuskan untuk meninggalkan kontrol kecerahan menggunakan PWM , tetapi meningkatkan frekuensi. Saya bahkan tidak mulai mengukur flicker dengan metode non-invasif menggunakan fotoresistor atau fotodioda, saya segera membongkar monitor.



Pengontrol Cahaya Latar - OZ9993CN. Tidak ada lembar data normal, hanya driver lampu latar grup yang dibuat oleh O 2 Micro. Ternyata pengemudi juga terlibat dalam meningkatkan tegangan (menurut pengukuran dari 14,4 V menjadi 54,6 V) menggunakan transistor efek medan kuat dan induktansi.

Salah satu sirkuit memiliki arti yang mirip dengan pengemudi, nomor pin tidak cocok:



Di papan tulis, jalur sinyal PWM ke pengemudi ditandatangani sebagai B-Dim (Backlight dimming?), Saya tidak perlu mencari. Selanjutnya, tiruan dari USBee AX USB digital osiloskop digabungkan dengan sigrok di sisi PC ikut bermain. Pengukuran menunjukkan bahwa frekuensi lampu latar adalah 180 Hz (itu tidak akan cukup!). Level sinyal tinggi - 5 V.



Sekarang Anda perlu menaikkan frekuensi PWM ke nilai kilohertz, sekali setiap 16. Hal pertama yang terlintas dalam pikiran adalah memasukkan mikrokontroler ke dalam celah trek PWM untuk menerima sinyal dan memutarnya 16 kali lebih cepat. Kami membutuhkan 2 timer, yang satu akan mengukur durasi level rendah dan tinggi, yang lain akan memberikan sinyal PWM. Setelah mengambil koefisien pembagi, kita dapat melakukannya tanpa aritmatika sama sekali, hanya dengan menyalin. Tidak, Arduino tidak akan melakukannya. Tidak akan ada assembler juga, akan ada GCC. MK kecil dengan setidaknya dua timer (dari stok) adalah ATtiny15. Tapi WinAVR tidak ingin bekerja dengannya, jadi saya harus mengambil versi yang lebih lama - ATtiny45 (ATtiny25 / 85 juga akan bekerja).

Skema:

100n ┌───────┤├───────┐ │ ┌────────────┐ │ │ │ 1 8 ├─┴─ VCC │ │ 2 7 ├─ PB2 (INT0) INPUT │ │ 3 6 ├─ PB1 (OC1A) OUTPUT GND ─┴─┤ 4 5 │ └────────────┘ ATtiny45 

Kami memilih faktor pembagi timer. Ambil frekuensi CPU sekitar 8 MHz, dari built-in RC-generator.

  • Pengukur waktu. Berapa banyak ukuran dalam periode peredupan? 8000000/180 sekitar$4444. Agar sesuai dengan register delapan-bit timer dengan kehilangan akurasi minimum, kami mengambil pre-divider 256, nilai maksimum dari counter akan menjadi 8.000.000/180/256 sekitar$173,.
  • Timer PWM Kami akan membuat frekuensinya 16 kali lebih besar: 180 cdot16=2880Hz, maka pra-pembagi adalah beberapa kali lebih kecil: 256/16=16.

Sinyal input terhubung ke kaki interupsi eksternal. Penangannya:

 /* External Interrupt 0 */ ISR(INT0_vect, ISR_NAKED) { uint8_t timer = TCNT0; //     if (PINB & 1<<PB2) { //  .   -    OCR1C = timer; //   TCNT0 = 0; //     } else { //   -  OCR1A = timer; //   } reti(); } 

Apa itu ISR_NAKED?
"ISR_NAKED" berarti bahwa penyimpanan / pengembalian register dan bendera prosesor dibuang, ini dilakukan untuk mempercepat. Ini dapat dilakukan dengan memastikan bahwa mereka tidak terpengaruh dalam loop utama (kami hanya memiliki loop while(1) {} ), dan bahwa tidak akan ada panggilan dari subrutin. Nah, pada akhirnya, kami meresepkan kembalinya dari fungsi dengan memiringkan reti() interrupt reti() bendera.

Disolder, dipasang - dan berhasil!



Tetapi throttle itu mulai berdecit. Kami melihat apa yang ada di gerbang pengontrol lapangan yang mengontrol arus melalui induktor daya:



Semuanya sesuai dengan throttle, itu terus beroperasi pada frekuensi 320 kHz, tetapi jika sebelumnya frekuensi PWM adalah 180 Hz dan hampir tidak terdengar (hanya jika Anda membawa telinga Anda), maka 2,9 kHz sangat terdengar. Dan kenyamanan jelas tidak meningkat. Tetapi bagaimana jika Anda membawa frekuensi melampaui batas kemampuan mendengar? Sebagai contoh 180Hz cdot128=23040Hz? Kami mengubah pengali pembagi timer PWM dari 16 menjadi 2, dan mem-flash-nya. Ternyata semuanya beres. Hampir.

Timer delapan bit dalam kasus ini tidak cukup , Anda perlu lebih banyak mineral . Ini memanifestasikan dirinya dalam bentuk fluktuasi frekuensi rendah dalam kecerahan, dengan peningkatan halus dan hilangnya frekuensi beberapa detik. Untuk mengatasi momok ini, Anda dapat mengambil kristal lebih gemuk, tapi ini bukan cara kami. Kami akan meningkatkan kedalaman bit timer pengukur secara terprogram dan memperkenalkan ambang batas (histeresis) untuk deteksi andal perpindahan kecerahan oleh pengguna (0-100 dengan resolusi 1). Kami meningkatkan keakuratan pengukur waktu sebanyak 256 kali, dan faktor pengali menjadi sama dengan 1.

Mengukur timer overflow handler dengan opsi "ada yang salah dan durasi level berlarut-larut":

 /* Timer/Counter0 Overflow */ ISR(TIM0_OVF_vect, ISR_NAKED) { #define TIME_H_LIM (UCHAR_MAX-1) if (time_h < TIME_H_LIM) { // Normal way time_h += 1; } else { // High part overflowed if (PINB & 1<<PB2) { OCR1A = TIME_H_LIM; // Always on } else { OCR1A = 0; // Always off } OCR1C = TIME_H_LIM; time_h = 0; time_cycle = 0; time_on = 0; } reti(); // Because ISR_NAKED } 

Gangguan eksternal sekarang juga sedikit lebih rumit:

 /* External Interrupt 0 */ ISR(INT0_vect, ISR_NAKED) { // F_CPU / Timer1 prescaler / F_PWM_IN / grades / 4 #define THRESHOLD (F_CPU / 1 / F_PWM_IN / 100 / 4) uint16_t time; uint8_t time_l = TCNT0; if ((TIFR & 1<<TOV0) && (time_l <= UCHAR_MAX/2)) { // Overflow occured right now time_l = UCHAR_MAX; // 0xff } time = (time_h << 8) + time_l; if (PINB & 1<<PB2) { // Risen if (abs(time - time_cycle) > THRESHOLD) { time_cycle = time; OCR1C = time_h; } TCNT0 = 0; time_h = 0; if (TIFR & 1<<TOV0) { TIFR = 1<<TOV0; // Clear Timer0 overflow flag } } else { // Falled if (abs(time - time_on) > THRESHOLD) { time_on = time; OCR1A = time_h; } } reti(); // Because ISR_NAKED } 

Ada beberapa variabel global yang saya kendarai ke register, bagaimanapun juga kita memiliki overclocking. SRAM hanya digunakan untuk menyimpan alamat pengirim saat memasukkan interrupt handler. Bagian tertinggi dari penghitung pengukuran interval adalah dalam variabel time_h, dan nilai-nilai dari panjang siklus PWM yang diukur dan siklus tugas masing-masing adalah dalam time_cycle dan time_on. THRESHOLD - ambang batas untuk mendeteksi perubahan kecerahan.

Sekarang semuanya berfungsi, seperti yang dimaksudkan.

Kode lengkap
 /* PWM frequency multiplier x128 100n ┌───────┤├───────┐ │ ┌────────────┐ │ │ │ 1 8 ├─┴─ VCC │ │ 2 7 ├─ PB2 (INT0) INPUT │ │ 3 6 ├─ PB1 (OC1A) OUTPUT GND ─┴─┤ 4 5 │ └────────────┘ ATtiny45 fuses: lfuse=0xe2 hfuse=0xdf */ #include <avr/interrupt.h> #include <avr/wdt.h> #include <stdlib.h> #include <limits.h> #define F_CPU 8000000UL #define F_PWM_IN 180U register uint8_t time_h asm("r4"); // High part of time counter register uint16_t time_cycle asm("r12"); // Period register uint16_t time_on asm("r14"); // H level duration __attribute__((naked)) int main(void) { time_h = 0; time_cycle = 0; time_on = 0; ACSR |= 1<<ACD; // Comparator disable // Timer0 TCCR0A = 0; // CK/1 TCCR0B = 1<<CS00; // Timer1 DDRB |= 1<<PB1; // PWM output // CK/2, Clear the OC1A output line TCCR1 = 1<<CTC1|1<<PWM1A|2<<COM1A0|2<<CS10; TIMSK |= 1<<TOIE0; // Timer0 overflow // Ext int 0 MCUCR |= 1<<ISC00; // Any logical change on INT0 generates an interrupt request GIMSK |= 1<<INT0; // External Interrupt Request 0 Enable PORTB |= 1<<PB2; // Input wdt_enable(WDTO_120MS); // Watchdog on sei(); // Interrupts enable while (1) { // Do not use flags or registers wdt_reset(); // Watchdog reset } } /* External Interrupt 0 */ ISR(INT0_vect, ISR_NAKED) { // F_CPU / Timer1 prescaler / F_PWM_IN / grades / 4 #define THRESHOLD (F_CPU / 1 / F_PWM_IN / 100 / 4) uint16_t time; uint8_t time_l = TCNT0; if ((TIFR & 1<<TOV0) && (time_l <= UCHAR_MAX/2)) { // Overflow occured right now time_l = UCHAR_MAX; // 0xff } time = (time_h << 8) + time_l; if (PINB & 1<<PB2) { // Risen if (abs(time - time_cycle) > THRESHOLD) { time_cycle = time; OCR1C = time_h; } TCNT0 = 0; time_h = 0; if (TIFR & 1<<TOV0) { TIFR = 1<<TOV0; // Clear Timer0 overflow flag } } else { // Falled if (abs(time - time_on) > THRESHOLD) { time_on = time; OCR1A = time_h; } } reti(); // Because ISR_NAKED } /* Timer/Counter0 Overflow */ ISR(TIM0_OVF_vect, ISR_NAKED) { #define TIME_H_LIM (UCHAR_MAX-1) if (time_h < TIME_H_LIM) { // Normal way time_h += 1; } else { // High part overflowed if (PINB & 1<<PB2) { OCR1A = TIME_H_LIM; // Always on } else { OCR1A = 0; // Always off } OCR1C = TIME_H_LIM; time_h = 0; time_cycle = 0; time_on = 0; } reti(); // Because ISR_NAKED } 


Anda dapat menyebutnya saran otomatis, tetapi hasilnya adalah ini: hidup menjadi lebih baik, hidup telah menjadi lebih menyenangkan! Bahkan proyek yang sudah lama berjalan pun berlanjut.

Jika dalam kasus Anda, frekuensi lampu latar tidak memengaruhi kesejahteraan dan produktivitas Anda - anggaplah Anda beruntung. Mungkin Serta orang yang memastikan bahwa mereka benar-benar nyaman ketika konten CO 2 di dalam ruangan lebih dari 0,2% (2000 ppm ).

Tapi bagaimana dengan tautan ke github?

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


All Articles