L'overclocking du processeur ou de la mémoire est compréhensible, mais pourquoi overclocker le rétroéclairage du moniteur?

Il s'agit de l'ancien Samsung SyncMaster BX2340 de 23 pouces (sorti en janvier 2011) avec rétro-éclairage LED. Au fil du temps, il a commencé à remarquer que travailler pour lui était fatigant et se concentrait de plus en plus difficile. Et pas seulement travailler, il suffit de lire, par exemple. Le moniteur lui-même est resté le même, mais cela est devenu plus difficile pour moi. Et pour les autres écrans, cela a très bien fonctionné.
Une fois
sur Internet, j'ai lu sur les sentiments subjectifs des utilisateurs de téléphones avec écrans OLED avec un taux de rafraîchissement de 240 Hz. Se plaint de fatigue et de maux de tête. Et il y avait des références (sans preuves) d'études sur l'effet de la fréquence de gradation du rétro-éclairage sur le corps: bien que l'œil ne voit pas de scintillement à 240 Hz, le cerveau y répond. Une lueur constante ou avec une fréquence supérieure à 3 kHz ne charge pas le cerveau de cette façon.
Ensuite, sur YouTube, j'ai obtenu une
vidéo sur la refonte du rétro-éclairage du moniteur pour le courant continu. L'intervention dans le schéma a été cardinale. Sous la vidéo, il y avait des commentaires sur le changement de couleur à faible courant sur les fils. Et mon rétro-éclairage fonctionne à 10-25%, car la pièce est assez sombre.
UPD : Dans la vidéo, l'auteur n'avait qu'une seule guirlande de LED et j'en avais 4.
Il a été décidé de quitter le contrôle de la luminosité en utilisant
PWM , mais d'augmenter la fréquence. Je n'ai même pas commencé à mesurer le scintillement par une méthode non invasive à l'aide d'une photorésistance ou d'une photodiode, j'ai tout de suite démonté le moniteur.

Contrôleur de rétroéclairage - OZ9993CN. Il n'y avait pas de fiche technique normale, seulement un pilote de rétroéclairage de groupe fabriqué par O
2 Micro. Il s'est avéré que le pilote est également impliqué dans l'augmentation de la tension (selon les mesures de 14,4 V à 54,6 V) en utilisant un transistor à effet de champ externe puissant et une inductance.
L'un des circuits a une signification similaire à celle du pilote; les numéros de broches ne correspondent pas:

Sur la carte, le chemin du signal PWM vers le pilote est signé comme B-Dim (gradation du rétro-éclairage?), Je n'ai pas eu à chercher. Ensuite, un clone de l'oscilloscope numérique USBee AX USB couplé à sigrok du côté PC est entré en jeu. La mesure a montré que la fréquence de rétroéclairage est de 180 Hz (ce ne sera pas suffisant!). Niveau de signal élevé - 5 V.

Maintenant, vous devez en quelque sorte augmenter la fréquence PWM à des valeurs kilohertz, une fois tous les 16. La première chose qui m'est venue à l'esprit est d'insérer un microcontrôleur dans l'espace de piste PWM pour recevoir le signal et le jouer 16 fois plus vite. Nous avons besoin de 2 temporisateurs, l'un mesurera la durée des niveaux bas et haut, l'autre donnera un signal PWM. Après avoir ramassé les coefficients du diviseur, nous pouvons nous passer du tout d'arithmétique, simplement en copiant. Non, Arduino ne le fera pas. Il n'y aura pas non plus d'assembleur, il y aura GCC. Le petit MK avec au moins deux minuteries (en stock) était ATtiny15. Mais WinAVR ne veut pas travailler avec, donc j'ai dû prendre une version plus ancienne - ATtiny45 (ATtiny25 / 85 fonctionnera également).
Schéma:
100n ┌───────┤├───────┐ │ ┌────────────┐ │ │ │ 1 8 ├─┴─ VCC │ │ 2 7 ├─ PB2 (INT0) INPUT │ │ 3 6 ├─ PB1 (OC1A) OUTPUT GND ─┴─┤ 4 5 │ └────────────┘ ATtiny45
Nous sélectionnons les facteurs des diviseurs de minuterie. Prenez la fréquence du processeur d'environ 8 MHz, à partir du générateur RC intégré.
- Minuterie de mesure. Combien de mesures pendant la période de gradation?
. Pour que cela s'intègre dans le registre à huit bits du temporisateur avec une perte de précision minimale, nous prenons le pré-diviseur 256, la valeur maximale du compteur sera
. - Minuterie PWM Nous allons augmenter la fréquence 16 fois:
, alors le pré-diviseur est autant de fois plus petit:
.
Le signal d'entrée est connecté à la jambe d'interruption externe. Gestionnaire de celui-ci:
ISR(INT0_vect, ISR_NAKED) { uint8_t timer = TCNT0;
Qu'est-ce que ISR_NAKED?"ISR_NAKED" signifie que la sauvegarde / restauration des registres et drapeaux du processeur est supprimée, ceci est fait pour accélérer. Cela peut être fait en s'assurant qu'ils ne sont pas affectés dans la boucle principale (nous avons juste une boucle while(1) {}
sans fin while(1) {}
), et qu'il n'y aura pas d'appels de sous-programmes. Eh bien, à la fin, nous prescrivons le retour de la fonction avec l'armement de l' reti()
interruption reti()
.
Soudé, flashé - et cela a fonctionné!

Mais l'accélérateur a commencé à grincer. Nous regardons ce qui se trouve sur la porte du contrôleur de terrain qui contrôle le courant à travers l'inductance de puissance:

Tout est en ordre avec l'accélérateur, il continue de fonctionner à une fréquence de 320 kHz, mais si auparavant la fréquence PWM était de 180 Hz et est presque inaudible (seulement si vous apportez votre oreille), alors 2,9 kHz est très audible. Et le confort n'a clairement pas augmenté. Mais que se passe-t-il si vous amenez la fréquence au-delà de la limite supérieure d'audibilité? Par exemple

? Nous modifions le multiplicateur du diviseur de temporisation PWM de 16 à 2 et le clignotons. Il s'est avéré que tout était en ordre. Presque.
Les minuteries à huit bits dans ce cas ne suffisent pas
, vous avez besoin de plus de minéraux . Cela se manifeste sous la forme de fluctuations de luminosité à basse fréquence, avec une augmentation et une disparition en douceur d'une fréquence de plusieurs secondes. Pour faire face à ce fléau, vous pouvez prendre le cristal plus gros, mais ce n'est pas notre chemin. Nous allons augmenter la profondeur de bits de la minuterie de mesure par programmation et introduire un seuil (hystérésis) pour une détection fiable de la commutation de luminosité par l'utilisateur (0–100 avec une résolution de 1). Nous augmentons la précision du chronomètre de mesure de 256 fois et le facteur multiplicateur devient égal à 1.
Gestionnaire de débordement de la minuterie de mesure avec l'option «quelque chose s'est mal passé et la durée du niveau a traîné»:
ISR(TIM0_OVF_vect, ISR_NAKED) { #define TIME_H_LIM (UCHAR_MAX-1) if (time_h < TIME_H_LIM) {
L'interruption externe est désormais un peu plus compliquée:
ISR(INT0_vect, ISR_NAKED) {
Il y a des variables globales que j'ai introduites dans les registres, nous avons l'overclocking après tout. SRAM est uniquement utilisé pour stocker l'adresse de retour lors de la saisie des gestionnaires d'interruption. La partie la plus élevée du compteur de mesure d'intervalle se trouve dans la variable time_h, et les valeurs de la longueur de cycle PWM et du rapport cyclique mesurés sont dans time_cycle et time_on, respectivement. SEUIL - seuil pour détecter les changements de luminosité.
Maintenant, tout fonctionnait comme prévu.
Code complet #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 }
Vous pouvez l'appeler autosuggestion, mais le résultat est le suivant: la vie est devenue meilleure, la vie est devenue plus amusante! Même les projets de longue haleine ont évolué.
Si dans votre cas, la fréquence du rétroéclairage n'affecte en rien votre bien-être et votre productivité - considérez-vous chanceux. Probablement. Ainsi que les personnes qui assurent un confort absolu lorsque la teneur en CO
2 de la pièce est supérieure à 0,2% (2000
ppm ).
Mais qu'en est-il du lien vers github?