nerdegutta.no
PIC16F628A - Move a servo motor 45 degrees
29.12.24
Embedded
These lines of code moves a servomotor 45 degrees and back. We're not using any timers, but make the PWM signal manual with a for-loop.
// INCLUDE LIBRARIES #include < xc.h > // CONFIGURATION BITS #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = ON // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR) #pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD enabled) #pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has PGM function, low-voltage programming enabled) #pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // DEFINITIONS #define _XTAL_FREQ 4000000 #define servo PORTBbits.RB0 // VARIABLES // PROTOTYPES // FUNCTIONS // Servo Initialization function void Servo_Init(void) { servo = 0; // Ensure the pin starts low } // Function to create a precise delay in microseconds void Delay_us(unsigned int us) { while (us--) { __delay_us(1); } } // Function to set servo angle void Set_Servo_Angle(unsigned char angle) { unsigned int pulse_width; // Calculate pulse width (1ms to 2ms for 0 to 180 degrees) pulse_width = (unsigned int)((angle * 20 / 180) + 5); // Generate PWM signal manually for (unsigned char i = 0; i < 50; i++) { // 50 cycles for 20ms period servo = 1; // Set pin high Delay_us(pulse_width * 10); // Delay for high period servo = 0; // Set pin low Delay_us((20 - pulse_width) * 100); // Delay for low period } } void main() { TRISBbits.TRISB0 = 0; // Configure PORTB.RB0 as output Servo_Init(); // Initialize Servo control while (1) { Set_Servo_Angle(0); // Set servo to 0 degrees __delay_ms(500); // Wait for 0.5 second Set_Servo_Angle(45); // Set servo to 45 degrees __delay_ms(500); // Wait for 0.5 second } }