June 17, 2012
by missle3944
|
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
|
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
|
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 |