//--------------------------------------------------------
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
//--------------------------------------------------------
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#define BAUD 9600
#define MYUBRR(F_CPU,BAUD)((F_CPU/16/BAUD)-1)
//--------------------------------------------------------
#define E (1<<PD3)
#define RS (1<<PD2)
//--------------------------------------------------------
void adc_init();
int adc_read(char channel);
//--------------------------------------------------------
void lcd_init();
void latch(void);
void lcd_cmd(uint8_t cmd);
void lcd_char(uint8_t data);
void lcd_print(char *str);
void lcd_setcursor(uint8_t x, uint8_t y);
//--------------------------------------------------------
char temp[10];
float celsius;
void latch(void)
{
PORTD |= E; //send high
_delay_us(500); //wait
PORTD &= ~E; //send low
_delay_us(500); //wait
}
//to send commands in the right order
void lcd_cmd(uint8_t cmd)
{
PORTD = (PORTD & 0x0F) | (cmd & 0xF0); //send high nibble
PORTD &= ~RS; //send 0 to select command register
latch(); //latch the data
PORTD = (PORTD & 0x0F) | (cmd << 4); //send low nibble
latch(); //latch the data
}
//init sequence
void lcd_init()
{
//Init ports for LCD
DDRD |= (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7);
//send pulse to latch the data
latch();
_delay_ms(2); //delay for stable power
//command to set up the LCD
lcd_cmd(0x33);
_delay_us(100);
lcd_cmd(0x32);
_delay_us(100);
lcd_cmd(0x28); //2 lines 5x7 matrix dot
_delay_us(100);
//lcd_cmd(0x0E); // display ON, cursor ON
lcd_cmd(0x0C); //display ON, cursor ON
_delay_us(100);
lcd_cmd(0x01); //clear LCD
_delay_ms(20); //wait
lcd_cmd(0x06); //shift cursor to right
_delay_ms(1);
}
void lcd_setcursor(uint8_t x, uint8_t y)
{
uint8_t firstcharadr[] = {0x80,0xC0,0x94,0xD4};
lcd_cmd(firstcharadr[y-1]+ x-1);
_delay_us(1000);
}
void lcd_char(uint8_t data)
{
PORTD = (PORTD & 0x0F) | (data & 0xF0); //send high nibble
PORTD |= RS; //send one to select command register
latch();
PORTD = (PORTD & 0x0F) | (data<<4); //send high nibble
latch();
}
void lcd_print(char *str)
{
uint8_t k = 0;
while(str[k] != 0)
{
lcd_char(str[k]);
k++;
}
return str;
}
//--------------------------------------------------------
void adc_init(void)
{
//set the voltage reference using REFS1 and REFS0 bits and select the ADC channel using MUX bits
ADMUX = 0b01000000; //REFS1=0,REFS0=1(Vref as AVCC pin), ADLAR = 0(right adjusted),MUX4 to MUX0 is 0000 for ADC0
//enable ADC module, set prescalar of 128 which gives CLK/128
ADCSRA |= (1<<ADEN) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
}
int adc_read(char channel)
{
ADMUX = 0x40 | (channel & 0x07); //0100 0000 | (channel & 0000 0100)
_delay_ms(1); //Wait for 1ms
return ADCW; //Return ADC word
}
//--------------------------------------------------------
ISR(ADC_vect)
{
celsius = (adc_read(2)*4.9);
celsius = (celsius/10.00);
dtostrf(celsius,6,2,temp);
lcd_setcursor(1,2);
lcd_print(temp);
lcd_char(0xDF);
lcd_print("C");
ADCSRA |= (1<<ADSC); //start ADC conversion
}
//--------------------------------------------------------
int main()
{
lcd_init();
adc_init();
sei(); //enable global interrupt
lcd_setcursor(1,1);
lcd_print("Temperature:");
ADCSRA |= (1<<ADSC); //start ADC conversion
while(1){}
return 0;
}