ADXL345

 avatar
subratasarkar20
c_cpp
5 months ago
4.8 kB
4
Indexable
/*
 * ADC_ADXL_ATmega328p.cpp
 *
 * Created: 16-10-2024 11:59:53
 * Author : subrs
 */ 
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include "util/delay.h"
#include <stdio.h>

#define TOGGLE_PIN PD2								// Toggle this pin in ADC ISR

volatile uint16_t x_axis = 0;					// Variable to store the ADC result
volatile uint16_t y_axis = 0;					// Variable to store the ADC result
volatile uint16_t z_axis = 0;					// Variable to store the ADC result
volatile uint16_t channel = 0;					// Variable to store the ADC result

#define RS PD0							// Use PIND0 for Register Select
#define EN PD1							// Use PIND1 for Enable
#define LCD_PORT PORTB					// Use PORTC for data (D0-D7)

char buffer0[16];						// To store frequency value as a string
char buffer1[16];
char buffer2[16];

void LCD_Command(unsigned char cmnd);
void LCD_Char(unsigned char data);
void LCD_Init(void);
void LCD_String(char *str);
void LCD_Clear(void);
void LCD_SetCursor(unsigned char row, unsigned char col);

void timer0_init(void) 
{
	// Set Timer0 to CTC mode
	TCCR0A |= (1 << WGM01);							// CTC mode
	TCCR0B |= (1 << CS01) | (1 << CS00);			// Prescaler 64

	OCR0A = 15;									// Compare value for 1ms at 16MHz clock with 64 prescaler

	TIMSK0 |= (1 << OCIE0A);						// Enable Compare Match A interrupt
}

void adc_init(void) 
{
	ADMUX |= (1 << REFS0);							// AVcc as reference
	ADMUX |= (1 << MUX0);							// Select ADC1 (PC1)

	ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);			// Enable ADC and set prescaler to 128 for 125kHz ADC clock (16MHz/128)
	
	ADCSRA |= (1 << ADIE);								// Enable ADC Interrupt
}

ISR(TIMER0_COMPA_vect) 
{
	ADCSRA |= (1 << ADSC);								// Start ADC conversion
}

ISR(ADC_vect) 
{
    // Read ADC value and store it in the corresponding variable based on the current channel
    if (channel == 0) {
	    x_axis = ADC;  // Store value from ADC0
	    } else if (channel == 1) {
	    y_axis = ADC;  // Store value from ADC1
	    } else if (channel == 2) {
	    z_axis = ADC;  // Store value from ADC2
    }

    // Switch to the next ADC channel
    channel = (channel + 1) % 3;  // Loop through ADC0, ADC1, and ADC2

    // Update ADMUX to select the next channel
    ADMUX = (ADMUX & 0xF0) | channel;  // Ensure only the MUX bits are updated
}

int main(void) 
{
	DDRD |= (1 << TOGGLE_PIN);							// Set TOGGLE_PIN as output

	timer0_init();
	adc_init();

	sei();
	LCD_Init();
	
	while (1) 
	{
		LCD_Clear();
		
		sprintf(buffer0, "X: %u", x_axis);		// Convert pulse_time to string
		LCD_SetCursor(0, 0);								// Set cursor to first row, first column
		LCD_String(buffer0);									// Display pulse_time on LCD
		
		sprintf(buffer1, "Y: %u", y_axis);		// Convert pulse_time to string
		LCD_SetCursor(0, 8);								// Set cursor to first row, first column
		LCD_String(buffer1);									// Display pulse_time on LCD
				
		sprintf(buffer2, "Z: %u", z_axis);		// Convert pulse_time to string
		LCD_SetCursor(1, 0);								// Set cursor to first row, first column
		LCD_String(buffer2);									// Display pulse_time on LCD
		
		_delay_ms(500);
	}
}

// Send a command to the LCD
void LCD_Command(unsigned char cmnd)
{
	LCD_PORT = cmnd;                              // Send command to data bus
	PORTD &= ~(1 << RS);                          // RS = 0 for command
	PORTD |= (1 << EN);                           // Enable pulse
	_delay_us(1);
	PORTD &= ~(1 << EN);
	_delay_ms(2);
}

// Send a character to the LCD
void LCD_Char(unsigned char data)
{
	LCD_PORT = data;                              // Send data to data bus
	PORTD |= (1 << RS);                           // RS = 1 for data
	PORTD |= (1 << EN);                           // Enable pulse
	_delay_us(1);
	PORTD &= ~(1 << EN);
	_delay_ms(2);
}

// Initialize the LCD
void LCD_Init(void)
{
	DDRB = 0xFF;                                  // Configure data port for LCD (all output)
	DDRD |= (1 << RS) | (1 << EN);                // Configure RS and EN pins as output

	_delay_ms(20);                                // LCD power on delay
	LCD_Command(0x38);                            // 8-bit mode, 2-line, 5x7 font
	LCD_Command(0x0C);                            // Display ON, Cursor OFF
	LCD_Command(0x06);                            // Auto-increment cursor
	LCD_Command(0x01);                            // Clear display
	_delay_ms(2);
}

// Send a string to the LCD
void LCD_String(char *str)
{
	while (*str)
	{
		LCD_Char(*str++);
	}
}

// Clear the LCD display
void LCD_Clear(void)
{
	LCD_Command(0x01);                            // Clear display command
	_delay_ms(2);
}

// Set cursor to specific row and column
void LCD_SetCursor(unsigned char row, unsigned char col)
{
	unsigned char pos[] = {0x80, 0xC0};           // DDRAM addresses for row 0 and row 1
	LCD_Command(pos[row] + col);
}

Editor is loading...
Leave a Comment