/* * File: pwm_fan_controler * Author: www.henteko.org * * Created on 2021/05/23, 11:48 */ #include #pragma config FOSC = INTOSCIO #pragma config WDTE = OFF #pragma config FCMEN = OFF #pragma config PWRTE = ON #pragma config CP = OFF #pragma config CPD = OFF #pragma config BOREN = ON #pragma config MCLRE = OFF #define _XTAL_FREQ 8000000 void delay_ms(unsigned int t) { for(; t > 0; t--) __delay_ms(1); } unsigned int get_adc(unsigned char ch) { ADCON0bits.ADFM = 1; // padding right ADCON0bits.VCFG = 0; // VREF=VDD ADCON0bits.CHS = ch; // ADC channel ADCON0bits.GO_nDONE = 0; // ADC GO/^DONE ADCON0bits.ADON = 1; // ADC Enable __delay_us(25); GO = 1; while(GO); return (ADRESH << 8) + ADRESL; } void set_duty(unsigned int duty) { CCPR1L = duty >> 2; CCP1CONbits.DC1B = duty & 0b00000011; } void main(void) { unsigned int duty; OSCCON = 0b1110000; // clock 8MHz ANSEL = 0b1011000; // ADC Fosc/16. AN3 analog CMCON0 = 0b00000111; // comparator off TRISIO = 0b00010000; // GP4 input CCP1CON= 0b00001100; // PWM mode T2CONbits.T2CKPS = 00; // prescaler 1/1 8000000/4=0.5us T2CONbits.TMR2ON = 1; // tmr2 on PR2 = 124; // PWM frequency 0.5us * (124 + 1) = 62.5us = 16kHz TMR2 = 0; // tmr2 set_duty(1023); delay_ms(2000); while(1) { duty = get_adc(3); set_duty(duty / 2); } }