Skip to content

Instantly share code, notes, and snippets.

@inkwisit
Last active June 12, 2016 06:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inkwisit/6aaf0763a6cd60616e65b7df2697170e to your computer and use it in GitHub Desktop.
Save inkwisit/6aaf0763a6cd60616e65b7df2697170e to your computer and use it in GitHub Desktop.
Microcontroller 8-bit ATmega32A
#include"config.h"
#include<avr/io.h>
#include<util/delay.h>
//auto triggering mode is not used here in this library .. (ADATE in ADCSRA)
//differential input ADC has not been included in this library .. ADMUX (MUX[4:0])
//see in the Internet how the shift register is optimized for the constant variable shifting ..
//whether a constant value is assigned or shifting process is left for the processor ..
void adc_initialize()
{
ADCSRA |= (1<<ADEN);
// ADC is turned on ..
ADMUX |= (0<<REFS1)|(1<<REFS0);
// selecting the AVCC as the reference voltage .. add an external capacitor to the AVREF pin 0.1uF
// if the result is left adjusted and 8bit precision is required than ADCH is sufficient
ADMUX |= (1<<ADLAR);
// enabling the left adjustment ..
//for a 16MHZ clock (from the crystal) ADPS [2:0] are selected to divide the clock by 16 . these are ADC prescalar
ADCSRA |= (1<<ADPS2)|(0<<ADPS1)|(0<<ADPS0);
//it will give 1MHz clock to the ATmega32 for this crystal ..
//till now no need of interrupt so it is not set ..
ADCSRA |= (0<<ADIE);
// this interrupt is invoked when conversion is complete (ADIF is set) ..
return;
}
uint8_t read_adc_8bit(unsigned char channel)
{
ADMUX &= 0xf8;
// clearing the channel MUX register
ADMUX |= (channel & 0x07);
// setting the MUX register provided by the user ..
_delay_us(10);
// this delay is being given to stabilize the input voltage after selection of the channel ..
// start conversion , set high the ADSC bit int ADCSRA , this bit cleared automatically after the conversion is completed
ADCSRA |= (1<<ADSC);
//waiting for the conversion to finish
while((ADCSRA & (1<<ADIF)) == 0);
//clearing the ADIF bit in ADCSRA reg ..
ADCSRA |= (1<<ADIF);
return ADCH;
//reading the higher bit is sufficient ..
}
uint16_t read_adc_10bit(unsigned char channel)
{
uint16_t temp_ADCL = 0;
ADMUX &= 0xf8;
// clearing the channel MUX register
ADMUX |= (channel & 0x07);
// setting the MUX register provided by the user ..
_delay_us(10);
// this delay is being given to stabilize the input voltage after selection of the channel ..
// start conversion , set high the ADSC bit int ADCSRA , this bit cleared automatically after the conversion is completed
ADCSRA |= (1<<ADSC);
//waiting for the conversion to finish
while((ADCSRA & (1<<ADIF)) == 0);
//clearing the ADIF bit in ADCSRA reg .. otherwise automatically cleared after execution of the ISR of adc interrupt
ADCSRA |= (1<<ADIF);
temp_ADCL = ADCL;
//ADCL has to be read first ..
//((ADCH << 2)|(temp_ADCL>>6)) is done because the ADLAR bit has been set to 1.
return ((ADCH << 2)|(temp_ADCL>>6));
}
/*
* adc.h
*
* Created: 02-06-2016 02:37:36
* Author: Subha Sarkar
*/
#ifndef ADC_H_
#define ADC_H_
void adc_initialize();
uint8_t read_adc_8bit(unsigned char channel);
uint16_t read_adc_10bit(unsigned char channel);
#endif /* ADC_H_ */
#ifndef F_CPU
#define F_CPU 8000000UL
#endif
/*
* timer1_fast_pwm_atmega32a.c
*
* Created: 05-06-2016 14:38:06
* Author : Subha Sarkar
*/
#include <avr/io.h>
#include "config.h"
#include <avr/interrupt.h>
#include <util/delay.h>
#include "adc.h"
#include "uart.h"
#include <stdlib.h>
int main(void)
{
uint16_t pot_value = 0;
long long int duty_cycle = 0;
char buff[10]={0};
//max. 4 bytes for data and 1 for null character ..
DDRD = 0xff;
//setting the pin for OC1A as output
// initializing the timer1 ..
// Setting the timer to run in the maximum capable speed ..
// setting the CS bit to get clk/1 ..
TCCR1B |= (0<<CS12)|(0<<CS11)|(1<<CS10);
//setting for the FAST PWM mode .. (10 bit) TOP = 0x03FF
TCCR1A |= (1<<WGM11)|(1<<WGM10);
TCCR1B |= (0<<WGM13)|(1<<WGM12);
//setting the output compare bit mode ..
//clear the OC1A on compare match , set on BOTTOM..
TCCR1A |= (1<<COM1A1)|(0<<COM1A0);
TCCR1A |= (0<<COM1B1)|(0<<COM1B0);
//expected frequency at external 2.5V is 7.812 KHz with 50% duty cycle.
adc_initialize();
UART_setup(9600);
while (1)
{
pot_value = read_adc_10bit(0);
//scanning values from the channel 1;
OCR1A = pot_value;
duty_cycle = ((long int)pot_value*100)/1024;
//double buffered means the update of executing OCR1A will take place after the TCNT1 reaches BOTTOM.
ltoa(duty_cycle,buff,10);
UART_send_string(buff,-1);
UART_write('\n');
_delay_ms(100);
}
}
/*
* uart.c
*
* Created: 03-06-2016 06:59:40
* Author: Subha Sarkar
*/
// no double speed ..
// no external clock from XCK Pin
// Baud rate is calculated as per the formula of Baud rate in the data sheet .
#include <avr/io.h>
#include <stdlib.h>
#include "uart.h"
void UART_setup(uint32_t Baudrate)
{
uint32_t baud = ((F_CPU/Baudrate)/16)-1;
// Receiver complete enable interrupt is enabled ..
// Receiver is enabled ..
// Transmitter is enabled ..
// This UCSRB contains rx/tx interrupt enable bit , usart data register empty enable bit , character size bit (only 1 bit is there , remaining bits are in UCSRC)
// data bit 9 is present if 9-bit mode is selected ..
UCSRB |= (0<<RXCIE)|(1<<RXEN)|(1<<TXEN);
// this bit is selected while writing the UCSRC register ..
UCSRC |= (1<<URSEL);
// asynchronous mode is selected ..
UCSRC |= (0<<UMSEL);
// parity mode selector .. (No parity)
UCSRC |= (0<<UPM1)|(0<<UPM0);
// stop bit select .. (1 bit)
UCSRC |= (0<<USBS);
// Character size is selected .. (8-bit)
UCSRC |= (1<<UCSZ1)|(1<<UCSZ0);
//Making the URSEL bit of UCSRC 0 to disable further writing of the register ..
UCSRC ^= (1<<URSEL);
// URSEL is assumed to be zero .. so we are able to write in the UBRRH register ..
UBRRH = (unsigned char)(baud >> 8);
UBRRL = (unsigned char)baud;
}
char UART_read()
{
char data;
while(!(UCSRA & (1<<RXC)));
data = UDR; // the data is erased from the UDR register ..
return data;
}
void UART_write(char data)
{
//UDRE = 1 indicates that the data register is empty
while(!(UCSRA & (1<<UDRE)));
UDR = data;
return;
}
// put -1 to override the buff length check and the output depends solely on NULL pointer and the null character.
void UART_send_string(char* data,int buff_size)
{
unsigned int temp = 0;
if(buff_size == -1)
{
while(data != NULL && *data != '\0')
{
UART_write(*(data++));
}
}
else
{
while(temp<buff_size)
{
UART_write(*(data+temp));
temp++;
}
}
return;
}
/*
* uart.h
*
* Created: 03-06-2016 06:59:53
* Author: Subha Sarkar
*/
#include "config.h"
#include<util/delay.h>
#ifndef UART_H_
#define UART_H_
void UART_send_string(char* data,int buff_size);
void UART_write(char data);
char UART_read();
void UART_setup(uint32_t Baudrate);
#endif /* UART_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment