NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Reading eeprom

June 17, 2012
by missle3944
missle3944's Avatar

Hi guys,

I have a strange problem.I'm making a device were you enter a password through a dip switch and then it saves it to the eeprom. The first step the program goes through is if you have the original password entered. But everytime I enter the original password I have to reset the uC to get to the next step. Heres my code. its a little messy though.

/*simple eeprom program. stores a byte in 2 locations. stores 10 in register 1 and stores 9 in 46.
 */
#define F_CPU 14745600

#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include <avr/eeprom.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

void realtimeclock_setup() {
  // setup Timer0:
  // CTC (Clear Timer on Compare Match mode)
  // TOP set by OCR0A register
  TCCR0A |= (1<<WGM01);
  // clocked from CLK/1024
  // which is 14745600/1024, or 14400 increments per second
  TCCR0B |= (1<<CS02) | (1<<CS00);
  // set TOP to 143
  // because it counts 0, 1, 2, ... 142, 143, 0, 1, 2 ...
  // so 0 through 143 equals 144 events
  OCR0A = 143;
  // enable interrupt on compare event
  // (14400 / 144 = 100 per second)
  TIMSK0 |= (1<<OCIE0A);
}

// the_time will store the elapsed time
// in hundredths of a second.
// (100 = 1 second)
// 
// note that this will overflow in approximately 248 days!
//
// This variable is marked "volatile" because it is modified
// by an interrupt handler.  Without the "volatile" marking,
// the compiler might just assume that it doesn't change in 
// the flow of any given function (if the compiler doesn't
// see any code in that function modifying it -- sounds 
// reasonable, normally!).
//
// But with "volatile", it will always read it from memory 
// instead of making that assumption.
volatile int32_t the_time;

SIGNAL(TIMER0_COMPA_vect) {
  // when Timer0 gets to its Output Compare value,
  // one one-hundredth of a second has elapsed (0.01 seconds).
  the_time--;
}

int main() {
realtimeclock_setup();

 // init lcd

lcd_init();
  FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
  lcd_home();

  DDRC &= ~(1<<PC0); // set PC0 as input
  DDRC &= ~(1<<PC1); // set PC1 as input
  DDRC &= ~(1<<PC2); // set PC2 as input
  DDRC &= ~(1<<PC3); // set PC3 as input
  DDRC &= ~(1<<PC4); // set PC4 as input
  DDRC &= ~(1<<PC5); // set PC5 as input

  // turn on the internal resistors for the pins

  PORTC |= (1<<PC0); // turn on internal pull up resistor for PC0
  PORTC |= (1<<PC1); // turn on internal pull up resistor for PC1
  PORTC |= (1<<PC2); // turn on internal pull up resistor for PC2
  PORTC |= (1<<PC3); // turn on internal pull up resistor for PC3
  PORTC |= (1<<PC4); // turn on internal pull up resistor for PC6
  PORTC |= (1<<PC5); // turn on internal pull up resistor for PC7

  uint8_t a1;
  uint8_t a2;
  uint8_t a3;
  uint8_t b1;
  uint8_t b2;
  uint8_t b3;

uint16_t origin_password;
uint16_t password;
uint16_t num;
num = eeprom_read_byte((uint8_t*)5);
the_time = 500; //countdown timer for password entry = 10seconds

  sei();

          a1 = (PINC & (1<<PC0)) >> PC0;
      a2 = (PINC & (1<<PC1)) >> PC1;
      a3 = (PINC & (1<<PC2)) >> PC2;
      b1 = (PINC & (1<<PC3)) >> PC3;
      b2 = (PINC & (1<<PC4)) >> PC4;
      b3 = (PINC & (1<<PC5)) >> PC5;

  lcd_line_one();
 lcd_write_string(PSTR("Password Please?"));

origin_password = (a1<<6) + (a2<<5) + (a3<<4)  +  (b1<<3) + (b2<<2) + (b3<<1); 
num = eeprom_read_byte((uint8_t*)5);

eeprom_write_byte ((uint8_t*) 6, origin_password);
// After this I have to reset. I want a transition from the Password Please? to Enter a new password so it saves the new password

while(1) {   
          a1 = (PINC & (1<<PC0)) >> PC0;
      a2 = (PINC & (1<<PC1)) >> PC1;
      a3 = (PINC & (1<<PC2)) >> PC2;
      b1 = (PINC & (1<<PC3)) >> PC3;
      b2 = (PINC & (1<<PC4)) >> PC4;
      b3 = (PINC & (1<<PC5)) >> PC5;

num = eeprom_read_byte((uint8_t*)5);  //user entered passwrd prevously

if(origin_password == num){

  // clear the display and move the cursor to row 1, column 1
lcd_home();              // move to 1, 1 without clearing the display
lcd_line_one();
 lcd_write_string(PSTR("Enter new password!"));

fprintf_P(&lcd_stream, PSTR("%16.2f sec"), (double) the_time/100 );

if( the_time == 1){

lcd_clear_and_home();    // clear the display and move the cursor to row 1, column 1
           // move to 1, 1 without clearing the display
lcd_line_three();
password = (a1<<6) + (a2<<5) + (a3<<4)  +  (b1<<3) + (b2<<2) + (b3<<1); 
lcd_write_string(PSTR("Saving Password!"));
eeprom_write_byte ((uint8_t*) 5, password);
delay_ms(400);
lcd_clear_and_home();

lcd_line_four();
lcd_write_string(PSTR("Password Saved"));

lcd_clear_and_home;
}

}
   }
   return 0;
   }
June 19, 2012
by pcbolt
pcbolt's Avatar

missle -

I haven't played around with reading/writing to the eeprom too much, but have you tried using the "eeprom_busy_wait()" function between lines 109 and 111? Since it takes some time to do read/writes, having them execute right after one another may cause a problem.

June 21, 2012
by missle3944
missle3944's Avatar

pcbolt,

Thanks for the suggestion. It still doesn't work though. I think I need a flag or something becuase I cannot go from the main to while loop for some reason. But if the password is right it quickly goes from Please enter password, and then it jumps to enter new password.

-Dan

Post a Reply

Please log in to post a reply.

Did you know that you can read diagnostic data from some cars with a NerdKit? Learn more...