This commit is contained in:
sfokin 2025-04-12 21:36:10 +03:00
parent b74b63cd3b
commit b78d822ae3

274
main.c
View File

@ -1,137 +1,139 @@
#include <xc.h> #include <xc.h>
#include <stdint.h> #include <stdint.h>
#include <pic16f676.h> #include <pic16f676.h>
// CONFIGURATION // CONFIGURATION
#pragma config FOSC = INTRCIO // Internal oscillator #pragma config FOSC = INTRCIO // Internal oscillator
#pragma config WDTE = OFF // Watchdog timer off #pragma config WDTE = OFF // Watchdog timer off
#pragma config PWRTE = ON // Power-up timer enabled #pragma config PWRTE = ON // Power-up timer enabled
#pragma config MCLRE = OFF #pragma config MCLRE = OFF
#define _XTAL_FREQ 4000000 #define _XTAL_FREQ 4000000
volatile uint8_t current_button_status = 1; volatile uint8_t current_button_status = 1;
volatile uint8_t current_mode = 0; volatile uint8_t current_mode = 0;
volatile uint8_t servo_pos = 127; // 0=1ms, 255=2ms 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 pulse_state = 0; // 0=start pulse, 1=end pulse
volatile uint8_t isincreasing = 0; volatile uint8_t isincreasing = 0;
void __interrupt() ISR(void) { void __interrupt() ISR(void) {
INTCONbits.GIE = 0; INTCONbits.GIE = 0;
if (PIR1bits.TMR1IF) { if (PIR1bits.TMR1IF) {
PIR1bits.TMR1IF = 0; // Clear interrupt flag PIR1bits.TMR1IF = 0; // Clear interrupt flag
static uint16_t off_ticks; // Retains value between interrupts T1CONbits.TMR1ON = 0;
static uint16_t timer; static uint16_t off_ticks; // Retains value between interrupts
if (pulse_state == 0) { static uint16_t timer;
// Calculate pulse parameters if (pulse_state == 0) {
uint16_t on_ticks = 75 + ((uint16_t)servo_pos * 237) / 255; // Map to 0.5ms-2.5ms // Calculate pulse parameters
off_ticks = 2500 - on_ticks; // 2500 ticks = 20ms uint16_t on_ticks = 125 + ((uint16_t)servo_pos * 125) / 255; // Map to 0.5ms-2.5ms
RC5 = 1; // Start pulse off_ticks = 2500 - on_ticks; // 2500 ticks = 20ms
timer = 65535 - on_ticks;
TMR1L = (unsigned char)(timer & 0xFF); timer = 65535 - on_ticks;
TMR1H = (unsigned char)(timer >> 8); TMR1L = (unsigned char)(timer & 0xFF);
pulse_state = 1; TMR1H = (unsigned char)(timer >> 8);
} else { RC5 = 1; // Start pulse
RC5 = 0; // End pulse pulse_state = 1;
timer = 65535 - off_ticks; } else {
TMR1L = (unsigned char)(timer & 0xFF); timer = 65535 - off_ticks;
TMR1H = (unsigned char)(timer >> 8); TMR1L = (unsigned char)(timer & 0xFF);
pulse_state = 0; TMR1H = (unsigned char)(timer >> 8);
} RC5 = 0; // End pulse
} pulse_state = 0;
INTCONbits.GIE = 1; }
} T1CONbits.TMR1ON = 1;
}
void setup() { INTCONbits.GIE = 1;
}
// Set RA1 as digital input
ANSEL = 0; void setup() {
CMCON = 0x07;
TRISC = 0x00; // Set RA1 as digital input
TRISAbits.TRISA1 = 1; ANSEL = 0;
WPUAbits.WPUA1 = 1; CMCON = 0x07;
OPTION_REGbits.nRAPU = 0; TRISC = 0x00;
TRISAbits.TRISA1 = 1;
// Configure Timer1 WPUAbits.WPUA1 = 1;
T1CON = 0b00110000; // Timer1: prescaler 1:8, internal clock, OFF OPTION_REGbits.nRAPU = 0;
TMR1H = (65536 - 188) >> 8; // Initial 1.5ms pulse (high byte)
TMR1L = (65536 - 188) & 0xFF; // Initial 1.5ms pulse (low byte) // Configure Timer1
PIR1bits.TMR1IF = 0; // Clear interrupt flag T1CON = 0b00110000; // Timer1: prescaler 1:8, internal clock, OFF
PIE1bits.TMR1IE = 1; // Enable Timer1 interrupt TMR1H = (65536 - 188) >> 8; // Initial 1.5ms pulse (high byte)
INTCONbits.PEIE = 1; // Enable peripheral interrupts TMR1L = (65536 - 188) & 0xFF; // Initial 1.5ms pulse (low byte)
INTCONbits.GIE = 1; // Enable global interrupts PIR1bits.TMR1IF = 0; // Clear interrupt flag
T1CONbits.TMR1ON = 1; PIE1bits.TMR1IE = 1; // Enable Timer1 interrupt
INTCONbits.PEIE = 1; // Enable peripheral interrupts
// Configure ADC INTCONbits.GIE = 1; // Enable global interrupts
TRISAbits.TRISA2 = 0; T1CONbits.TMR1ON = 1;
ANSELbits.ANS2 = 1;
ADCON0 = 0b00001001; // Configure ADC
ADCON1 = 0; TRISAbits.TRISA2 = 1;
} ANSELbits.ANS2 = 1;
ADCON0 = 0b00001001;
#define bool uint8_t ADCON1 = 0;
#define false 0 }
#define true 1
#define bool uint8_t
void UpdateLeds() #define false 0
{ #define true 1
RC0 = current_mode == 0;
RC1 = current_mode == 1; void UpdateLeds()
RC2 = current_mode == 2; {
} RC0 = current_mode == 0;
RC1 = current_mode == 1;
void check_button() { RC2 = current_mode == 2;
if (!RA1 && current_button_status) { }
__delay_ms(20);
if(!RA1) { void check_button() {
current_mode = (current_mode + 1) % 3; // Cycle through modes if (!RA1 && current_button_status) {
UpdateLeds(); __delay_ms(20);
} if(!RA1) {
} current_mode = (current_mode + 1) % 3; // Cycle through modes
current_button_status = RA1; UpdateLeds();
} }
}
void smooth_servo(uint8_t target_pos) { current_button_status = RA1;
// Move servo_pos towards target_pos gradually }
if (servo_pos < target_pos) {
servo_pos++; void smooth_servo(uint8_t target_pos) {
} else if (servo_pos > target_pos) { // Move servo_pos towards target_pos gradually
servo_pos--; 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; inline uint8_t read_adc() {
} ADCON0bits.GO = 1;
while(ADCON0bits.GO_DONE);
void main() { return ADRESH;
setup(); // Initialize peripherals }
UpdateLeds();
while(1) { void main() {
check_button(); // Check for button presses setup(); // Initialize peripherals
switch(current_mode) { UpdateLeds();
case 0: while(1) {
smooth_servo(read_adc()); check_button(); // Check for button presses
__delay_us(100); switch(current_mode) {
break; case 0:
case 1: smooth_servo(read_adc());
//target_pos = 511; __delay_us(100);
smooth_servo(127); break;
__delay_us(100); case 1:
break; smooth_servo(128);
case 2: __delay_us(100);
if(isincreasing) { break;
smooth_servo(servo_pos + 1); case 2:
__delay_ms(10); if(isincreasing) {
if(servo_pos + 1 >= 254) isincreasing = 0; smooth_servo(servo_pos + 1);
} else __delay_ms(10);
{ if(servo_pos + 1 >= 254) isincreasing = 0;
smooth_servo(servo_pos - 1); } else
__delay_ms(10); {
if(servo_pos - 1 <= 0) isincreasing = 1; smooth_servo(servo_pos - 1);
} __delay_ms(10);
break; if(servo_pos - 1 <= 0) isincreasing = 1;
} }
} break;
}
}
} }