unsigned char *TCCR0A_ESP = (unsigned char *)0x2A;
unsigned char *TCCR0B_ESP = (unsigned char *)0x2B;
void MyDelay(unsigned long mSec);
void init_PWM() {
// Set OC0A (PD6) as output
unsigned char *portPinD;
portPinD = (unsigned char *) 0x29;
*portPinD |= 0x40;
// Configure Timer/Counter 0 for Fast PWM
*TCCR0A_ESP |= 0x23;
*TCCR0A_ESP |= 0x80; // Set OC0A on compare match, clear OC0A at BOTTOM
*TCCR0B_ESP |= 0x01; // No prescaler
}
void init_ADC() {
// Set A0 (PC0) as input
unsigned char *portPinC;
portPinC = (unsigned char *) 0x26;
*portPinC &= ~0x01;
// Configure ADC
ADMUX |= 0x40; // Reference voltage on AVCC
ADMUX |= 0x20; // Left adjust result (8-bit resolution)
ADCSRA |= 0x80; // Enable ADC
}
uint8_t read_ADC() {
// Start conversion
ADCSRA |= 0x40;
// Wait for conversion to complete
while (ADCSRA & 0x40);
// Return ADC value
return ADCH;
}
int main() {
// Initialize PWM and ADC
init_PWM();
init_ADC();
// Initialize serial communication
Serial.begin(9600);
// Set duty cycle based on the last two digits of My student ID
uint8_t duty_cycle = 24;
// Calculate timer value for the desired duty cycle and period
uint8_t timer_value = (duty_cycle * 255) / 100;
// Set the initial duty cycle
OCR0A = timer_value;
// Main loop
while (1) {
// Extract ADC values for at least 5 seconds
for (int i = 0; i < 5; i++) {
uint8_t adc_value = read_ADC();
// Print ADC value to serial
Serial.println(adc_value);
// Delay for a short interval
MyDelay(1000);
}
// Toggle the duty cycle for the next iteration
OCR0A = 255 - timer_value;
}
return 0;
}
void MyDelay(unsigned long mSec)
{
volatile unsigned long i;
unsigned long endT = 500 * mSec;
for (i = 0; i < endT; i++);
}