Thank you for the explanation. Unfortunately, I don't think I can do much with only sixteen 64-usec steps across that 1000-us range.
#define COUNT_LOW 0
#define COUNT_HIGH 8888
#define TIMER_WIDTH 16
#include "esp32-hal-ledc.h"
void setup() {
ledcSetup(1, 50, TIMER_WIDTH); // channel 1, 50 Hz, 16-bit width
ledcAttachPin(2, 1); // GPIO 22 assigned to channel 1
}
void loop() {
for (int i=COUNT_LOW ; i < COUNT_HIGH ; i=i+100)
{
ledcWrite(1, i); // sweep servo 1
delay(50);
}
}
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP32_HAL_LEDC_H_
#define _ESP32_HAL_LEDC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
typedef enum {
NOTE_C, NOTE_Cs, NOTE_D, NOTE_Eb, NOTE_E, NOTE_F, NOTE_Fs, NOTE_G, NOTE_Gs, NOTE_A, NOTE_Bb, NOTE_B, NOTE_MAX
} note_t;
//channel 0-15 resolution 1-16bits freq limits depend on resolution
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits);
void ledcWrite(uint8_t channel, uint32_t duty);
double ledcWriteTone(uint8_t channel, double freq);
double ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
uint32_t ledcRead(uint8_t channel);
double ledcReadFreq(uint8_t channel);
void ledcAttachPin(uint8_t pin, uint8_t channel);
void ledcDetachPin(uint8_t pin);
#ifdef __cplusplus
}
#endif
#endif /* _ESP32_HAL_LEDC_H_ */
Yeah, that's why I said "libraries" - but at 240MHz, a little overhead can be tolerated.LOL here a sample
Code:#define COUNT_LOW 0 #define COUNT_HIGH 8888 #define TIMER_WIDTH 16 #include "esp32-hal-ledc.h" void setup() { ledcSetup(1, 50, TIMER_WIDTH); // channel 1, 50 Hz, 16-bit width ledcAttachPin(2, 1); // GPIO 22 assigned to channel 1 } void loop() { for (int i=COUNT_LOW ; i < COUNT_HIGH ; i=i+100) { ledcWrite(1, i); // sweep servo 1 delay(50); } }
What is wrong with you?Do you constantly need some kind of validation? If you think everything in life is a competition, professional help is available and happiness is possible. Keep your local suicide prevention hotline number available - the holidays are difficult for people with your symptoms.
Mike.. Its done with! We'll keep it civil...What is wrong with you?
or any of the pwm pins.library disables analogWrite() (PWM) functionality on pins 9 and 10
I believe I was civil.Mike.. Its done with! We'll keep it civil...
#include "p16f15323.inc"
; Config BITS
;#######################################################################################################################
;#######################################################################################################################
__CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _FCMEN_ON
__CONFIG _CONFIG2, _MCLRE_OFF & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON
__CONFIG _CONFIG3, _WDTCPS_WDTCPS_31 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_SC
__CONFIG _CONFIG4, _BBSIZE_BB512 & _BBEN_OFF & _SAFEN_OFF & _WRTAPP_OFF & _WRTB_OFF & _WRTC_OFF & _WRTSAF_OFF & _LVP_ON
__CONFIG _CONFIG5, _CP_ON
; Servo I/O Pin definitions
;#######################################################################################################################
;#######################################################################################################################
#define Servo_0 LATC, RC0
#define Servo_1 LATC, RC1
#define Servo_2 LATC, RC2
#define Servo_3 LATC, RC3
#define Servo_4 LATC, RC4
#define Servo_5 LATC, RC5
#define Servo_6 LATA, RA0
#define Servo_7 LATA, RA1
; Variable Definitions
;#######################################################################################################################
;#######################################################################################################################
ServoIndex equ h'40'
ServoTempH equ h'41'
ServoTempL equ h'42'
; Interrupt and Program Vector
;#######################################################################################################################
;#######################################################################################################################
RES_VECT CODE 0x0000 ; processor reset vector
GOTO Initial_START ; go to beginning of program
ISR CODE 0x0004 ; interrupt vector location
; <Search the device datasheet for 'context' and copy interrupt
; context saving code here. Older devices need context saving code,
; but newer devices like the 16F#### don't need context saving code.>
;
; START Interrupt Program
;#######################################################################################################################
;#######################################################################################################################
banksel PIR6
btfss PIR6, 0
goto PeriodInterval
PulseInterval:
banksel PIR6
bcf PIR6, 0
banksel ServoIndex
movf ServoIndex,W
banksel PCL
addwf PCL,F
goto Handle_SERVO_OFF_0
goto Handle_SERVO_OFF_1
goto Handle_SERVO_OFF_2
goto Handle_SERVO_OFF_3
goto Handle_SERVO_OFF_4
goto Handle_SERVO_OFF_5
goto Handle_SERVO_OFF_6
goto Handle_SERVO_OFF_7
Handle_SERVO_OFF_0:
banksel LATC
bcf Servo_0
Handle_SERVO_OFF_1:
banksel LATC
bcf Servo_1
Handle_SERVO_OFF_2:
banksel LATC
bcf Servo_2
Handle_SERVO_OFF_3:
banksel LATC
bcf Servo_3
Handle_SERVO_OFF_4:
banksel LATC
bcf Servo_4
Handle_SERVO_OFF_5:
banksel LATC
bcf Servo_5
Handle_SERVO_OFF_6:
banksel LATA
bcf Servo_6
Handle_SERVO_OFF_7:
banksel LATA
bcf Servo_7
goto Interrupt_Done ; Should never reach this line
PeriodInterval:
banksel PIR4
btfss PIR4, 0
goto Interrupt_Done
bcf PIR4, 0
banksel T1CON ; Dissable Timer 1
bcf T1CON, 0
banksel TMR1H ; Reset Timer 1 Period Value
movlw HIGH TMR1_Period_value
movwf TMR1H
banksel TMR1L
movlw LOW TMR1_Period_value
movwf TMR1L
banksel T1CON ; Enable Timer 1
bsf T1CON, 0
;...............................................................................
banksel ServoIndex ; Increment ServoIndex and keep range from 0 to 7
incf ServoIndex,W
andlw b'00000111'
movwf ServoIndex
banksel ServoIndex
movf ServoIndex,W
banksel PCL
addwf PCL,F
goto Handle_SERVO_ON_0
goto Handle_SERVO_ON_1
goto Handle_SERVO_ON_2
goto Handle_SERVO_ON_3
goto Handle_SERVO_ON_4
goto Handle_SERVO_ON_5
goto Handle_SERVO_ON_6
goto Handle_SERVO_ON_7
Handle_SERVO_ON_0:
banksel LATC ; Set Servo 0 I/O HIGH
bsf Servo_0
movlw HIGH Servo0_value ; Load Servo 0 Time ON Data
banksel ServoTempH
movwf ServoTempH
movlw LOW Servo0_value
banksel ServoTempL
movwf ServoTempL
call Process_Data
goto Interrupt_Done
Handle_SERVO_ON_1:
banksel LATC ; Set Servo 1 I/O HIGH
bsf Servo_1
movlw HIGH Servo1_value ; Load Servo 1 Time ON Data
banksel ServoTempH
movwf ServoTempH
movlw LOW Servo1_value
banksel ServoTempL
movwf ServoTempL
call Process_Data
goto Interrupt_Done
Handle_SERVO_ON_2:
banksel LATC ; Set Servo 2 I/O HIGH
bsf Servo_2
movlw HIGH Servo2_value ; Load Servo 2 Time ON Data
banksel ServoTempH
movwf ServoTempH
movlw LOW Servo2_value
banksel ServoTempL
movwf ServoTempL
call Process_Data
goto Interrupt_Done
Handle_SERVO_ON_3:
banksel LATC ; Set Servo 3 I/O HIGH
bsf Servo_3
movlw HIGH Servo3_value ; Load Servo 3 Time ON Data
banksel ServoTempH
movwf ServoTempH
movlw LOW Servo3_value
banksel ServoTempL
movwf ServoTempL
call Process_Data
goto Interrupt_Done
Handle_SERVO_ON_4:
banksel LATC ; Set Servo 4 I/O HIGH
bsf Servo_4
movlw HIGH Servo4_value ; Load Servo 4 Time ON Data
banksel ServoTempH
movwf ServoTempH
movlw LOW Servo4_value
banksel ServoTempL
movwf ServoTempL
call Process_Data
goto Interrupt_Done
Handle_SERVO_ON_5:
banksel LATC ; Set Servo 5 I/O HIGH
bsf Servo_5
movlw HIGH Servo5_value ; Load Servo 5 Time ON Data
banksel ServoTempH
movwf ServoTempH
movlw LOW Servo5_value
banksel ServoTempL
movwf ServoTempL
call Process_Data
goto Interrupt_Done
Handle_SERVO_ON_6:
banksel LATA ; Set Servo 6 I/O HIGH
bsf Servo_6
movlw HIGH Servo6_value ; Load Servo 6 Time ON Data
banksel ServoTempH
movwf ServoTempH
movlw LOW Servo6_value
banksel ServoTempL
movwf ServoTempL
call Process_Data
goto Interrupt_Done
Handle_SERVO_ON_7:
banksel LATA ; Set Servo 7 I/O HIGH
bsf Servo_7
movlw HIGH Servo7_value ; Load Servo 7 Time ON Data
banksel ServoTempH
movwf ServoTempH
movlw LOW Servo7_value
banksel ServoTempL
movwf ServoTempL
call Process_Data
goto Interrupt_Done
;banksel CCPR1H ; Set Compare 1 Value
;movlw h'00'
;movwf CCPR1H
;banksel CCPR1L
;movlw h'00'
;movwf CCPR1L
Interrupt_Done:
RETFIE
Process_Data:
banksel ServoTempL ; Multiply Servo Time by 8
rlf ServoTempL,F
banksel ServoTempH ; Note: your mileage may vary here...
rlf ServoTempH,F ; I used a processor running at 32MHz.
banksel ServoTempL ; That means that the instruction time was 125ns
rlf ServoTempL,F ; To get 1 micro second Resolution I multiplied
banksel ServoTempH ; 125ns by 8 which equals 1 micro second.
rlf ServoTempH,F ; So a processor running at 8MHz could still
banksel ServoTempL ; achieve a 1 microsecond resolution by omitting
rlf ServoTempL,F ; this section.
banksel ServoTempH
rlf ServoTempH,F
banksel ServoTempL
movf ServoTempL,W
andlw b'11111000'
movwf ServoTempL
movlw LOW TMR1_Period_value ; Add TMR1_Period_value to ServoTemp
banksel ServoTempL
addwf ServoTempL,F
btfsc STATUS,C
banksel ServoTempH
incf ServoTempH,F
movlw HIGH TMR1_Period_value
banksel ServoTempH
addwf ServoTempH,F
banksel ServoTempL ; Set Compare Value
movf ServoTempL,W
banksel CCPR1L
movwf CCPR1L
banksel ServoTempH
movf ServoTempH,W
banksel CCPR1H
movwf CCPR1H
return
MAIN_PROG CODE ; let linker place main program
Initial_START:
; START Main Program Initialization - Define PORTs
;#######################################################################################################################
;#######################################################################################################################
banksel LATA ; Preset PORTA to all LOW
clrf LATA
banksel TRISA
movlw b'11111100'
movwf TRISA ; DEFINE ALL pins as INPUT
banksel LATC ; Preset PORTA to all LOW
clrf LATC
banksel TRISC
movlw b'11000000'
movwf TRISC ; DEFINE RC0 to RC5 as OUTPUT
; START Main Program Initialization - Define Analog vs Digital operation Mode
;#######################################################################################################################
;#######################################################################################################################
banksel ANSELA
movlw b'00000000'
; XX...... Unimplemented
; ..XX.... RA5 RA4 anaolg or digital select
; ....X... Unimplemented
; .....XXX RA2 RA1 RA0 anaolg or digital select
movwf ANSELA
banksel ANSELC
movlw b'00000000'
; XX...... Unimplemented
; ..XXXXXX RC5 RC0 anaolg or digital select
movwf ANSELC
; TIMER and Interrupt Setup
;#######################################################################################################################
;#######################################################################################################################
banksel INTCON
movlw b'11000000' ;DEBUG DISABLE
; X....... Global Interrupt Enable
; .X...... Peripheral Interrupt Enable
; ..XXXXX. Unimplemented
; .......X Interrupt Edge Select
movwf INTCON
banksel T1CON
movlw b'00000011'
; XX...... Unimplemented: Read as '0'
; ..XX.... CKPS<1:0>: Timer1 Input Clock Prescale Select bits
; ....X... Unimplemented: Read as '0'
; .....X.. SYNC: Timer1 Synchronization Control bit
; ......X. RD16: 16-bit Read/Write Mode Enable bit
; .......X ON: Timer1 On bit
movwf T1CON
banksel T1CLK
movlw b'00000001'
; XXXX.... Unimplemented: Read as '0'
; ....XXXX CS<3:0>: Timer1 Clock Select bits
movwf T1CLK
banksel PIE4
movlw b'00000001'
; XXXXXX.. Unimplemented: Read as '0'
; ......X. TMR2 to PR2 Match Interrupt Enable
; .......X Timer1 Interrupt Enable
movwf PIE4
; Compare Setup
;#######################################################################################################################
;#######################################################################################################################
banksel CCP1CON
movlw b'10000010'
; X....... EN: CCPx Module Enable bit
; .X...... Unimplemented: Read as '0'
; ..X..... OUT: CCPx Output Data bit (read-only)
; ...X.... FMT: CCPW (Pulse Width) Alignment bit
; ....XXXX MODE<3:0>: CCPx Mode Select bits(1)
movwf CCP1CON
banksel PIE6
movlw b'00000001'
; XXXXXX.. Unimplemented: Read as '0'
; ......X. CCP2IE: CCP2 Interrupt Enable bit
; .......X CCP1IE: CCP1 Interrupt Enable bit
movwf PIE6
; How to set Period interval
;#######################################################################################################################
;#######################################################################################################################
; TMR1_Period_value = 65535 - ( ( Period * Fosc/4 ) / PreScale )
;
; Period ... Normal 20ms Period for ONE channel is 0.02 ... divide .02 by 8 for 8 Channels to obtain 0.0025 Period Value
;
; TMR1_Period_value = 65535 - ( ( 0.0025 * 32000000/4 ) / 1 )
;
; TMR1_Period_value = 65535 - ( ( 0.0025 * 8000000 ) / 1 )
;
; TMR1_Period_value = 65535 - ( 20000 / 1 )
;
; TMR1_Period_value = 45535
TMR1_Period_value equ d'45535'
; Note: Due to overhead requirements, running at 32MHz, the shortest pulse is 133 us and the longest pulse is 2495 us
Servo0_value equ d'500' ;micro seconds
Servo1_value equ d'787' ;micro seconds
Servo2_value equ d'1071' ;micro seconds
Servo3_value equ d'1357' ;micro seconds
Servo4_value equ d'1643' ;micro seconds
Servo5_value equ d'1929' ;micro seconds
Servo6_value equ d'2214' ;micro seconds
Servo7_value equ d'2495' ;micro seconds <--- Note cannot exceed Period Value PLUS some overhead
Main_Program:
; START Main Program
;#######################################################################################################################
;#######################################################################################################################
GOTO Main_Program
END
; START Interrupt Program
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
banksel PIR6 ; bank 14 |14
btfss PIR6,CCP1IF ; match irq? yes, skip, else |14
goto PeriodInterval ; branch (check TMR1IF) |14
PulseInterval:
bcf PIR6,CCP1IF ; clear the interrupt flag and |14
banksel LATC ; bank 00 |00
clrf LATC ; turn servo output off |00
goto Interrupt_done ; |00
;WAS
movlw LOW TMR1_Period_value ; Add TMR1_Period_value to ServoTemp
banksel ServoTempL
addwf ServoTempL,F
btfsc STATUS,C
banksel ServoTempH
incf ServoTempH,F
movlw HIGH TMR1_Period_value
banksel ServoTempH
addwf ServoTempH,F
;SHOULD BE
movlw LOW TMR1_Period_value ; Add TMR1_Period_value to ServoTemp
banksel ServoTempL
addwf ServoTempL,F
banksel ServoTempH
btfsc STATUS,C
incf ServoTempH,F
movlw HIGH TMR1_Period_value
banksel ServoTempH
addwf ServoTempH,F
The link I posted in post #5 is to an 11 year old thread.We went to this rodeo over a decade ago:
If we are going to discuss how old we've gotten Mike - K8LH and I started talking about this in September 2007. Over 13 years ago.The link I posted in post #5 is to an 11 year old thread.
/*
* Author: DAN1138
* Date: 2020-JAN-3
* File: main.c
* Target: PIC16F877A
* OS: Win7 Pro, 64-bit
* IDE: MPLABX v5.25
* Compiler: XC8 1.45 (free)
*
* Application: Use PWM to drive one RC servo from analog voltage present on AN0
*
* RA0 - Analog ADC input from potentiometer
*
* RC2 - CCP1, pulse output for servos
*/
/* Set up the configuration bits */
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#include <xc.h>
/*
* 4MHz crystal
* FOSC set for 4MHz
*/
#define FOSC 4000000L /* target device system clock freqency */
#define FCYC (FOSC/4L) /* target device instruction clock freqency */
#define _XTAL_FREQ FOSC /* required for HITECH PICC delay macros */
#define NUMBER_OF_SERVOS 1
#define SERVO1_INDEX 0
/*
* These defines are used to configure this application for your needs.
*
* FCYC
* TMR2_PRESCALE
* PWM_MAX
* NUMBER_OF_SERVOS
*
* The default values are tuned for a 8MHz instruction clock and eight servos.
*
* After each servo has completed its pulse we need to take one
* PWM period to update the servo multiplexor.
*
* You need to make sure that time period for updating all the servos
* pulse an extra PWM period for each servo is less than 20 milliseconds.
*
* Making PWM_MAX smaller will make the extra PWM period for each servo shorter.
* The tradeoff is that we get interrupted more often to service TMR2.
*
*/
/*
* PWM_MAX must be >= 1 and <= 255.
* small values (< 100) will cause the TMR2 interrupt
* to occur so often they are kind of useless.
*
*/
#define TMR2_PRESCALE 4L
#define PWM_MAX (250L)
#define TCYC_ns (1000000000L / FCYC)
#define PWM_PERIOD_us ((TCYC_ns * TMR2_PRESCALE * PWM_MAX) / 1000L)
/*
* The update rate for our servos is 20.000 milliseconds. (50Hz)
* So this sets the number of PWM ticks in 20,000 microseconds
* SERVO_UPDATE_IN_PWM_PERIODS must be <= 65535 to fit into an unsigned int.
*
*/
#define SERVO_UPDATE_IN_PWM_PERIODS ((20000L + (PWM_PERIOD_us / 2L)) / PWM_PERIOD_us)
/*
* Position min and max are 16-bit unsigned values
*
* Define the limits for a particular servo
* The servo rotates to the "left" limit for a pulse of 0.500 milliseconds.
* The servo rotates to the "right" limit for a pulse of 2.000 milliseconds.
*
*/
#define POSITION_MIN ((500L * (PWM_MAX * 4)) / PWM_PERIOD_us)
#define POSITION_MAX ((2000L * (PWM_MAX * 4)) / PWM_PERIOD_us)
void init (void);
void update_position(unsigned int *servo_period,unsigned char *dir, unsigned int delta);
/*
* Timer 2 interrupt handler
*
* This handler updates PWM one for a typical
* pulse output to control a common analog
* model radio control servo.
*
*/
unsigned int servo_bank_one[NUMBER_OF_SERVOS];
unsigned int update_tick_count;
struct {
unsigned char updated:1;
unsigned char one_complete:1;
unsigned char select_next:1;
unsigned char select;
} servo;
unsigned char IsServoUpdateComplete(void)
{
if (servo.updated)
{
return 1;
}
else
{
return 0;
}
}
void ResetServoUpdateComplete(void)
{
servo.updated = 0;
}
void SetServoPosition(unsigned char servo_number, unsigned int servo_position)
{
if (servo_number < NUMBER_OF_SERVOS)
{
/* Do not allow PWM interrupts while */
/* updating servo position array. */
/* Start critical section. */
PIE1bits.TMR2IE = 0;
servo_bank_one[servo_number] = servo_position;
PIE1bits.TMR2IE = 1;
/* End critical section. */
}
}
void TMR2_handler(void)
{
static unsigned int temp_period_one;
if (PIE1bits.TMR2IE) /* test if T2 interrupt is enabled */
{
if (PIR1bits.TMR2IF) /* test if T2 interrupt is asserted */
{
PIR1bits.TMR2IF = 0; /* reset T2 assertion */
if(servo.select_next)
{
servo.select_next = 0;
if (++servo.select < NUMBER_OF_SERVOS)
{
temp_period_one = servo_bank_one[servo.select];
}
else
{
servo.select = 0;
}
}
if (servo.one_complete)
{
servo.one_complete = 0;
servo.select_next = 1;
}
if (update_tick_count == 0)
{
update_tick_count = SERVO_UPDATE_IN_PWM_PERIODS;
temp_period_one = servo_bank_one[0];
servo.updated = 1;
}
--update_tick_count;
CCP1CONbits.CCP1Y = 0;
CCP1CONbits.CCP1X = 0;
if (temp_period_one > (PWM_MAX * 4))
{
CCPR1L = PWM_MAX;
temp_period_one -= (PWM_MAX * 4);
}
else
{
if (temp_period_one != 0)
{
servo.one_complete = 1;
if (temp_period_one & 0b00000001)
{
CCP1CONbits.CCP1Y = 1;
}
if (temp_period_one & 0b00000010)
{
CCP1CONbits.CCP1X = 1;
}
temp_period_one >>= 2;
CCPR1L = (unsigned char)(temp_period_one);
temp_period_one = 0;
}
else
{
CCPR1L = 0;
}
}
}
}
}
/* initialize the PWM and interrupt on T2 overflow */
void TMR2_init(void)
{
PIE1bits.TMR2IE = 0; /* turn off TMR2 interrupt */
TRISC &= (0b11111011); /* make RC2 output for PWM */
#if (TMR2_PRESCALE == 1)
T2CON = 0b00000000; /* postscaler 1:1 */
/* TMR2 off */
/* prescaler 1:1 */
#endif
#if (TMR2_PRESCALE == 4)
T2CON = 0b00000001; /* postscaler 1:1 */
/* TMR2 off */
/* prescaler 1:4 */
#endif
#if (TMR2_PRESCALE == 16)
T2CON = 0b00000010; /* postscaler 1:1 */
/* TMR2 off */
/* prescaler 1:16 */
#endif
TMR2 = 0;
PR2 = PWM_MAX-1; /* set PWM period */
CCP1CON = 0b00001100; /* PWM mode */
CCPR1L = 0;
update_tick_count = 0;
servo.updated = 0;
servo.select_next = 0;
for (servo.select=0; servo.select < NUMBER_OF_SERVOS; ++servo.select)
{
servo_bank_one[servo.select] = POSITION_MAX;
}
servo.select=0;
T2CONbits.TMR2ON = 1; /* turn on TMR2 */
PIE1bits.TMR2IE = 1; /* turn on TMR2 interrupt */
}
/*----------------------------------------------*/
/* interrupt handlers */
/*----------------------------------------------*/
void interrupt Interrupt_Handlers(void)
{
TMR2_handler();
}
/*----------------------------------------------*/
/* Initialize this PIC */
/*----------------------------------------------*/
void init (void)
{
/* disable all interrupt sources */
INTCON = 0x00;
PIE1 = 0x00;
PIE2 = 0x00;
ADCON0 = 0xC1; /* turn on ADC module */
/* TAD = ADCRC */
/* Select AN0 as input */
ADCON1 = 0x8E; /* set port A AN0 for analog input all others for digital I/O */
/* ADC results are right justified */
OPTION_REG = 0b11011110;/* PORTB weak pull ups disabled */
/* Interrupt on rising edge of RB0/INT pin */
/* T0 internal clock source */
/* T0 clock edge high-to-low */
/* Prescaler assigned to WDT */
/* Prescale 1:64 for WDT */
/* initialize my interrupt handlers */
TMR2_init();
/* turn on the interrupt system */
PEIE = 1;
GIE = 1;
}
/*----------------------------------------------*/
/* Main application */
/*----------------------------------------------*/
#define SERVO_UPDATES_PER_SECOND 50
#define ADC_MAX_VALUE 1023L
#define SW2 PORTAbits.RA4
#define SW3 PORTAbits.RA5
void main (void)
{
unsigned int servo_one;
unsigned long PotPosition;
unsigned long increment;
unsigned char Pause;
init();
/*
* This is a simple servo movement test that
* sets the position servo based on the analog
* voltage present on AN0.
*/
/* initial servo position at mid range */
servo_one = ((POSITION_MAX - POSITION_MIN) / 2) + POSITION_MIN;
increment = 0;
Pause = 0;
while(1)
{
if (IsServoUpdateComplete())
{
SetServoPosition(SERVO1_INDEX,servo_one);
ResetServoUpdateComplete();
if(SW2 && SW3)
{
ADCON0bits.GO = 1;
while(ADCON0bits.GO) continue;
PotPosition = ADRESH;
PotPosition = PotPosition << 8;
PotPosition = PotPosition | ADRESL;
servo_one = (unsigned int)( (((ADC_MAX_VALUE - PotPosition) * (POSITION_MAX - POSITION_MIN)) / ADC_MAX_VALUE) + POSITION_MIN );
}
else
{
if(!SW2 && SW3)
{
if (Pause == 0)
{
servo_one = (unsigned int)( ((increment * (POSITION_MAX - POSITION_MIN)) / ADC_MAX_VALUE) + POSITION_MIN );
Pause = SERVO_UPDATES_PER_SECOND / 50;
increment++;
if (increment > ADC_MAX_VALUE)
{
increment = 0;
}
}
else
{
Pause--;
}
}
else
{
if(SW2 && !SW3)
{
servo_one = ((POSITION_MAX - POSITION_MIN) / 2) + POSITION_MIN;
}
}
}
}
}
}
Didn't think it was a competition.If we are going to discuss how old we've gotten Mike
Right, not a competition ... an exhibition! Please no wagering.Didn't think it was a competition.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?