Overview of the project
a) To use C pointers and bit manipulation to read and manipulate bits in the hardware registers
b) To model the Analogue-to-Digital Converter (ADC) Control and Status Register A using
C Structures and Bit Fields
c) To initiate an Analogue to Digital (A to D) conversion and to use the Polling algorithm to
check/wait until the completion of the (A to D) conversion before reading the binary output
d) To generate PWM outputs with different duty cycles
The code reads an analog input from pin A0 and outputs a PWM signal on pins 3 and 11, based on the value of the input.**
When interfaced with an led from pin 3 and pin 11 one of them must be bright and the other one is dimmer and vice-versa as the resistance goes up or down
#include <avr/io.h>
#include <util/delay.h>
int main (void)
{
uint8_t *ddrdp, *tccr2ap, *ddrbp ,*tccr2bp, *ocr2bp ,*ocr2ap , *admuxp ,*adclp,*adchp,adcsra,upperbit,lowerbit;
uint16_t totalbit;
Serial.begin(9600);
uint8_t x; //test
ddrdp = (uint8_t *) 0x2A; //Pin 3 (DDRD)
ddrbp = (uint8_t *) 0x24; //Pin 11 (DDRB)
*ddrdp = 0b00001000;
*ddrbp = 0b00001000;
struct adcsra {
uint8_t adps : 3; // ADC Prescaler Select Bits (least significant bit)
uint8_t adie : 1; // ADC Interrupt Enable Bit
uint8_t adif : 1; // ADC Interrupt Flag Bit
uint8_t adate : 1; // ADC Auto Trigger Enable Bit
uint8_t adsc : 1; // ADC Start Conversion Bit
uint8_t aden : 1; // ADC Enable Bit (most significant bit)
} ;
tccr2ap = (uint8_t *) 0xB0; //TCCR2A – Timer/Counter Control Register A
*tccr2ap = *tccr2ap & 0b00001100;
*tccr2ap = *tccr2ap | 0b10100011;
_delay_ms(100);
tccr2bp = (uint8_t *) 0xB1; //TCCR2B – Timer/Counter Control Register B
*tccr2bp = *tccr2bp & 0b00110000;
*tccr2bp = *tccr2bp | 0b00000111;
_delay_ms(100);
ocr2ap = (uint8_t *) 0xB3; // OCR2A – Output Compare Register A
ocr2bp = (uint8_t *) 0xB4; // OCR2B – Output Compare Register B
admuxp = (uint8_t *) 0x7C;
*admuxp = *admuxp & 0b00000000;
*admuxp = *admuxp | 0b01000000; //declare analog input A0
_delay_ms(100);
adchp = (uint8_t *) 0x79; //declaring adc register-high mode
adclp = (uint8_t *) 0x78; //declaring adc register-low mode
struct adcsra *adcsrap;
adcsrap = (struct adcsra* ) 0x7A;
_delay_ms(100);
adcsrap-> aden = 1 ;
_delay_ms(100);
adcsrap -> adps = 0b111; // 3 bits
_delay_ms(100);
while(1)
{
adcsrap -> adsc = 1;
while(adcsrap -> adsc == 1)
{
_delay_us(1);
}
upperbit = *adchp; // to obtain the data from the upper bit (2 bits)
lowerbit = *adclp; // to obtain the data from the lower bit (8 bits)
totalbit = (upperbit << 8) | lowerbit; //shifting the bit to left to make allowance for the lower bit with a total of 10 bits
x=(totalbit/1023)*255;
*ocr2ap = x +1 ;
*ocr2bp = 256-x;
_delay_ms(100);
Serial.print(totalbit); //test.
Serial.print("\n");
}
}