// Set PWM values.
// OCR1A - duty_cycle = 68; // 0 d - 1ms
// OCR1A - duty_cycle = 301; // 180 d - 2ms
// OCR1A - duty_cycle = 184; // 90 d - 1.5ms
#define TIMER1_TOP 320 /* 10-bit PWM */
#define TIMER1_BOTTOM 0 /* 10-bit PWM */
#define Servo_TOP 125 /* 10-bit PWM */
#define Servo_BOTTOM 63 /* 10-bit PWM */
#define Servo_Delay 30
#define BIT1_MASK 0x02 // 0000 0010 --> Pin 0
#define PORTB_MASK 0x25
#define DDRB_MASK 0x24
#define PINB_MASK 0x23
unsigned char *SREG_ESP;
unsigned char *portDDRB;
unsigned char *portPinB;
unsigned char *portB;
// Register Pointer Declaration
unsigned char *TCCR1A_ESP; //0x80
unsigned char *TCCR1B_ESP; //0x81
unsigned char *TCNT1H_ESP; //0x85
unsigned char *TCNT1L_ESP; //0x84
unsigned char *ICR1AH_ESP; //0x89
unsigned char *ICR1AL_ESP; //0x88
unsigned char *OCR1AH_ESP; //0x89
unsigned char *OCR1AL_ESP; //0x88
unsigned char *OCR1BH_ESP; //0x89
unsigned char *OCR1BL_ESP; //0x88
unsigned char *TIMSK1_ESP; //0x6F
void setup(){
//////////////////////////////////////////////////
// Serial Library
Serial.begin(9600); // open the serial port at 9600 bps:
//////////////////////////////////////////////////
// SREG
SREG_ESP = (unsigned char *) 0x5F;
// Assigned Register Address 
TCCR1A_ESP = (unsigned char *) 0x80;
TCCR1B_ESP = (unsigned char *) 0x81;
TCNT1H_ESP = (unsigned char *) 0x85;
TCNT1L_ESP = (unsigned char *) 0x84;
ICR1AH_ESP = (unsigned char *) 0x87;
ICR1AL_ESP = (unsigned char *) 0x86;
OCR1AH_ESP = (unsigned char *) 0x89;
OCR1AL_ESP = (unsigned char *) 0x88;
OCR1BH_ESP = (unsigned char *) 0x8B;
OCR1BL_ESP = (unsigned char *) 0x8A;
TIMSK1_ESP = (unsigned char *) 0x6F;
/* Timer 1 is 10-bit PWM (COM1A1)(WGM11)
* TCCR1A = TIMER1_PWM_INIT;
* COM1A1:0 =10 => Clear OC1A/OC1B on Compare Match when up-counting
* WGM2:0 =011 => PWM, Phase Correct, 10-bit */
*TCCR1A_ESP = 0b10000010; //
/* Start timer 1. (WGM13)(WGM12)(CS12)
* CS12:0 = 011 => clkI/O/64 (From prescaler) */
*TCCR1B_ESP = 0b00011100; //
/* Enable OC1 as output. PB1*/
portDDRB = (unsigned char *) DDRB_MASK;
*portDDRB |= BIT1_MASK; // Configure PB bit 1 as an output
portB = (unsigned char *) PORTB_MASK;
int period_1 = 1250;
*ICR1AH_ESP = ((period_1) & 0xFF00)>>8;
*ICR1AL_ESP = period_1 & 0x00FF;
/* Enable timer 1 overflow interrupt. (TOIE1)*/
*TIMSK1_ESP = 0b00000001; // enable timer compare interrupt - BIT1
// Global Interrupt Enabled
*SREG_ESP = 0x80;
}
enum { UP, DOWN };
ISR (TIMER1_OVF_vect)
{
static uint16_t duty_cycle;
static uint8_t direction;
switch (direction)
{
case UP:
if (++duty_cycle == Servo_TOP+Servo_Delay)
direction = DOWN;
break;
case DOWN:
if (--duty_cycle == Servo_BOTTOM-Servo_Delay)
direction = UP;
break;
}
*OCR1AH_ESP = ((duty_cycle) & 0xFF00)>>8;
*OCR1AL_ESP = duty_cycle & 0x00FF;
//////////////////////////////////////////////////
// Serial Library
Serial.print(duty_cycle); // print as an ASCII-encoded decimal - same as "DEC"
Serial.print("\n"); // prints two tabs to accomodate the label lenght
//////////////////////////////////////////////////
}
int main (void)
{
setup ();
/* loop forever, the interrupts are doing the rest */
for (;;) {
}
return (0);
}