// //////////////////////////////////////////////
// ESP (CS 33301-001)
// Project 3.2: PWM - Servo Motor Control
// Phase Correct PWM – 10 bit w/ SW
// using Serial Library
// Kent State University
// Dept. of Computer Science
// Jungyoon Kim, Ph.D.
//
//Project done by Ean Dodge
// //////////////////////////////////////////////
// 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 301 /* 10-bit PWM */
#define Servo_BOTTOM 68 /* 10-bit PWM */
#define Servo_Delay 10
#define BIT1_MASK 0x02 // 0000 0010 --> Pin 0
#define PORTB_MASK 0x25
#define DDRB_MASK 0x24
#define PINB_MASK 0x23
#define BIT1_MASK 0x02
#define BIT2_MASK 0x04
#define DDRC_MASK 0x27
#define PINC_MASK 0x26
#define ADC_PIN 0
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 *OCR1AH_ESP; //0x89
unsigned char *OCR1AL_ESP; //0x88
unsigned char *OCR1BH_ESP; //0x89
unsigned char *OCR1BL_ESP; //0x88
unsigned char *TIMSK1_ESP; //0x6F
unsigned char *portPinC;
unsigned char *portDDRC;
bool flag1 = true;
bool flag2 = true;
bool pressed(unsigned char *, unsigned char, bool );
unsigned char *ADMUX_ESP;
unsigned char *ADCSRA_ESP;
unsigned char *ADCSRB_ESP;
unsigned char *ADCL_ESP;
unsigned char *ADCH_ESP;
void setup() {
ADMUX_ESP = (unsigned char*) 0x7c;
ADCSRA_ESP = (unsigned char*) 0x7a;
ADCSRB_ESP = (unsigned char*) 0x7b;
ADCL_ESP = (unsigned char*) 0x78;
ADCH_ESP = (unsigned char*) 0x79;
//////////////////////////////////////////////////
// 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;
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)(WGM10)
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 = 0b10000011; // 0X82
/* Start timer 1. (CS11)(CS10)
CS12:0 = 011 => clkI/O/64 (From prescaler) */
//*TCCR1B_ESP = 0b00001011; // 0X02 10bit Fast PWM
*TCCR1B_ESP = 0b00000011; // 0X02
/* 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;
/* Enable timer 1 overflow interrupt. (TOIE1)*/
*TIMSK1_ESP = 0b00000001; // enable timer compare interrupt - BIT1
// Global Interrupt Enabled
*SREG_ESP = 0x80;
portDDRC = (unsigned char*) DDRC_MASK;
*portDDRC &= ~BIT1_MASK; //input
*portDDRC &= ~BIT2_MASK; //input
portPinC = (unsigned char*) PINC_MASK;
}
enum { UP, DOWN };
ISR (TIMER1_OVF_vect)
{
//flag1 = pressed(portPinC, 0x02, flag1);
//flag2 = pressed(portPinC, 0x04, flag2);
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);
Serial.print(adc_read(ADC_PIN)); // 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);
}
bool pressed(unsigned char *portPinC, unsigned char num, bool flag) {
if (flag) {
if ((*portPinC ) == num)
return false;
}
if (!flag) {
if ((*portPinC ) != num)
return true;
}
}
uint16_t adc_read(uint8_t adcx) {
/* adcx is the analog pin we want to use. ADMUX's first few bits are
the binary representations of the numbers of the pins so we can
just 'OR' the pin's number with ADMUX to select that pin.
We first zero the four bits by setting ADMUX equal to its higher
four bits. */
*ADMUX_ESP &= 0xf0;
*ADMUX_ESP |= adcx;
/* This starts the conversion. */
*ADCSRA_ESP |= 0b01000000;
Serial.print( adcx);
/* Finally, we return the converted value to the calling function. */
unsigned char cl = *ADCL_ESP;
unsigned char ch = *ADCH_ESP;
Serial.print(cl);
return (cl | (ch << 8));
}