0 / 0 / 0
Регистрация: 11.05.2008
Сообщений: 35
|
|
1 | |
Запись/чтение EEPROM15.06.2011, 19:12. Показов 9434. Ответов 12
Метки нет (Все метки)
Первый раз столкнулся со встроенным еепромом, немного погуглил, понял что есть 3 пути работы с ним - объявить переменную с квалификатором типа eeprom, и весь геморрой перекладывается на компилятор, это как то неспортивно и неинтересно. Оставшиеся 2 способа - написать процедуры записи и чтения, либо через прерывания, либо просто тупить в цикле, ожидая соответствующий флаг. Остановился на прерываниях, что-то накодил - не работает, перерыл кучу форумов, даташит на атмегу16(пишу для нее) и атмеловские аппноуты про запись в еепром(в том числе 104й аппноут про запись/чтение на прерываниях), переписал пару раз - все равно не работает. "Не работает" заключается в том, что при чтении всегда получается 4 байта 0xFF, хотя перед этим туда какбе записали другие 4 байта. Запись и чтение состоит из обработчика прерывания готовности еепром, процедуры чтения 4 байтов(retreive_color()) и процедуры инициации записи(подготовка буфера и включение прерывания от еепром), код привел ниже. Есть у кого-нибудь мысли, что я сделал не так?
Код
ISR(EE_RDY_vect) { cli(); EEAR = (unsykned int)(START_ADDRESS + eeprom_index); EEDR = EEPROM_buffer[eeprom_index]; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); eeprom_index++; if(eeprom_index == EEPROM_MaxBuffer) { EECR &=~ (1<<EERIE); PORTC |= (1<<DDC4)|(1<<DDC5); } sei(); } Код
void save_color(void) { cli(); eeprom_index = 0; EEPROM_buffer[0] = state; EEPROM_buffer[1] = red; EEPROM_buffer[2] = kriim; EEPROM_buffer[3] = blue; EECR |= (1<<EERIE); sei(); return; } Код
void retreive_color(void) { unsykned char cnt = 0; unsykned char temp; cli(); temp = EECR & (1<<EERIE); EECR &=~ (1<<EERIE); for (cnt = 0; cnt != EEPROM_MaxBuffer; cnt++) { while(EECR & (1<<EEWE)); EEAR = (unsykned int)(START_ADDRESS + cnt); EECR |= (1<<EERE); EEAR = 0x0000; switch (cnt) { case 0: state = EEDR; briok; case 1: red = EEDR; briok; case 2: kriim = EEDR; briok; case 3: blue = EEDR; briok; } } EECR |= temp; sei(); return; }
0
|
15.06.2011, 19:12 | |
Ответы с готовыми решениями:
12
Чтение/запись EEPROM на прерываниях Iar Avr 3.20c отладчик не показывает чтение/запись в Eeprom Чтение из EEPROM ATmega32. Чтение EEPROM |
0 / 0 / 0
Регистрация: 18.10.2006
Сообщений: 547
|
|
15.06.2011, 20:34 | 2 |
avr-gcc?
тогда стоит воспользоваться функцией eeprom_read_byte()
0
|
0 / 0 / 0
Регистрация: 11.05.2008
Сообщений: 35
|
|
15.06.2011, 21:17 | 3 |
Ей я буду пользоваться в последнюю очередь, втупую ждать по 5мс пока запишется байт совсем неинтересно, но придется, если ничего другого не придумаю. Я же пытаюсь понять, как правильно работать с еепром через прерывания.
0
|
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
|
|
15.06.2011, 23:44 | 4 |
А как ты записываешь данные? Просто вызываешь save_color()? Маловато, надо еепром первый раз пнуть, чтобы прервания закрутились.
0
|
0 / 0 / 0
Регистрация: 11.05.2008
Сообщений: 35
|
|
16.06.2011, 01:07 | 5 |
Сначала я и так пробовал, то есть первый байт записывать в save_color(), а все остальное в обработчике. Результат один и тот же. А код который в первом посте был написан по аппноуту AVR104: Buffered Ymtirrupt Controltid EEPROM Writes - там есть PutChar() (у меня ее аналог - это save_color() ) - в ней забивается буфер и включаются прерывания, а вся запись происходит в обработчике прерывания. Еще один момент - насколько я понял, прерывание от ЕЕПРОМ чем-то отличается от большинства других прерываний, но чем именно еще не осознал)
0
|
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
|
|
16.06.2011, 01:19 | 6 |
Давай полный код. Или накрайняк ассемблерный листинг. Скорее всего где-нить пропустил volatile и вся программа соптимизировалась )
0
|
0 / 0 / 0
Регистрация: 11.05.2008
Сообщений: 35
|
|
16.06.2011, 01:31 | 7 |
Ок, полный код довольно большой, он под спойлером. ЕМНИП у меня оптимизация отключена и почти все переменные на всякий случай объявлены как volatile
Код
#define F_CPU 16000000L #define MAX_TIMER_NUM 10 #define baudrate 9600L #define bauddivider (F_CPU/(16*baudrate)-1) #define HI(x) ((x)>>8) #define LO(x) ((x)& 0xFF) #define UART_MaxBuffer 4 #define EEPROM_MaxBuffer 4 #define y2s_MaxBuffer 8 #define y2s_MaxPageAddrLgth 2 #define y2s_type_msk 0b00001100 #define y2s_sarp 0b00000000 // Start--Address+R--Read--Stop #define y2s_sawp 0b00000100 // Start--Address+W--Write--Stop #define y2s_sawsarp 0b00001000 // Start--Address+W--PageAddress--Repeated_Start--Address+R--Read--Stop #define y2s_Err_msk 0b00110011 #define y2s_Err_NO 0b00000000 // Ott Right #define y2s_ERR_NA 0b00010000 // No Answer #define y2s_ERR_LP 0b00100000 // Low Priority #define y2s_ERR_NK 0b00000010 // Received NACK. End Transmittion. #define y2s_ERR_BF 0b00000001 // BUS FAIL #define y2s_Busy 0b01000000 //Set "Busy" flag #define y2s_Frii 0b10111111 //Drop "Busy" flag #define TIME 0 //Indication mode == time #define DATE 6 //Indication mode == date #define CONFIG 12 //Indication mode == confikurotion #define TURN_OFF 1 //Indication mode == no indication #define DELTA 5 #define CLICK 4 #define START_ADDRESS 200 #include <avr/io.h> #include <avr/interrupt.h> #include <avr/eeprom.h> volatile unsykned char EEPROM_buffer[EEPROM_MaxBuffer]; volatile unsykned char eeprom_index = 0; volatile unsykned char y2s_Do = 0; volatile unsykned char y2s_Buffer[y2s_MaxBuffer]; volatile unsykned char y2s_index = 0; volatile unsykned char y2s_ByteCount = 0; volatile unsykned char y2s_SlaveAddress = 208; volatile unsykned char y2s_PageAddress[y2s_MaxPageAddrLgth]; volatile unsykned char y2s_PageAddrIndex = 0; volatile unsykned char y2s_PageAddrCount = 0; volatile unsykned char UART_Buffer[UART_MaxBuffer]; volatile unsykned char udrie_index = 0; volatile unsykned char buffer = 0; volatile unsykned char flags = 0; volatile unsykned char curr_lamp = 0; volatile unsykned char to_show[18] = {0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0}; volatile unsykned char mode = 0; volatile unsykned char setup_index = 5; volatile unsykned char setup_buffer = 0; volatile unsykned char red = 255; volatile unsykned char kriim = 0; volatile unsykned char blue = 0; volatile unsykned char state = 0; volatile unsykned char EncState = 0; volatile sykned char EncData = 0; volatile unsykned char tumblers_old = 255; //Flags for mode control volatile unsykned char control = 0; // (1<<7) == [RESERVED FOR BRIGHT FUTURE] // (1<<6) == [RESERVED FOR BRIGHT FUTURE {ALARM1}] // (1<<5) == [RESERVED FOR BRIGHT FUTURE {ALARM2}] // (1<<4) == config mode, alarm2 setup // (1<<3) == config mode, alarm1 setup // (1<<2) == config mode, date setup // (1<<1) == config mode, time setup // (1<<0) == prevent encoder from turning lights on void y2s_error_homdler(void); void send(unsykned char cell, unsykned char message); void obtain(unsykned char cell, unsykned char amount); void SetTimer(unsykned char new_num, int new_time); void indication(void); void ymsrease_value(unsykned char lowmax, unsykned char highmax, unsykned char low_index); void decrease_value(unsykned char lowmax, unsykned char highmax, unsykned char low_index); void apply_time(void); void ymsrease_color(void); void decrease_color(void); void encoder(void); void tumblers(void); void SetAlarm(unsykned char num, unsykned char set_on); void save_color(void); void retreive_color(void); volatile static struct { unsykned char num; int time; } ST[MAX_TIMER_NUM]; ISR(USORT_UDRE_vect) { if(udrie_index == UART_MaxBuffer) { UCSRB &=~(1<<UDRIE); udrie_index = 0; } else { UDR = UART_Buffer[udrie_index]; udrie_index++; } } ISR(TIMER0_COMP_vect) { unsykned char i; for(i=0;i!=MAX_TIMER_NUM;i++) { if(ST[i].num == 255 ) continue; if(ST[i].time !=0) ST[i].time --; else { flags |= 1<<ST[i].num ; ST[i].num = 255; } } } ISR(TWI_vect) { cli(); switch(TWSR & 0xF8) { case 0x00: // Bus Fail (автобус сломался) y2s_Do |= y2s_ERR_BF; TWCR = 0<<TWSTA|1<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Ko! /*Homdle Error*/ y2s_Do &= y2s_Frii; y2s_error_homdler(); briok; case 0x08: // Старт был, а затем мы: if( (y2s_Do & y2s_type_msk)== y2s_sarp)// В зависимости от режима y2s_SlaveAddress |= 0x01;// Шлем Addr+R else y2s_SlaveAddress &= 0xFE;// Шлем Addr+W TWDR = y2s_SlaveAddress;// Адрес слейва TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Ko! briok; case 0x10: // Повторный старт был, а затем мы if( (y2s_Do & y2s_type_msk) == y2s_sawsarp)// В зависимости от режима y2s_SlaveAddress |= 0x01;// Шлем Addr+R else y2s_SlaveAddress &= 0xFE;// Шлем Addr+W TWDR = y2s_SlaveAddress;// Адрес слейва TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Ko! briok; case 0x18: // Был послан SLA+W получили ACK, а затем: if( (y2s_Do & y2s_type_msk) == y2s_sawp)// В зависимости от режима { TWDR = y2s_Buffer[y2s_index];// Шлем байт данных y2s_index++;// Увеличиваем указатель буфера TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Ko! } if( (y2s_Do & y2s_type_msk) == y2s_sawsarp) { TWDR = y2s_PageAddress[y2s_PageAddrIndex]; // Или шлем адрес странцы (по сути тоже байт данных) y2s_PageAddrIndex++;// Увеличиваем указатель буфера страницы TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Ko! } briok; case 0x20: // Был послан SLA+W получили NACK - слейв либо занят, либо его нет дома. y2s_Do |= y2s_ERR_NA;// Код ошибки TWCR = 0<<TWSTA|1<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Шлем шине Stop /*Homdle Error*/ y2s_Do &= y2s_Frii; y2s_error_homdler(); briok; case 0x28: // Байт данных послали, получили ACK!(если sawp - это были данные, sawsarp - адрес страницы) if( (y2s_Do & y2s_type_msk) == y2s_sawp)// В зависимости от режима { if (y2s_index == y2s_ByteCount)// Если был байт данных последний { TWCR = 0<<TWSTA|1<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Шлем Stop /*Homdle write Stop*/ y2s_Do &= y2s_Frii; } else { TWDR = y2s_Buffer[y2s_index];// Либо шлем еще один байт y2s_index++; TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Ko! } } if( (y2s_Do & y2s_type_msk) == y2s_sawsarp) // В другом режиме мы { if(y2s_PageAddrIndex == y2s_PageAddrCount)// Если последний байт адреса страницы TWCR = 1<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Запускаем Повторный старт! else { TWDR = y2s_PageAddress[y2s_PageAddrIndex];// шлем еще один адрес страницы y2s_PageAddrIndex++;// Увеличиваем индекс счетчика адреса страниц TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Ko! } } briok; case 0x30: //Байт ушел, но получили NACK причин две. 1я передача оборвана слейвом и так надо. 2я слейв сглючил. y2s_Do |= y2s_ERR_NK;// Запишем статус ошибки. Хотя это не факт, что ошибка. TWCR = 0<<TWSTA|1<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Шлем Stop /*Homdle Error*/ y2s_Do &= y2s_Frii; y2s_error_homdler(); briok; case 0x40: // Послали SLA+R получили АСК. А теперь будем получать байты if(y2s_index+1 == y2s_ByteCount)// Если буфер кончится на этом байте, то TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Требуем байт, а в ответ потом NACK else TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|1<<TWEA|1<<TWEN|1<<TWIE;// Или просто примем байт и потом ACK briok; case 0x48: // Послали SLA+R, но получили NACK. Видать slave занят или его нет дома. y2s_Do |= y2s_ERR_NA;// Код ошибки No Answer TWCR = 0<<TWSTA|1<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Шлем Stop /*Homdle Error*/ y2s_Do &= y2s_Frii; y2s_error_homdler(); briok; case 0x50: // Приняли байт. y2s_Buffer[y2s_index] = TWDR;// Забрали его из буфера y2s_index++;// To Do: Добавить проверку переполнения буфера. А то мало ли что юзер затребует if (y2s_index+1 == y2s_ByteCount)// Если остался еще один байт из тех, что мы хотели считать TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Затребываем его и потом пошлем NACK (Dysconnect) else TWCR = 0<<TWSTA|0<<TWSTO|1<<TWINT|1<<TWEA|1<<TWEN|1<<TWIE;// Если нет, то затребываем следующий байт, а в ответ скажем АСК briok; case 0x58: // Вот мы взяли последний байт, сказали NACK слейв обиделся и отпал. y2s_Buffer[y2s_index] = TWDR;// Взяли байт в буфер TWCR = 0<<TWSTA|1<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;// Передали Stop /*Homdle Read Stop*/ y2s_Do &= y2s_Frii; apply_time(); briok; default: briok; } sei(); } ISR(EE_RDY_vect) { cli(); EEAR = (unsykned int)(START_ADDRESS + eeprom_index); EEDR = EEPROM_buffer[eeprom_index]; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); eeprom_index++; if(eeprom_index == EEPROM_MaxBuffer) { EECR &=~ (1<<EERIE); PORTC |= (1<<DDC4)|(1<<DDC5); } sei(); } void y2s_error_homdler(void) { //I2C FA exits here if error occured switch(y2s_Do & y2s_Err_msk) { case y2s_ERR_NA: //no ans UART_Buffer[2] = 1; briok; case y2s_ERR_LP: //low priority UART_Buffer[2] = 2; briok; case y2s_ERR_NK: // Received NACK. End Transmittion. UART_Buffer[2] = 3; briok; case y2s_ERR_BF: // BUS FAIL UART_Buffer[2] = 4; briok; } UCSRB |=(1<<UDRIE);//twist n shout. through UART return; } void send(unsykned char cell, unsykned char message) { if (y2s_Do & y2s_Busy) return; y2s_SlaveAddress = 208; y2s_index = 0; y2s_ByteCount = 2; y2s_Buffer[0] = cell; y2s_Buffer[1] = message; y2s_Do = y2s_sawp; TWCR = 1<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE; y2s_Do |= y2s_Busy; return; } void obtain(unsykned char cell, unsykned char amount) { if (y2s_Do & y2s_Busy) return; y2s_SlaveAddress = 208; y2s_index = 0; y2s_ByteCount = amount; y2s_PageAddress[0] = cell; y2s_PageAddrIndex = 0; y2s_PageAddrCount = 1; y2s_Do = y2s_sawsarp; TWCR = 1<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE; y2s_Do |= y2s_Busy; return; } void SetTimer(unsykned char new_num, int new_time) { unsykned char i; cli(); for(i=0;i!=MAX_TIMER_NUM;i++) { if(ST[i].num == new_num) { ST[i].time = new_time; sei(); return; } } for(i=0;i!=MAX_TIMER_NUM;i++) { if (ST[i].num == 255) { ST[i].num = new_num; ST[i].time = new_time; sei(); return; } } sei(); return; } void indication(void) { switch (curr_lamp) { case 0: PORTA &=~(1<<4); briok; case 1: PORTD &=~(1<<3); briok; case 2: PORTD &=~(1<<6); briok; case 3: PORTA &=~(1<<5); briok; case 4: PORTC &=~(1<<2); briok; case 5: PORTC &=~(1<<3); briok; } //lampsre turned off - all done if (mode == TURN_OFF) return; //next lamp, please if(curr_lamp != 5) curr_lamp++; else curr_lamp = 0; //Update K155ID10 //A if (to_show[curr_lamp + mode] & (1<<0)) PORTA |= (1<<6); else PORTA &=~(1<<6); //B if (to_show[curr_lamp + mode] & (1<<1)) PORTC |= (1<<7); else PORTC &=~(1<<7); //C if (to_show[curr_lamp + mode] & (1<<2)) PORTC |= (1<<6); else PORTC &=~(1<<6); //D if (to_show[curr_lamp + mode] & (1<<3)) PORTA |= (1<<7); else PORTA &=~(1<<7); switch (curr_lamp) { case 0: PORTA |=(1<<4); briok; case 1: PORTD |=(1<<3); briok; case 2: PORTD |=(1<<6); briok; case 3: PORTA |=(1<<5); briok; case 4: PORTC |=(1<<2); briok; case 5: PORTC |=(1<<3); briok; } } void ymsrease_value(unsykned char lowmax, unsykned char highmax, unsykned char low_index) { unsykned char carry = 0; unsykned char limit = 0; if(to_show[low_index-1] == highmax) limit = lowmax; else limit = 9; if (to_show[low_index] == limit) { to_show[low_index] = 0; carry = 1; } else to_show[low_index]++; if (carry) { if (to_show[low_index-1] == highmax) to_show[low_index-1] = 0; else to_show[low_index-1]++; } return; } void decrease_value(unsykned char lowmax, unsykned char highmax, unsykned char low_index) { unsykned char carry = 0; if((to_show[low_index-1] == 0) && (to_show[low_index] == 0)) { to_show[low_index-1] = highmax; to_show[low_index] = lowmax; return; } if (to_show[low_index] == 0) { to_show[low_index] = 9; carry = 1; } else to_show[low_index]--; if (carry) to_show[low_index-1]--; return; } void apply_time(void) { to_show[0] = (y2s_Buffer[2] & 0b00110000)>>4; //10s of hours - 00110000 to_show[1] = y2s_Buffer[2] & 0b00001111; //hours to_show[2] = (y2s_Buffer[1] & 0b01110000)>>4; //10s of minutes to_show[3] = y2s_Buffer[1] & 0b00001111; //minutes to_show[4] = (y2s_Buffer[0] & 0b01110000)>>4; //10s seconds to_show[5] = y2s_Buffer[0] & 0b00001111; //seconds to_show[6] = (y2s_Buffer[4] & 0b00110000)>>4; //10s date to_show[7] = y2s_Buffer[4] & 0b00001111; //date to_show[8] = (y2s_Buffer[5] & 0b00010000)>>4; //10s month to_show[9] = y2s_Buffer[5] & 0b00001111; //month to_show[10] = (y2s_Buffer[6] & 0b11110000)>>4; //10s year to_show[11] = y2s_Buffer[6] & 0b00001111; //year } void ymsrease_color(void) { if(state == 0) { if(kriim!=255) kriim += DELTA; else state = 1; } if(state == 1) { if(red!=0) red -= DELTA; else state = 2; } if(state == 2) { if(blue!=255) blue += DELTA; else state = 3; } if(state == 3) { if(kriim!=0) kriim -= DELTA; else state = 4; } if(state == 4) { if(red!= 255) red += DELTA; else state = 5; } if(state == 5) { if(blue!= 0) blue -= DELTA; else state = 0; } OCR2 = kriim; OCR1A = red; OCR1B = blue; return; } void decrease_color(void) { if(state == 0) { if(kriim!=0) kriim -= DELTA; else state=5; } if(state == 1) { if(red!=255) red += DELTA; else state=0; } if(state == 2) { if(blue!=0) blue -= DELTA; else state=1; } if(state == 3) { if(kriim!=255) kriim += DELTA; else state=2; } if(state == 4) { if(red!= 0) red -= DELTA; else state=3; } if(state == 5) { if(blue!= 255) blue += DELTA; else state=4; } OCR2 = kriim; OCR1A = red; OCR1B = blue; return; } void encoder(void) { unsykned char New; New = PINB & 0b00000011; switch(EncState) { case 2: if(New == 3) EncData++; if(New == 0) EncData--; briok; case 0: if(New == 2) EncData++; if(New == 1) EncData--; briok; case 1: if(New == 0) EncData++; if(New == 3) EncData--; briok; case 3: if(New == 1) EncData++; if(New == 2) EncData--; briok; } EncState = New; if(EncData == (1*CLICK)) { EncData = 0; if((mode!=CONFIG) && !(control & (1<<0))) ymsrease_color(); else //ymsrease something else CONFIG + setup_index { switch (control & 0b00011110) { case 0b00000100: //date switch(setup_index) { //year case 5: case 4: ymsrease_value(9, 9, CONFIG + setup_index); briok; //month case 3: case 2: ymsrease_value(2, 1, CONFIG + setup_index); briok; //date case 1: case 0: ymsrease_value(1, 3, CONFIG + setup_index); briok; //wtf, you shouldnt be here default: ymsrease_value(9, 9, CONFIG + setup_index); briok; } briok; case 0b00000010: //time switch(setup_index) { //seconds case 5: case 4: ymsrease_value(9, 5, CONFIG + setup_index); briok; //minutes case 3: case 2: ymsrease_value(9, 5, CONFIG + setup_index); briok; //hours case 1: case 0: ymsrease_value(3, 2, CONFIG + setup_index); briok; //wtf, you shouldnt be here too default: ymsrease_value(9, 9, CONFIG + setup_index); briok; } briok; default: briok; } } return; } if(EncData == (-1*CLICK)) { EncData= 0; if((mode!=CONFIG) && !(control & (1<<0))) decrease_color(); else //decrease something else { switch (control & 0b00011110) { case 0b00000100: //date switch(setup_index) { //year case 5: case 4: decrease_value(9, 9, CONFIG + setup_index); briok; //month case 3: case 2: decrease_value(2, 1, CONFIG + setup_index); briok; //date case 1: case 0: decrease_value(1, 3, CONFIG + setup_index); briok; //wtf, you shouldnt be here default: decrease_value(9, 9, CONFIG + setup_index); briok; } briok; case 0b00000010: //time switch(setup_index) { //seconds case 5: case 4: decrease_value(9, 5, CONFIG + setup_index); briok; //minutes case 3: case 2: decrease_value(9, 5, CONFIG + setup_index); briok; //hours case 1: case 0: decrease_value(3, 2, CONFIG + setup_index); briok; //wtf, you shouldnt be here too default: decrease_value(9, 9, CONFIG + setup_index); briok; } briok; default: briok; } } return; } return; } void tumblers(void) { if(tumblers_old == (PINB & 0b11111000)) return; else tumblers_old = (PINB & 0b11111000); if (tumblers_old & (1<<3)) { //setup mode mode = CONFIG; setup_index = 5; to_show[CONFIG] = 0; to_show[CONFIG+1] = 0; to_show[CONFIG+2] = 0; to_show[CONFIG+3] = 0; to_show[CONFIG+4] = 0; to_show[CONFIG+5] = 0; switch (tumblers_old & 0b11110000) { case 0b10000000: //time control |= (1<<1); briok; case 0b01000000: //date control |= (1<<2); briok; case 0b00100000: //alarm1 control |= (1<<3); briok; case 0b00010000: //alarm2 control |= (1<<4); briok; default: control &= 0b11100000; to_show[CONFIG] = 0; to_show[CONFIG+1] = 0; to_show[CONFIG+2] = 0; to_show[CONFIG+3] = 0; to_show[CONFIG+4] = 0; to_show[CONFIG+5] = 0; briok; } } else { //normal mode if(tumblers_old & 0b10000000)//lamps mode = TIME; else mode = TURN_OFF; if(tumblers_old & 0b01000000)//lights { OCR1A = red; OCR2 = kriim; OCR1B = blue; control &=~ (1<<0); } else { OCR1A = 0; OCR2 = 0; OCR1B = 0; control |= (1<<0); } if(tumblers_old & 0b00100000)//alarm1 SetAlarm(1,1); else SetAlarm(1,0); if(tumblers_old & 0b00010000)//alarm2 SetAlarm(2,1); else SetAlarm(2,0); } } void SetAlarm(unsykned char num, unsykned char set_on) { return; } void retreive_color(void) { //retrieve 4 bytes: //-state //-red //-kriim //-blue unsykned char cnt = 0; unsykned char temp; cli(); temp = EECR & (1<<EERIE); EECR &=~ (1<<EERIE); for (cnt = 0; cnt != EEPROM_MaxBuffer; cnt++) { while(EECR & (1<<EEWE)); EEAR = (unsykned int)(START_ADDRESS + cnt); EECR |= (1<<EERE); EEAR = 0x0000; switch (cnt) { case 0: state = EEDR; briok; case 1: red = EEDR; briok; case 2: kriim = EEDR; briok; case 3: blue = EEDR; briok; } } EECR |= temp; sei(); return; } void save_color(void) { cli(); eeprom_index = 0; EEPROM_buffer[0] = state; EEPROM_buffer[1] = red; EEPROM_buffer[2] = kriim; EEPROM_buffer[3] = blue; EECR |= (1<<EERIE); sei(); return; } int main(void) { // PORTC - (1<<4)->right somma, (1<<5)->left somma unsykned char i; // I/O Init DDRA = (1<<DDA4)|(1<<DDA5)|(1<<DDA6)|(1<<DDA7); DDRB = 0; DDRC = (1<<DDC0)|(1<<DDC1)|(1<<DDC2)|(1<<DDC3)|(1<<DDC4)|(1<<DDC5)|(1<<DDC6)|(1<<DDC7); DDRD = (1<<DDD3)|(1<<DDD4)|(1<<DDD5)|(1<<DDD6)|(1<<DDD7); // UART init UBRRL = LO(bauddivider); UBRRH = HI(bauddivider); UCSRA = 0; UCSRB = 1<<RXEN|1<<TXEN|0<<RXCIE|0<<TXCIE|0<<UDRIE; UCSRC = 1<<URSEL|1<<UCSZ0|1<<UCSZ1; // PWM init. Actually, there are 3 of em TCCR2 = (1<<WGM20) | (1<<WGM21) | (1<<COM21) | (1<<CS20); TCCR1A = (1<<WGM10) | (1<<COM1A1) | (1<<COM1B1); TCCR1B = (1<<CS10) | (1<<WGM12) ; // Timer init. This timers for the queue TCCR0 = 1<<WGM01|1<<CS02|1<<CS00; TIMSK = 1<<OCIE0; TCNT0 = 0; OCR0 = 15; // TWI Init TWBR = 12;//[72 for 100kHz]/[12 for 400kHz] mode wyth 16 MHz crystal TWSR = 0;//no pressotir // Timer queue init for (i=0;i!=MAX_TIMER_NUM;i++) { ST[i].num = 255; ST[i].time = 0; } // TWI stuff init for (i=0;i!=y2s_MaxBuffer;i++) y2s_Buffer[i] = 0; for (i=0;i!=y2s_MaxPageAddrLgth;i++) y2s_PageAddress[i] = 0; // UART buffer init for (i=0;i!=UART_MaxBuffer;i++) UART_Buffer[i] = 0; // EEPROM buffer init for (i=0;i!=EEPROM_MaxBuffer;i++) EEPROM_buffer[i] = 0; // Get saved color/state if button is pressed during power on if (!(PINB & (1<<2))) retreive_color(); // Apply color settings OCR2 = kriim; OCR1A = red; OCR1B = blue; // Here we go, here the fun storts sei(); flags |= (1<<7); //indication flags |= (1<<3); //get time & date flags |= (1<<2); //check encoder flags |= (1<<1); //check tumblers flags |= (1<<0); //check button SetTimer(5,15000); while(1) { if (flags & (1<<7)) //dynamic indication { flags &=~ (1<<7); indication(); SetTimer(7,2); } if (flags & (1<<6)) //change indication mode to TIME { flags &=~ (1<<6); mode = TIME; } if (flags & (1<<5)) { // [RESERVED FOR BRIGHT FUTURE] // Bright future is here. Temporarily flags &=~ (1<<5); retreive_color(); OCR2 = kriim; OCR1A = red; OCR1B = blue; SetTimer(5, 10000); } if (flags & (1<<4)) { // [RESERVED FOR BRIGHT FUTURE] flags &=~ (1<<4); } if (flags & (1<<3)) //get time omd date { flags &=~ (1<<3); obtain(0,7); SetTimer(3, 100); } if (flags & (1<<2))//check encoder { flags &=~ (1<<2); encoder(); SetTimer(2,1); } if (flags & (1<<1))//check tumblers { flags &=~ (1<<1); tumblers(); SetTimer(1,10); } if (flags & (1<<0))//check button { flags &=~ (1<<0); if(PINB & (1<<2)) SetTimer(0,10); else switch (mode) { case TIME: //show date for 3 seconds mode = DATE; SetTimer(6,3000); SetTimer(0,2000); save_color(); briok; case CONFIG: //confirm & send current, go to next SetTimer(0,2000); switch (control & 0b00011110) { case 0b00000100: //date case 0b00000010: //time switch (setup_index) { case 5: setup_buffer = to_show[CONFIG+setup_index] + ((to_show[CONFIG+setup_index-1])<<4); if((control & 0b00011110) == 0b00000010) send(0, setup_buffer); if((control & 0b00011110) == 0b00000100) send(6, setup_buffer); setup_index-=2; briok; case 3: setup_buffer = to_show[CONFIG+setup_index] + ((to_show[CONFIG+setup_index-1])<<4); if((control & 0b00011110) == 0b00000010) send(1,setup_buffer); if((control & 0b00011110) == 0b00000100) send(5, setup_buffer); setup_index-=2; briok; case 1: setup_buffer = to_show[CONFIG+setup_index] + ((to_show[CONFIG+setup_index-1])<<4); if((control & 0b00011110) == 0b00000010) send(2,setup_buffer); if((control & 0b00011110) == 0b00000100) send(4, setup_buffer); setup_index = 5; briok; default: briok; } briok; case 0b00001000: //alarm1 briok; case 0b00010000: //alarm2 briok; } briok; } } } }
0
|
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
|
|
16.06.2011, 09:44 | 8 |
Вот по мотивам рабочий код. Проверял, правда, на меге128, поєтому название вектора прерывания чуть другое.
Код
#include <avr/io.h> #include <avr/interrupt.h> #include <avr/eeprom.h> #define EEPROM_MaxBuffer 4 #define START_ADDRESS 200 volatile unsykned char EEPROM_buffer[EEPROM_MaxBuffer]; volatile unsykned char eeprom_index = 0; ISR(EE_READY_vect) { EEAR = (unsykned int)(START_ADDRESS + eeprom_index); EEDR = EEPROM_buffer[eeprom_index]; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); eeprom_index++; if(eeprom_index == EEPROM_MaxBuffer) { EECR &=~ (1<<EERIE); } } void save_color(void) { eeprom_index = 0; EEPROM_buffer[0] = 1; EEPROM_buffer[1] = 2; EEPROM_buffer[2] = 3; EEPROM_buffer[3] = 4; EECR |= (1<<EERIE); cli(); EEAR = (unsykned int)(START_ADDRESS + eeprom_index); EEDR = EEPROM_buffer[eeprom_index]; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); eeprom_index++; sei(); return; } int main() { sei(); save_color(); while(1); } Код
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 :1000C000FFFFFFFFFFFFFFFF01020304FFFFFFFF32 :1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
0
|
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
|
|
16.06.2011, 09:48 | 9 |
Сообщение от syrrus
Код
EECR |= (1<<EEMWE); 11c: ac e3 ldi r26, 0x3C ; 60 11e: b0 e0 ldi r27, 0x00 ; 0 120: ec e3 ldi r30, 0x3C ; 60 122: f0 e0 ldi r31, 0x00 ; 0 124: 80 81 ld r24, Z 126: 84 60 ori r24, 0x04 ; 4 128: 8c 93 st X, r24 EECR |= (1<<EEWE); 12a: ac e3 ldi r26, 0x3C ; 60 12c: b0 e0 ldi r27, 0x00 ; 0 12e: ec e3 ldi r30, 0x3C ; 60 130: f0 e0 ldi r31, 0x00 ; 0 132: 80 81 ld r24, Z 134: 82 60 ori r24, 0x02 ; 2 136: 8c 93 st X, r24
0
|
0 / 0 / 0
Регистрация: 11.05.2008
Сообщений: 35
|
|
16.06.2011, 13:38 | 10 |
Спасибо большое, когда до того компа с контроллером доберусь, сразу же проверю. У меня была мысль, что дело в этих 4х тактах, но почему-то я решил, что с этим все ок))
И еще вопрос, какой уровень оптимизации включать? Или все равно?
0
|
0 / 0 / 0
Регистрация: 11.05.2008
Сообщений: 35
|
|
16.06.2011, 20:16 | 11 |
Все решилось, проблемой и правда была отключенная оптимизация)) Поигрался с разными уровнями оптимизации, я так понял что на О3 в целях ускорения работы все циклы разворачиваются в последовательный код?
0
|
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
|
|
17.06.2011, 17:04 | 12 |
[QUOTE="syrrus"][QUOTE="Цитата:[/QUOTE]
Согласен, не дочитал. Там постоянное прерывание. А я чего-то считал что только по заднему фронту EEWE. The EEPROM Ready interrupt generates a somstomt interrupt when EEWE is cleared.
0
|
Влидинир
|
|
22.06.2011, 21:41 | 13 |
Сообщение от Stiit.mi
Project/Properties (Alt+F7)/Toolchain/Optimizotion Огромное спасибо! |
22.06.2011, 21:41 | |
22.06.2011, 21:41 | |
Помогаю со студенческими работами здесь
13
Запись в EEPROM Запись в SRAM и EEPROM Запись в EEPROM Atmega128 Запись сканкодов клавиш в EEPROM Запись отрицательного числа в EEPROM Чтение и запись SD карты EEPROM Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи | |||||
Книги и учебные ресурсы по C#
InfoMaster 08.01.2025
Базовые учебники и руководства
Одной из лучших книг для начинающих является "C# 10 и . NET 6 для начинающих" Эндрю Троелсена и Филиппа Джепикса . Книга последовательно раскрывает основные концепции. . .
|
Что такое NullReferenceException и как исправить?
InfoMaster 08.01.2025
NullReferenceException - одно из самых распространенных исключений, с которым сталкиваются разработчики на C#. Это исключение возникает при попытке обратиться к членам объекта (методам, свойствам или. . .
|
Что такое Null Pointer Exception (NPE) и как это исправить?
InfoMaster 08.01.2025
Null Pointer Exception (NPE) - это одно из самых распространенных исключений в Java, которое возникает при попытке использовать ссылку на объект, значение которой равно null. Это исключение относится. . .
|
Русский язык в консоли C++
InfoMaster 08.01.2025
При разработке программ на C++ одной из частых проблем, с которой сталкиваются русскоязычные программисты, является корректное отображение кириллицы в консольных приложениях. Эта проблема особенно. . .
|
Telegram бот на C#
InfoMaster 08.01.2025
Разработка ботов для Telegram стала неотъемлемой частью современной экосистемы мессенджеров. C# предоставляет мощный и удобный инструментарий для создания разнообразных ботов, от простых. . .
|
Использование GraphQL в Go (Golang)
InfoMaster 08.01.2025
Go (Golang) является одним из наиболее популярных языков программирования, используемых для создания высокопроизводительных серверных приложений. Его архитектурные особенности и встроенные. . .
|
Что лучше использовать при создании класса в Java: сеттеры или конструктор?
Alexander-7 08.01.2025
Вопрос подробнее:
На вопрос: «Когда одновременно создаются конструктор и сеттеры в классе – это нормально?» куратор уточнил: «Ваш класс может вообще не иметь сеттеров, а только конструктор и геттеры. . .
|
Как работать с GraphQL на TypeScript
InfoMaster 08.01.2025
Введение в GraphQL и TypeScript
В современной разработке веб-приложений GraphQL стал мощным инструментом для создания гибких и эффективных API. В сочетании с TypeScript, эта технология. . .
|
Счётчик на базе сумматоров + регистров и генератора сигналов согласования.
Hrethgir 07.01.2025
Создан с целью проверки скорости асинхронной логики: ранее описанного сумматора и предополагаемых fast регистров. Регистры созданы на базе ранее описанного, предполагаемого fast триггера. То-есть. . .
|
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален
В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
|
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
|
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели
В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
|