From b78d822ae3af3db5ad9370114557aba72bad8089 Mon Sep 17 00:00:00 2001 From: sfokin Date: Sat, 12 Apr 2025 21:36:10 +0300 Subject: [PATCH] fix adc --- main.c | 274 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 138 insertions(+), 136 deletions(-) diff --git a/main.c b/main.c index fc5e913..aa716b9 100644 --- a/main.c +++ b/main.c @@ -1,137 +1,139 @@ -#include -#include -#include - -// CONFIGURATION -#pragma config FOSC = INTRCIO // Internal oscillator -#pragma config WDTE = OFF // Watchdog timer off -#pragma config PWRTE = ON // Power-up timer enabled -#pragma config MCLRE = OFF -#define _XTAL_FREQ 4000000 - -volatile uint8_t current_button_status = 1; -volatile uint8_t current_mode = 0; -volatile uint8_t servo_pos = 127; // 0=1ms, 255=2ms -volatile uint8_t pulse_state = 0; // 0=start pulse, 1=end pulse -volatile uint8_t isincreasing = 0; - -void __interrupt() ISR(void) { - INTCONbits.GIE = 0; - if (PIR1bits.TMR1IF) { - PIR1bits.TMR1IF = 0; // Clear interrupt flag - static uint16_t off_ticks; // Retains value between interrupts - static uint16_t timer; - if (pulse_state == 0) { - // Calculate pulse parameters - uint16_t on_ticks = 75 + ((uint16_t)servo_pos * 237) / 255; // Map to 0.5ms-2.5ms - off_ticks = 2500 - on_ticks; // 2500 ticks = 20ms - RC5 = 1; // Start pulse - timer = 65535 - on_ticks; - TMR1L = (unsigned char)(timer & 0xFF); - TMR1H = (unsigned char)(timer >> 8); - pulse_state = 1; - } else { - RC5 = 0; // End pulse - timer = 65535 - off_ticks; - TMR1L = (unsigned char)(timer & 0xFF); - TMR1H = (unsigned char)(timer >> 8); - pulse_state = 0; - } - } - INTCONbits.GIE = 1; -} - -void setup() { - - // Set RA1 as digital input - ANSEL = 0; - CMCON = 0x07; - TRISC = 0x00; - TRISAbits.TRISA1 = 1; - WPUAbits.WPUA1 = 1; - OPTION_REGbits.nRAPU = 0; - - // Configure Timer1 - T1CON = 0b00110000; // Timer1: prescaler 1:8, internal clock, OFF - TMR1H = (65536 - 188) >> 8; // Initial 1.5ms pulse (high byte) - TMR1L = (65536 - 188) & 0xFF; // Initial 1.5ms pulse (low byte) - PIR1bits.TMR1IF = 0; // Clear interrupt flag - PIE1bits.TMR1IE = 1; // Enable Timer1 interrupt - INTCONbits.PEIE = 1; // Enable peripheral interrupts - INTCONbits.GIE = 1; // Enable global interrupts - T1CONbits.TMR1ON = 1; - - // Configure ADC - TRISAbits.TRISA2 = 0; - ANSELbits.ANS2 = 1; - ADCON0 = 0b00001001; - ADCON1 = 0; -} - -#define bool uint8_t -#define false 0 -#define true 1 - -void UpdateLeds() -{ - RC0 = current_mode == 0; - RC1 = current_mode == 1; - RC2 = current_mode == 2; -} - -void check_button() { - if (!RA1 && current_button_status) { - __delay_ms(20); - if(!RA1) { - current_mode = (current_mode + 1) % 3; // Cycle through modes - UpdateLeds(); - } - } - current_button_status = RA1; -} - -void smooth_servo(uint8_t target_pos) { - // Move servo_pos towards target_pos gradually - if (servo_pos < target_pos) { - servo_pos++; - } else if (servo_pos > target_pos) { - servo_pos--; - } -} - -inline uint8_t read_adc() { - ADCON0bits.GO = 1; - while(ADCON0bits.GO_DONE); - return ADRESH; -} - -void main() { - setup(); // Initialize peripherals - UpdateLeds(); - while(1) { - check_button(); // Check for button presses - switch(current_mode) { - case 0: - smooth_servo(read_adc()); - __delay_us(100); - break; - case 1: - //target_pos = 511; - smooth_servo(127); - __delay_us(100); - break; - case 2: - if(isincreasing) { - smooth_servo(servo_pos + 1); - __delay_ms(10); - if(servo_pos + 1 >= 254) isincreasing = 0; - } else - { - smooth_servo(servo_pos - 1); - __delay_ms(10); - if(servo_pos - 1 <= 0) isincreasing = 1; - } - break; - } - } +#include +#include +#include + +// CONFIGURATION +#pragma config FOSC = INTRCIO // Internal oscillator +#pragma config WDTE = OFF // Watchdog timer off +#pragma config PWRTE = ON // Power-up timer enabled +#pragma config MCLRE = OFF +#define _XTAL_FREQ 4000000 + +volatile uint8_t current_button_status = 1; +volatile uint8_t current_mode = 0; +volatile uint8_t servo_pos = 127; // 0=1ms, 255=2ms +volatile uint8_t pulse_state = 0; // 0=start pulse, 1=end pulse +volatile uint8_t isincreasing = 0; + +void __interrupt() ISR(void) { + INTCONbits.GIE = 0; + if (PIR1bits.TMR1IF) { + PIR1bits.TMR1IF = 0; // Clear interrupt flag + T1CONbits.TMR1ON = 0; + static uint16_t off_ticks; // Retains value between interrupts + static uint16_t timer; + if (pulse_state == 0) { + // Calculate pulse parameters + uint16_t on_ticks = 125 + ((uint16_t)servo_pos * 125) / 255; // Map to 0.5ms-2.5ms + off_ticks = 2500 - on_ticks; // 2500 ticks = 20ms + + timer = 65535 - on_ticks; + TMR1L = (unsigned char)(timer & 0xFF); + TMR1H = (unsigned char)(timer >> 8); + RC5 = 1; // Start pulse + pulse_state = 1; + } else { + timer = 65535 - off_ticks; + TMR1L = (unsigned char)(timer & 0xFF); + TMR1H = (unsigned char)(timer >> 8); + RC5 = 0; // End pulse + pulse_state = 0; + } + T1CONbits.TMR1ON = 1; + } + INTCONbits.GIE = 1; +} + +void setup() { + + // Set RA1 as digital input + ANSEL = 0; + CMCON = 0x07; + TRISC = 0x00; + TRISAbits.TRISA1 = 1; + WPUAbits.WPUA1 = 1; + OPTION_REGbits.nRAPU = 0; + + // Configure Timer1 + T1CON = 0b00110000; // Timer1: prescaler 1:8, internal clock, OFF + TMR1H = (65536 - 188) >> 8; // Initial 1.5ms pulse (high byte) + TMR1L = (65536 - 188) & 0xFF; // Initial 1.5ms pulse (low byte) + PIR1bits.TMR1IF = 0; // Clear interrupt flag + PIE1bits.TMR1IE = 1; // Enable Timer1 interrupt + INTCONbits.PEIE = 1; // Enable peripheral interrupts + INTCONbits.GIE = 1; // Enable global interrupts + T1CONbits.TMR1ON = 1; + + // Configure ADC + TRISAbits.TRISA2 = 1; + ANSELbits.ANS2 = 1; + ADCON0 = 0b00001001; + ADCON1 = 0; +} + +#define bool uint8_t +#define false 0 +#define true 1 + +void UpdateLeds() +{ + RC0 = current_mode == 0; + RC1 = current_mode == 1; + RC2 = current_mode == 2; +} + +void check_button() { + if (!RA1 && current_button_status) { + __delay_ms(20); + if(!RA1) { + current_mode = (current_mode + 1) % 3; // Cycle through modes + UpdateLeds(); + } + } + current_button_status = RA1; +} + +void smooth_servo(uint8_t target_pos) { + // Move servo_pos towards target_pos gradually + if (servo_pos < target_pos) { + servo_pos++; + } else if (servo_pos > target_pos) { + servo_pos--; + } +} + +inline uint8_t read_adc() { + ADCON0bits.GO = 1; + while(ADCON0bits.GO_DONE); + return ADRESH; +} + +void main() { + setup(); // Initialize peripherals + UpdateLeds(); + while(1) { + check_button(); // Check for button presses + switch(current_mode) { + case 0: + smooth_servo(read_adc()); + __delay_us(100); + break; + case 1: + smooth_servo(128); + __delay_us(100); + break; + case 2: + if(isincreasing) { + smooth_servo(servo_pos + 1); + __delay_ms(10); + if(servo_pos + 1 >= 254) isincreasing = 0; + } else + { + smooth_servo(servo_pos - 1); + __delay_ms(10); + if(servo_pos - 1 <= 0) isincreasing = 1; + } + break; + } + } } \ No newline at end of file