Недавно задумался над усмирением шумного вентилятора в компьютере.
Ранее у меня было ограничено напряжение на вентиляторе, последовательно подключен стабилитрон.
Схема вполне эффективно работает, вентилятор почти не слышно, но есть один недостаток, стабилитрон греется. Рассеиваемая мощность составляет 1Вт = 3.3В * 0,3А. И еще хотелось бы иметь возможность регулировать скорость, а на материнской плате регулируется только вентилятор процессора.
В регуляторах с высоким КПД применяют широтно-импульсную модуляцию. Регулирующий элемент работает в ключевом режиме, то есть находится в одном из двух состояний: открыт или закрыт. Частота переключений остается постоянной, меняется соотношение времени открытого и закрытого состояний. На выходе импульсное напряжение фильтруется LC цепочкой, на нагрузке остается постоянная составляющая.
Широтно-импульсная модуляция реализована в микроконтроллерах семейства PIC16, но только для одного выхода. Программно сложно сделать достаточно высокочастотную модуляцию сразу для нескольких выходов.
Отладил программку в PIC simulator IDE. 4-х канальный 16-ти уровневый ШИМ модулятор, импульсы на выходах появляются в разное время, при условии что на них установлены разные уровни.
; коэффициент делителя TMR0 TMR0PRESCAL EQU 1 ; значение инициализации регистра OPTION_REG ; Выходы ШИМ OUTPORT EQU 0x05 ;порт вывода, PORTA в данном случае OUTPORTMASK EQU 0xF0 OUTPIN1 EQU 0 OUTPIN2 EQU 1 OUTPIN3 EQU 2 OUTPIN4 EQU 3 ; Копия порта вывода TMPOUT EQU 0x21 ; Входные параметры функции PWM4 TMPVAL1 EQU 0x22 TMPVAL2 EQU 0x23 TMPVAL3 EQU 0x24 TMPVAL4 EQU 0x25 COUNTER EQU 0x26 ; Переменные для хранения контекста во время прерывания W_TEMP EQU 0x70 ; Для хранения W регистра STATUS_TEMP EQU 0x20 ;---------- ORG 0 GOTO MAIN ORG 4 INTERRUPT: MOVWF W_TEMP SWAPF STATUS,W BCF STATUS,RP0 BCF STATUS,RP1 MOVWF STATUS_TEMP ; Тело обработчика прерывания BCF INTCON,T0IF ; сбрасываем флаг прерывания SWAPF STATUS_TEMP,W MOVWF STATUS SWAPF W_TEMP,F SWAPF w_TEMP,W RETFIE INITTMR0: ; переключаем предделитель на вход TMR0 ; устанавливаем коэффициент деления CLRF TMR0 BSF STATUS,RP0 MOVLW TMR0PRESCAL MOVWF OPTION_REG ; Разрешаем прерывания CLRF INTCON BSF INTCON,T0IE BSF INTCON,GIE BCF STATUS,RP0 RETURN PWM4: MOVF TMPOUT,W MOVWF OUTPORT ;Отправляем значение в порт ANDLW OUTPORTMASK ;Сбрасываем используемые биты MOVWF TMPOUT INCF TMPVAL1,W SUBWF COUNTER,W BTFSS STATUS,C BSF TMPOUT,OUTPIN1 INCF TMPVAL2,W SUBWF COUNTER,W BTFSS STATUS,C BSF TMPOUT,OUTPIN2 INCF TMPVAL3,W SUBWF COUNTER,W BTFSS STATUS,C BSF TMPOUT,OUTPIN3 INCF TMPVAL4,W SUBWF COUNTER,W BTFSS STATUS,C BSF TMPOUT,OUTPIN4 RETURN MAIN: INIT: CLRF STATUS ; По умолчанию выбираем нулевую страницу памяти CALL INITTMR0 ; устанавливаем направление порта BSF STATUS,RP0 CLRF OUTPORT ; TRIS BCF STATUS,RP0 ; Переключаем на нулевую страницу памяти ; инициализируем переменные BREZEN4 CLRF TMPOUT ; Передаем параметры Функции MOVLW 0x00 ; Значение на первом выходе MOVWF TMPVAL1 MOVLW 0x01 MOVWF TMPVAL2 MOVLW 0x08 MOVWF TMPVAL3 MOVLW 0x0F MOVWF TMPVAL4 RESETCOUNTER: MOVLW 0x10 MOVWF COUNTER MAINLOOP: CALL PWM4 DECFSZ COUNTER,F GOTO MAINLOOP GOTO RESETCOUNTER
Генерируемая частота получилась совсем невелика - 11кГц. И это при частоте кварца 20МГц.
Решил реализовать на основе метода Брезенхема. Сигнал на выходе появляется во время переполнения счетчика-сумматора.
Например:
Нам нужно значение 5 из 16 уровней.
Значение счетчика | Действие | Выход |
0 | 0+5 | Переполнения не возникло, на выходе 0 |
5 | 5+5 | Переполнения не возникло, на выходе 0 |
10 | 10+5 | Переполнения не возникло, на выходе 0 |
15 | 15+5 | Переполнение, на выходе 1 |
Импульсы в выходном потоке появляются достаточно равномерно.
Программная реализация 4-х канального регулятора для микроконтроллера PIC.; коэффициент делителя TMR0 TMR0PRESCAL EQU 1 ; значение инициализации регистра OPTION_REG ; Выходы ШИМ START_SHIFT EQU 128 ;начальное смещение последовательности OUTPORT EQU 0x05 OUTPORTMASK EQU 0xF0 OUTPIN1 EQU 0 OUTPIN2 EQU 1 OUTPIN3 EQU 2 OUTPIN4 EQU 3 ; Входные параметры функции BREZEN4 TMPOUT EQU 0x21 TMPVAL1 EQU 0x22 TMPVAL2 EQU 0x23 TMPVAL3 EQU 0x24 TMPVAL4 EQU 0x25 ; Промежуточные значения для алгоритма OLDVAL1 EQU 0x26 OLDVAL2 EQU 0x27 OLDVAL3 EQU 0x28 OLDVAL4 EQU 0x29 ; Переменные для хранения контекста во время прерывания W_TEMP EQU 0x70 ; Для хранения W регистра STATUS_TEMP EQU 0x20 ;---------- ORG 0 GOTO MAIN ORG 4 INTERRUPT: MOVWF W_TEMP SWAPF STATUS,W BCF STATUS,RP0 BCF STATUS,RP1 MOVWF STATUS_TEMP ; Тело обработчика прерывания BCF INTCON,T0IF ; сбрасываем флаг прерывания SWAPF STATUS_TEMP,W MOVWF STATUS SWAPF W_TEMP,F SWAPF w_TEMP,W RETFIE INITTMR0: ; переключаем предделитель на вход TMR0 ; устанавливаем коэффициент деления CLRF TMR0 BSF STATUS,RP0 MOVLW TMR0PRESCAL MOVWF OPTION_REG ; Разрешаем прерывания CLRF INTCON BSF INTCON,T0IE BSF INTCON,GIE BCF STATUS,RP0 RETURN BREZEN4: MOVF TMPOUT,W MOVWF OUTPORT ;Отправляем значение в порт ANDLW OUTPORTMASK MOVWF TMPOUT MOVF TMPVAL1,W ADDWF OLDVAL1,F BTFSC STATUS,C BSF TMPOUT,OUTPIN1 MOVF TMPVAL2,W ADDWF OLDVAL2,F BTFSC STATUS,C BSF TMPOUT,OUTPIN2 MOVF TMPVAL3,W ADDWF OLDVAL3,F BTFSC STATUS,C BSF TMPOUT,OUTPIN3 MOVF TMPVAL4,W ADDWF OLDVAL4,F BTFSC STATUS,C BSF TMPOUT,OUTPIN4 RETURN MAIN: INIT: CLRF STATUS ; По умолчанию выбираем нулевую страницу памяти CALL INITTMR0 ; устанавливаем направление порта BSF STATUS,RP0 CLRF OUTPORT ; TRIS BCF STATUS,RP0 ; Переключаем на нулевую страницу памяти ; инициализируем переменные BREZEN4 CLRF TMPOUT MOVLW START_SHIFT MOVWF OLDVAL1 MOVWF OLDVAL2 MOVWF OLDVAL3 MOVWF OLDVAL4 ; Передаем параметры Функции MOVLW 0x30 ; Значение на первом выходе MOVWF TMPVAL1 MOVLW 0x80 MOVWF TMPVAL2 MOVLW 0xFF MOVWF TMPVAL3 MOVLW 0x01 MOVWF TMPVAL4 MAINLOOP: CALL BREZEN4 GOTO MAINLOOP
Такие осциллограммы получаем на выходах
Основная частота получилась выше, примерно 96кГц при уровне 128/256.
Частота следования импульсов изменяется от уровня к уровню, для уровня 1 в выходной последовательности появляется 1 положительный импульс, для 20 - 20.
Если генерировать последовательности по таймеру, то частота понизится, а её стабильность повысится. А неизрасходованные такты процессора можно выделить для коммутации с другими устройствами.
Есть идея передавать нужные уровни через последовательный порт с компьютера или по параллельному интерфейсу с другого микроконтроллера с LCD дисплеем и клавиатурой.
Комментариев нет:
Отправить комментарий