Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //**********************************************************
- // **** MAIN routine FOR Interfacing microSD/SD CARD ******
- //**********************************************************
- //Controller: ATmega168 (Clock: 8 Mhz-internal)
- //Compiler: AVR-GCC
- //Version : 2.1
- //Author: CC Dharmani, Chennai (India)
- // www.dharmanitech.com
- //Date: 26 Feb 2009
- //********************************************************
- //Link to the Post: http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html
- #define F_CPU 8000000UL //freq 8 MHz
- #include <avr/io.h>
- #include <avr/pgmspace.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- #include <stdlib.h>
- #include "SPI_routines.h"
- #include "SD_routines.h"
- #include "UART_routines.h"
- #include "FAT32.h"
- volatile unsigned long startBlock;
- volatile unsigned long totalBlocks;
- volatile unsigned char buffer[512];
- volatile unsigned long firstDataSector, rootCluster, totalClusters;
- volatile unsigned int bytesPerSector, sectorPerCluster, reservedSectorCount;
- volatile uint16_t digitala = 0, digitalb = 0;
- volatile int seconds = 0, minutes = 1, hours = 2;
- volatile int days = 3, months = 4, years = 10;
- volatile int sample = 1;
- void port_init(void)
- {
- MCUCR = 0x00; // Don't disable pullup resistors
- // Setup Port B DDR PORTB
- // 7 - XTAL2 0 0 (Cannot be used as IO pin)
- // 6 - XTAL1 1 1 (Cannot be used as IO pin)
- // 5 - SCK (DAPA) 1 1
- // 4 - MISO (DAPA) 1 1
- // 3 - MOSI (DAPA) 1 1
- // 2 - SS 1 1
- // 1 - (DAPA) 1 1
- // 0 - Bootloader, Input 1 1 (Pullup Resistor)
- //
- PORTB = 0xEF; // The description doesnt agree with the settings
- DDRB = 0xEF; // MISO line i/p, rest o/p
- // Setup Port C DDR PORTC
- // 6 - Reset, input 0 0
- // 5 - LED, logging, ouput 1 0 (LED Off)
- // 4 - ANALOG4 (unused), input 0 0
- // 3 - ANALOG3, input 0 0
- // 2 - ANALOG2, input 0 0
- // 1 - ANALOG1, input 0 0
- // 0 - Log Button, input 0 1 (Pullup Resistor)
- //
- DDRC = 0b00100000;
- PORTC = 0b00000001;
- // Setup Port D DDR PORTD
- // 7 - Button, timeset, input 0 1 (Pullup Resistor)
- // 6 - LED, timeset1, output 1 0 (LED off)
- // 5 - LED, timeset2, output 1 0 (LED off)
- // 4 - 1 0
- // 3 - INT1, input 0 1 (Pullup Resistor)
- // 2 - INT0, input 0 1 (Pullup Resistor)
- // 1 - UART TXD, output 1 0
- // 0 - UART RXD, input 0 1
- //
- DDRD = 0b01110010;
- PORTD = 0b10001101;
- }
- //UART0 initialize
- // desired baud rate: 19200
- // actual: baud rate: 19231 (0.2%)
- // char size: 8 bit
- // parity: Disabled
- void uart0_init(void)
- {
- UCSR0B = 0x00; //disable while setting baud rate
- UCSR0A = 0x00;
- UCSR0C = 0x06;
- UBRR0L = 0x19; //set baud rate lo
- UBRR0H = 0x00; //set baud rate hi
- UCSR0B = 0x18;
- }
- // Initialise ADC
- void adc_init() {
- // Initialise analog to digital converter
- ADMUX = 0x00; // Set for external reference (3.3V), single ended input
- // set analog to digital converter
- // to be enabled, with a clock prescale of 1/128
- // so that the ADC clock runs at 62.5kHz
- ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
- // fire a convertsion just to get the ADC warmed up
- ADCSRA |= (1<<ADSC);
- }
- //call this routine to initialize all peripherals
- void init_devices(void)
- {
- cli();
- port_init();
- spi_init();
- uart0_init();
- adc_init();
- // Set up debounce timer (Timer0)
- TCCR0A = 0x00; // Set Timer0 to normal running mode
- TCCR0B = 0x00; // Ensure Timer0 is stopped
- TCNT0 = 0x00; // Clear Timer0 counter
- TIMSK0 = 0b00000001; // Enable overflow interrupt on Timer0
- // Set up Real Time Clock (RTC) timer (16 bit)
- TCCR1A = 0x00; // Set Timer1 to normal running mode
- TCCR1B = 0x00; // Ensure Timer1 is stopped
- TCNT1 = 0x85EE; // Allow 31250 increments per overflow interrupt (1 second)
- TIMSK1 = 0b00000001; // Enable overflow interrupt on Timer1
- TCCR1B = 0b00000100; // Set timer1 running at clk/256
- // Set up debounce timer (Timer2)
- TCCR2A = 0x00; // Set Timer2 to normal running mode
- TCCR2B = 0x00; // Ensure Timer2 is stopped
- TCNT2 = 0x00; // Clear Timer2 counter
- TIMSK2 = 0b00000001; // Enable overflow interrupt on Timer2
- // Set up interrupts for digital pulse (INT0 & INT1)
- // DDRD = 0b11110111; // Set PD3(INT1) to input
- // PORTD = 0b00001000; // Set PD3 pullup resistor
- EIMSK = 0b00000011; // Enable INT1 & INT0
- EICRA = 0b00001010; // Activate on falling egde (ISK11=1, ISK10=0, ISK01=1, ISK00=0)
- sei(); // Set interrupt enable
- }
- int main(void)
- {
- unsigned char error, FAT32_active, logs;
- unsigned int i;
- unsigned char fileName[13], fileNameTemp[13];
- _delay_ms(100); //delay for VCC stabilization
- init_devices();
- TX_NEWLINE;
- TX_NEWLINE;
- transmitString_F (PSTR("***********************************"));
- TX_NEWLINE;
- transmitString_F (PSTR("** Mujda Data Logger Development **"));
- TX_NEWLINE;
- transmitString_F (PSTR("** Create Consecutive Log File **"));
- TX_NEWLINE;
- SD_init();
- SPI_HIGH_SPEED; //SCK - 4 MHz
- _delay_ms(1);
- // Set the 6 pins to input mode - Two 3 bit numbers
- //DDRC &= ~(1<<PC0); // set PC0 as input
- // turn on the internal resistors for the pins
- //PORTC |= (1<<PC0); // turn on internal pull up resistor for PA0
- FAT32_active = 1;
- logs = 0;
- error = getBootSectorData (); //read boot sector and keep necessary data in global variables
- if(error)
- {
- transmitString_F (PSTR("FAT32 not found!")); //FAT32 incompatible drive
- while(1){
- PORTC |= 0b00100000; // Turn on LED1
- _delay_ms(500);
- PORTC &= 0b11011111; // Turn off LED1
- _delay_ms(500);
- }
- FAT32_active = 0;
- }
- while(FAT32_active == 1)
- {
- PORTC |= 0b00100000; // Turn on LED1
- // Pause for 2 seconds before checking for button press as button may have just been pressed to stop logging
- _delay_ms(2000);
- transmitString_F (PSTR("Press button to start logging"));
- TX_NEWLINE;
- while((PINC & 1) == 1);
- PORTC &= 0b11011111; // Turn off LED1
- fileName[0] = 'D';
- fileName[1] = 'a';
- fileName[2] = 't';
- fileName[3] = 'a';
- fileName[4] = '0';
- fileName[5] = '0';
- fileName[6] = '.';
- fileName[7] = 'c';
- fileName[8] = 's';
- fileName[9] = 'v';
- fileName[10] = 0x00;
- fileName[11] = 0x00;
- fileName[12] = 0x00;
- for(i=0; i<13; i++) fileNameTemp[i] = fileName[i]; //transfer to temporary variable due to Verification process
- while(readFile (VERIFY, fileNameTemp) == 1){
- fileName[5]++;
- if(fileName[5] == ':'){fileName[5] = '0'; fileName[4]++;}
- if(fileName[4] == ':'){transmitString_F(PSTR("Too many log files: ")); logs = 1;}
- for(i=0; i<13; i++) fileNameTemp[i] = fileName[i];
- }
- if(logs == 0) createFile(fileName);
- }
- return 0;
- }
- // Interrupt Service Routine
- // Call:
- // On -ve edge of INT1
- // Action:
- // If last call was greater than 1.024mS before, then:
- // - Pulse counter incremented
- // - Set timer counter going
- //
- ISR(SIG_INTERRUPT1)
- {
- if(TCNT0 == 0){ // If Timer0 is not running (enough time to exclude switch bounce)
- digitalb++; // Increment counts per sample
- TCNT0 = 0xF8; // Set counter to 8 increments before overflow
- TCCR0B = 0b00000101; // Set Timer0 Prescaler to 1024
- } // 8MHz/1024 = 7812.5 or 0.128mS per increment
- } // 8 increments (0xF8 to 0x00) = 1.024mS to Timer0 reset
- // Interrupt Service Routine
- // Call:
- // On -ve edge of INT0
- // Action:
- // If last call was greater than 1.024mS before, then:
- // - Pulse counter incremented
- // - Set timer counter going
- //
- ISR(SIG_INTERRUPT0)
- {
- if(TCNT2 == 0){ // If Timer2 is not running (enough time to exclude switch bounce)
- digitala++; // Increment counts per sample
- TCNT2 = 0xF8; // Set counter to 8 increments before overflow
- TCCR2B = 0b00000101; // Set Timer0 Prescaler to 1024
- } // 8MHz/1024 = 7812.5 or 0.128mS per increment
- } // 8 increments (0xF8 to 0x00) = 1.024mS to Timer2 reset
- // Interrupt Service Routine
- // Call:
- // On Timer0 overflow
- // Action:
- // - Stop Timer0
- // - Ensure Timer0 counter is zeroed
- //
- ISR(TIMER0_OVF_vect)
- {
- TCCR0B = 0b00000000; // Stop Timer0
- TCNT0 = 0; // Ensure counter is zeroed
- }
- // Interrupt Service Routine
- // Call:
- // On Timer1 overflow
- // Action:
- // - Set timer1 0x85EE (1 second to next interrupt)
- // - Update RTC
- // - Set the sample flag at appropriate interval
- //
- ISR(TIMER1_OVF_vect)
- {
- TCNT1 = 0x85EE; // Allow 31250 increments per overflow interrupt (1 second)
- seconds++;
- sample = 1; // Set the sample flag to initiate sampling
- if(seconds == 60){
- seconds = 0;
- minutes++;
- }
- if(minutes == 60){
- minutes = 0;
- hours++;
- }
- if(hours == 24){
- hours = 0;
- days++;
- }
- if(days == 29 && months == 2){
- days = 1;
- months++;
- }
- if(days == 31 && ((months == 4) || (months == 6) || (months == 9) || (months == 11))){
- days = 1;
- months++;
- }
- if(days == 32){
- days = 1;
- months++;
- }
- if(months == 13){
- months = 1;
- years++;
- }
- }
- // Interrupt Service Routine
- // Call:
- // On Timer2 overflow
- // Action:
- // - Stop Timer2
- // - Ensure Timer2 counter is zeroed
- //
- ISR(TIMER2_OVF_vect)
- {
- TCCR2B = 0b00000000; // Stop Timer0
- TCNT2 = 0; // Ensure counter is zeroed
- }
- //********** END *********** www.dharmanitech.com *************
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement