/* by Termostat avr123.nm.ru or avr123.by.ru 2004_12 редактировано MartKot 31/05/07 - 13/06/07 не рекомендуют использовать CHIP_ERASE (C7H, 94H, 80H, 9AH), есть ввероятность ошибки, смотреть выход fix-а от Atmel // AT45d161D-SU to SPI Port connection // // SCK SO SI CS нет WP RDY/BSY RST // PB7 PB6 PB5 PB4 PB3 нет(PB2) нет(PB1) RST9(PB0) // Настройка выводов МК // Out In Out Out In Out нет Out // 1 0 1 1 нет 1 нет 1 PB1 - RDY используется в проге как 0x02, для AT45d161D-SU отсутствует, используем задержку. PB4 - CS используется как DF_CHIP_SELECT или FLASH_CS PB0 - RST не используется в проге! всегда "1" PB2 - WP не используется в проге! всегда "1" PB0 - RST и PB2 - WP можно не соединять, а припаять ножки RST и WP прямо к питанию AT45 файл at45d161.h позволяет вам просто записывать байт за байтом в память не задумываясь какие процессы в ней происходят и сколько времени занимают. просто напишите в тексте вашей программы: write_to_flash (vash_byte); и значение хранящееся в вашей переменной: unsigned char vash_byte; будет записано в микросхему памяти, а когда вы снова вызовите эту функцию новое значение будет записано уже в следующую ячейку памяти. //установлены задержки: //erasing delay 45ms //write delay 0,5ms //read delay 0,5ms */ // I/O register definitions for ATmega16 #include #include // Standard Input/Output functions #include #include // at45 DataFlash - defines for all opcodes-определяет для всех кодов операции================= #define DF_CHIP_SELECT 0x10 // DataFlash chip select port pin (PINB.4) #define FLASH_CS PORTB.4 // DataFlash chip select port pin (PINB.4)(CS=1"OFFf", CS=0"ON") #define FLASH_SCK PORTB.7 #define FLASH_SI PORTB.5 #define BUFFER_1_WRITE 0x84 // buffer 1 write #define BUFFER_2_WRITE 0x87 // buffer 2 write #define BUFFER_1_READ 0xD4 // buffer 1 read, для 45DB161D #define BUFFER_2_READ 0xD6 // buffer 2 read, для 45DB161D // к странице оперативной памяти программируют со встроенным стиранием #define B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83 // buffer 1 to main memory page program with built-in erase #define B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86 // buffer 2 to main memory page program with built-in erase #define B1_TO_MM_PAGE_PROG_WO_ERASE 0x88 // buffer 1 to main memory page program without built-in erase #define B2_TO_MM_PAGE_PROG_WO_ERASE 0x89 // buffer 2 to main memory page program without built-in erase // (гллавная страница запоминающего устройства программирует через буфер 1) #define MM_PAGE_PROG_THROUGH_B1 0x82 // main memory page program through buffer 1 #define MM_PAGE_PROG_THROUGH_B2 0x85 // main memory page program through buffer 2 #define AUTO_PAGE_REWRITE_THROUGH_B1 0x58 // auto page rewrite through buffer 1 #define AUTO_PAGE_REWRITE_THROUGH_B2 0x59 // auto page rewrite through buffer 2 #define MM_PAGE_TO_B1_COMP 0x60 // main memory page compare to buffer 1 #define MM_PAGE_TO_B2_COMP 0x61 // main memory page compare to buffer 2 #define MM_PAGE_TO_B1_XFER 0x53 // main memory page to buffer 1 transfer #define MM_PAGE_TO_B2_XFER 0x55 // main memory page to buffer 2 transfer #define STATUS_REGISTER 0xD7 //0x57 DataFlash status register for reading density, compare status,and ready/busy status #define MAIN_MEMORY_PAGE_READ 0xD2 // main memory page read, для 45DB161D #define PAGE_ERASE 0x81 // erase a 528 byte page #define BLOCK_ERASE 0x50 // erase 512 pages //#define CHIP_ERASE // (C7H, 94H, 80H, 9AH)// 4 опкод все вмесе, не рекомендуют //=============== NEW =================================================================== #define SECTOR_ERASE 0x7C // для 45DB161D - надо попробовать, время стирания до 5 сек #define CHIP_ERASE (0xC7,0x94,0x80,0x9A) // 4 опкод все вмесе, не рекомендуют //======================================================================================= // PROTOTYPES=========================================================================== void block_erasing (void); // поблочно стереть всю память void chip_erasing (void); //стереть весь чип //void sector_erasing (void);//стереть всю память по секторам //void write_to_flash (unsigned char flash_data); // записать байт в память void WriteFlashByte(unsigned char byte_value); void Write_two_Byte(unsigned int two_byte_data); void Write_2_Flash (unsigned int RW_data); // записать 2-байта в память //void playback (void); // вывести содержимое всей памяти в ПК void playback (unsigned int page_counter, unsigned int page_end); // вывести содержимое памяти со стр.Х по стр.Y void next_page_to_next_buffer (unsigned char active_buffer, unsigned int page_counter); // скопировать следующую страницу памяти в следующий буфер void active_buffer_to_UART (unsigned char active_buffer); // вывести содержимое активного буфера в ПК // global variables===================================================================== volatile bit new_data = 0;// Флаг - если "1" то можно записывать с 0-й ячейки // если "0" то запись идет в следующую ячейку за последней записанной volatile bit buffer_2_write = 0; // if set 1 we must write data to second buffer volatile bit flag_flash_filed = 0; // флаг заполнения памяти 0 - незаполнена 1 - заполнена //volatile unsigned int dumb_data = 0; // переменная для заполнения памяти в тестовой программе unsigned char ctr_read; //unsigned char temp = 0x80; unsigned int last_byte_position_buffer = 0; // ячейка буфера памяти, в которую был записан последний байт unsigned int page_0 = 0; // Номер страницы с которой начинается запись в память unsigned int page_end = 4096; // Номер страницы на которой заканчиваем запись в память unsigned int last_page = 0; // страница памяти, в которую был записан последний байт unsigned int read_data = 0; unsigned int read_data_LBR=0; unsigned int read_data_HBR=0; unsigned int alt=0; void chip_erasing(void) //стирается вся память сразу { unsigned char temp = 0x80; SPCR = 0x5C; // interrupt disabled, SPI port enabled, master mode, MSB first, SPI mode 3, Fcl/4 FLASH_CS = 0; // enable DataFlash // putsf("TP 0001"); // выводится 8 байт тестовое сообщение, использовл при отладке SPDR = 0xC7; while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x94; while (!(SPSR & temp)); SPDR = 0x80; while (!(SPSR & temp)); SPDR = 0x9A; //SPDR = 0x00; // don't cares while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 1; // disable DataFlash delay_ms(2000); //<========== задержка 5 сек, для полной очистки чипа. // вся память стёрта SPCR = 0x00; // Выключить SPI } /*void sector_erasing(void) { unsigned int sector_counter = 0; //unsigned char temp = 0x80; new_data = 1; // установили флаг что можно записывать с ячейки 0. SPCR = 0x5C; // interrupt disabled, SPI port enabled, master mode, MSB first, SPI mode 3, Fcl/4 while (sector_counter < 16) { FLASH_CS = 0; // enable DataFlash // putsf("TP 0001"); // выводится 8 байт тестовое сообщение, использовл при отладке SPDR = SECTOR_ERASE; while (!(SPSR & temp)); // wait for data transfer to be completed // putsf("TP 0002"); // выводится 8 байт тестовое сообщение, использовл при отладке SPDR = (char)(sector_counter>>3); // точно по стр. 4 ДШ while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)(sector_counter<<5); // точно по стр. 4 ДШ while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // don't cares while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 1; // disable DataFlash sector_counter++; //while(!(PINB & 0x02)); // wait until block is erased-у нас такой ноги нет. delay_ms(2000); //<========== задержка 45 мсек, при 42, 100стр стирает с ошибками. } // все 512 блоков по 8 страниц стерты SPCR = 0x00; // Выключить SPI } */ void block_erasing(void) { unsigned int block_counter = 0; unsigned char temp = 0x80; new_data = 1; // установили флаг что можно записывать с ячейки 0. SPCR = 0x5C; // interrupt disabled, SPI port enabled, master mode, MSB first, SPI mode 3, Fcl/4 while (block_counter < 512) { FLASH_CS = 0; // enable DataFlash delay_us(1); // putsf("TP 0001"); // выводится 8 байт тестовое сообщение, использовл при отладке SPDR = BLOCK_ERASE; while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)(block_counter>>3); // точно по стр. 4 ДШ while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)(block_counter<<5); // точно по стр. 4 ДШ while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // don't cares while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 1; // disable DataFlash block_counter++; // wait until block is erased-у нас такой ноги нет. 50ms - 25сек время стирания delay_ms(60); //<========== задержка 55 мсек, при 45, 100стр стирает с ошибками. } SPCR = 0x00; // Выключить SPI // все 512 блоков по 8 страниц стерты } ///////////////////////////////////////////////////////////////////// /* Функция записи Байта в память - пример вызова: write_to_flash(переменная_содержащая_записываемый байт); чтобы запись пошла с 0 ячейки памяти, нужно установить флаг: new_data = 1 */ void write_to_flash(unsigned char flash_data) { // запись производится только через буфер 1. // static - такие переменные сохраняют свое значение при последующих вызовах функции! static unsigned int buffer_counter;// Хранит позицию в буфере для записи следующего байта static unsigned int page_counter; // Номер страницы в памяти unsigned char temp = 0x80; SPCR = 0x5C; // MSB first, SPI mode 3, Fcl/4, interrupt disabled, SPI port enabled, master mode if(new_data) // Если установлен флаг "new_data" - то обнулим счетчики страниц и буферов { buffer_counter = 0; // писАть в начало буфера page_counter = 0; // писАть в нулевую страницу new_data = 0; // сбросить "new_data" флаг } // ждем пока память освободится FLASH_CS = 0; // Включить AT45db161 - точнее "выбрать чип" значит сделать на CS уровень "0" delay_us(1);//<===//while(!(PINB & 0x02));нет в 161D-SU такой ноги, check if flash is busy SPDR = BUFFER_1_WRITE; while (!(SPSR & temp)); // wait for data transfer to be completed //ожидаем конца передачи данных SPDR = 0x00; // don't cares while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)(buffer_counter>>8); // don't cares plus first two bits of buffer address while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)buffer_counter; // buffer address (max. 2^8 = 256 pages) while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = flash_data; // write data into SPI Data Register while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 1; // disable DataFlash(CS) // сохранили в какую ячейку буфера был записан последн. байт last_byte_position_buffer = buffer_counter; buffer_counter++; // Хранит позицию в буфере для записи байта if (buffer_counter > 527) //miss!!!(исправлено Termostatom)// if buffer full write buffer into memory page { // если в буфер записано 528 байт, нужно записать буфер в страницу памяти buffer_counter = 0; if (page_counter < page_end) // если память не закончилась...пишем страницу { FLASH_CS = 0; // enable DataFlash SPDR = B1_TO_MM_PAGE_PROG_WO_ERASE; // write data from buffer1 to page while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)(page_counter>>6); while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)(page_counter<<2); while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // don't cares while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 0; // disable DataFlash last_page = page_counter;// сохранили страницу на которую был записан посл. байт данных page_counter++; } else { flag_flash_filed = 1; // флаг заполнения памяти } } } //пишем байт в dataflash void WriteFlashByte(unsigned char byte_value) { unsigned char tmp; unsigned char temp; temp = byte_value; for(tmp = 0; tmp < 8; tmp++) { #asm("nop"); if( (temp & 0b10000000) > 0) //Run FLASH_SI = 1; else FLASH_SI = 0; temp <<= 1; #asm("nop"); //Pulse clock line FLASH_SCK = 1; #asm("nop"); #asm("nop"); FLASH_SCK = 0; #asm("nop"); } } //запись в регистр двух байтовой переменной Store 16bit datas two byte variable void Write_two_Byte(unsigned int two_byte_data) { SPDR = ((char)two_byte_data); // LBR write data into SPI Data Register while (!(SPSR & 0x80)); // wait for data transfer to be completed SPDR = ((char)(two_byte_data>>8)); // HBR write data into SPI Data Register while (!(SPSR & 0x80)); // wait for data transfer to be completed } ///////////////////////////////////////////////////////////////////// /* Функция записи 2 Байта в память - пример вызова: Write_2_Flash(переменная_содержащая_записываемых 2байта); чтобы запись пошла с 0 ячейки памяти, нужно установить флаг: new_data = 1 */ void Write_2_Flash(unsigned int RW_data) { // Будем запись производится только через буфер 1 и 2 - Да. // static - такие переменные сохраняют свое значение при последующих вызовах функции! static unsigned int buffer_counter;// Хранит позицию в буфере для записи следующего байта static unsigned int page_counter; // Номер страницы в памяти //static unsigned int page; // Номер страницы в памяти //unsigned char buffer_write; //буфер для записи unsigned char temp = 0x80; SPCR = 0x5C; // MSB first, SPI mode 3, Fcl/4, interrupt disabled, SPI port enabled, master mode if(new_data) // Если установлен флаг "new_data" - то обнулим счетчики страниц и буферов { buffer_counter = 0; // писАть в начало буфера page_counter = page_0; // не писАть в нулевую страницу //page = 0; new_data = 0; // сбросить "new_data" флаг } delay_us(1);//<===//while(!(PINB & 0x02));нет в 161D-SU такой ноги, check if flash is busy // ждем пока память освободится 1мксек FLASH_CS = 0; // Включить AT45db161 - точнее "выбрать чип" значит сделать на CS уровень "0" #asm("nop"); //SPDR = BUFFER_1_WRITE; SPDR = (buffer_2_write)?0x87:0x84; //select bufer for writing (если "1"= second-0x87,"0"- first-0x84) while (!(SPSR & temp)); // ожидаем конца передачи данных //buffer_write = (buffer_2_write)?0x87:0x84; //select bufer for writing //WriteFlashByte(buffer_write); //WriteFlashByte(0x00); //WriteFlashByte((char)(buffer_counter>>8)); //WriteFlashByte((char)buffer_counter); SPDR = 0x00; // don't cares 8bit(00000000) while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = ((char)(buffer_counter>>8)); // 6bit don't cares plus first 2 bits of buffer address(000000AA) while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = ((char)buffer_counter); // 8 bit buffer address (max. 2^8 = 256 pages)(AAAAAAAA) while (!(SPSR & temp)); // wait for data transfer to be completed //WriteFlashByte((char)RW_data); //WriteFlashByte((char)(RW_data>>8)); //Store datas Write_two_Byte(RW_data); //SPDR = ((char)RW_data); // LBR write data into SPI Data Register //while (!(SPSR & temp)); // wait for data transfer to be completed //SPDR = ((char)(RW_data>>8)); // HBR write data into SPI Data Register //while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 1; // disable DataFlash - запись delay_us(1);//<=== check if flash is busy // last_byte_position_buffer = buffer_counter; // сохранили в какую ячейку буфера был записан последн. байт buffer_counter+=2; // Хранит позицию в буфере для записи байта, здесь 2 - количество сохраненных байтов за время if (buffer_counter == 528) // if buffer full write buffer into memory page { // если в буфер записано 528 байт, записываем буфер в страницу памяти, перключая наполнение на воторй буфер buffer_counter = 0; if (page_counter < page_end) // (max 4096) если память не закончилась...пишем страницу,перключаем буфер { FLASH_CS = 0; // enable DataFlash #asm("nop"); //SPDR = B1_TO_MM_PAGE_PROG_WITH_ERASE; // 0x83 // buffer 1 to main memory page program with built-in erase //SPDR = B1_TO_MM_PAGE_PROG_WO_ERASE; // 0x88 write data from buffer1 to page //SPDR = (buffer_2_write)?0x86:0x83;//запись buffer в страницу памяти со стиранием SPDR = (buffer_2_write)?0x89:0x88; //запись buffer(first-0x88 or 2-0x89) в страницу памяти без стирания while (!(SPSR & temp)); // wait for data transfer to be completed buffer_2_write = !buffer_2_write; //switch buffer, переключили буфер /////// page = page_counter; /////// page <<= 2; //сдвиг на 2bit влево страницы (0000AAAA AAAAAAAA)=(00AAAAAA AAAAAA00) /////// SPDR = ((char)(page>>8)); //8bit LBR page address (00AAAAAA)2bit don't cares, 6bit page address SPDR = ((char)(page_counter>>6)); // 2bit don't cares, 6bit page address (00AAAAAA) while (!(SPSR & temp)); // wait for data transfer to be completed /////// SPDR = ((char)page); // 6bit page address,2bit don't (AAAAAA00) SPDR = ((char)(page_counter<<2)); // 6bit page address,2bit don't (AAAAAA00) while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // 8bit don't cares (00000000) while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 1; // disable DataFlash last_page = page_counter;// сохранили страницу на которую был записан посл. байт данных page_counter++; } else { flag_flash_filed = 1; // флаг заполнения памяти } } } /*/////////////////////////////Main Memory Page Program Through Buffer////////////////////////////////////////////// // ещё не доделал void Write_Mem_Page(unsigned int page_n, unsigned int RW_data) { //запись производится только через буфер 1 static unsigned int buffer_counter;// Хранит позицию в буфере для записи следующего байта static unsigned int page_counter; // Номер страницы в памяти static unsigned int page; // Номер страницы в памяти unsigned char temp = 0x80; SPCR = 0x5C; // MSB first, SPI mode 3, Fcl/4, interrupt disabled, SPI port enabled, master mode buffer_counter = 0; // писАть в начало буфера page_counter = page_n; FLASH_CS = 0; // Включить AT45db161 - точнее "выбрать чип" значит сделать на CS уровень "0" #asm("nop"); SPDR = MM_PAGE_PROG_THROUGH_B1; //0x82 main memory page program through buffer 1 while (!(SPSR & temp)); // ожидаем конца передачи данных SPDR = ((char)(page_counter>>6));// 2bit don't cares, 6bit page address (00AAAAAA) while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = ((char)(page_counter<<2)+(char)(buffer_counter>>8)); // 6bit page address,2bit buffer address (AAAAAA00)+(000000BB) while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = ((char)buffer_counter); // 8 bit buffer address (max. 2^8 = 256 pages)(BBBBBBBB) while (!(SPSR & temp)); // wait for data transfer to be completed //Store datas SPDR = ((char)RW_data); // LBR write data into SPI Data Register while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = ((char)(RW_data>>8)); // HBR write data into SPI Data Register while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 1; // disable DataFlash - запись delay_us(1);//<=== check if flash is busy // last_byte_position_buffer = buffer_counter; // сохранили в какую ячейку буфера был записан последн. байт //ВНИМАНИЕ!!! Для 2-х Byte переменной размер буфера будет 264!!!(264х2В или 528х8 = 4224bit !!!) buffer_counter+=2; // Хранит позицию в буфере для записи байта, здесь 2 - количество сохраненных байтов за время if (buffer_counter == 528) //(264x2 or 528) if buffer full write buffer into memory page { // если в буфер записано 264/528 байт, записываем буфер в страницу памяти, перключая наполнение на воторй буфер buffer_counter = 0; if (page_counter < 4096) // если память не закончилась...пишем страницу,перключаем буфер { FLASH_CS = 0; // enable DataFlash #asm("nop"); FLASH_CS = 1; // disable DataFlash } else { flag_flash_filed = 1; // флаг заполнения памяти } } } *////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //=============================================================================== void playback (unsigned int page_counter, unsigned int page_end) ///////// чтение данных из флеши(2 буфера) и передача их по UART { //unsigned int page_counter = 0; //not used! unsigned int buffer_counter = 0; unsigned char active_buffer = 1; // active buffer = buffer1 SPCR = 0x5C;// interrupt disabled, SPI port enabled, master mode, MSB first, SPI mode 3, Fcl/4 next_page_to_next_buffer (active_buffer, page_counter); // неверно! read page0 to buffer1 - неверно! //правильно: Читает страницу page_counter в буфер НЕ(active_buffer) // read page0 to buffer2 //неверно! wait until page0 to buffer1 transaction is finished //правильно: wait until page0 to buffer2 transaction is finished //ожидаем пока завершится передача стр.0 в buffer2 delay_us(400);//<======//while(!(PINB & 0x02)); //ЗАРЕМАРЕНО MartKot // check if flash is busy // ждем пока память освободится // в while ниже довольно трудная для понимания логика, // я попробовал ее прокомментировать и понял !!! о чудо! while (page_counter < page_end) // если последняя сраница(max 4095) памяти не считана... { page_counter++; // now take next page /* Второй раз в цикле - текущ. стр. стала 2 */ if (active_buffer == 1) // if buffer1 is the active buffer { active_buffer++; // set buffer2 as active buffer } else // else { active_buffer--; // set buffer1 as active buffer } // Первый раз в цикле активным станет буфер-2 /* Второй раз в цикле - текущ. стал буфер-1 */ next_page_to_next_buffer (active_buffer, page_counter); /* Первый раз в цикле пишется стр. 1 в буфер 1 так как активен сейчас 2-й буфер! */ /* Второй раз в цикле - в буфер-2 будет скопирована стр. 2 */ active_buffer_to_UART (active_buffer); /* Первый раз в цикле будет выводится буфер-2 содерж стр. 0 так как активен сейчас 2-й буфер! */ /* Второй раз в цикле - из буфер-1 будет выводится стр. 1 */ } SPCR = 0x00; // disable SPI } void next_page_to_next_buffer (unsigned char active_buffer, unsigned int page_counter) { unsigned char temp = 0x80; delay_us(500); //<=======//while(!(PINB & 0x02)); // wait until flash is not busy FLASH_CS = 0; // enable DataFlash /* Здесь: Если активен один буфер, то текущая страница копируется в ДРУГОЙ !!! буфер, не текущий */ if (active_buffer == 1) // if buffer1 is the active buffer { SPDR = MM_PAGE_TO_B2_XFER; // transfer next page to buffer2 } else // else { SPDR = MM_PAGE_TO_B1_XFER; // transfer next page to buffer1 } while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)(page_counter >> 6); while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = (char)(page_counter << 2); while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // write don't care byte while (!(SPSR & temp)); // wait for data transfer to be completed FLASH_CS = 1; // disable DataFlash and start transaction } void active_buffer_to_UART (unsigned char active_buffer) /////16bit { // until active buffer not empty read active buffer to rs232 unsigned int buffer_counter = 0; unsigned char temp = 0x80; //putsf("NextPg."); // выводится 8 байт //putsf(";"); // выводится 8 байт FLASH_CS = 0; // enable DataFlash if (active_buffer == 1) // if buffer1 is the active buffer { SPDR = BUFFER_1_READ; // read from buffer1 } else // else { SPDR = BUFFER_2_READ; // read from buffer2 } while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // write don't care byte while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // write don't care byte while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // start at buffer address 0 while (!(SPSR & temp)); // wait for data transfer to be completed SPDR = 0x00; // write don't care byte while (!(SPSR & temp)); // wait for data transfer to be completed while (buffer_counter < 528) { SPDR = 0xFF; // write dummy value to start register shift while (!(SPSR & temp)); // wait for data transfer to be completed while (!UCSRA.5); // ждем пока освободится UDR - это для Mega16 //while (!USR.5); // ждем пока освободится UDR - это для AT90 //if((ctr_read == 0)|(ctr_read == 2)) //0 или 2-читаем LBR, 1 или 3-читаем HBR if((ctr_read % 2) == 0) //можно так, проверить остаток от деления на 2 { // четный/ read_data_LBR = SPDR; //записываем младший байт LBR в read_data(00000000LLLLLLLL) ctr_read++;//счётчк чтения памяти } else { // нечетный read_data_HBR = SPDR; //пишмем старший байт HBR в read_data(00000000HHHHHHHH) read_data = ((read_data_HBR<<8)+ read_data_LBR); //(HHHHHHHHLLLLLLLL) if(ctr_read == 1) { alt = read_data; ctr_read++;//счётчк чтения памяти } else { //accel = read_data; printf("%d,%d\n", alt, read_data); ctr_read=0; //printf("ADC=%d\n\r",read_data); //printf("====%d", read_data); // Adc1-первый датчик //printf(";%"); // Adc2-второй датчик //printf("AdcG=%d\n\r", Adc2); } read_data_LBR = 0; read_data_HBR = 0; } read_data = 0; /*/======================================================== // А теперь - случай, где смесь цикла и условного оператора оправдана: // int i; // for(i=0; i < 100; i++){ // if((i % 2) == 0) //проверяем остаток от деления на 2 // even(); // четный // else odd(); // нечетный/ // } // Тут в цикле проверяется четность индекса i. //========================================================== //ADC_data_LBR = ADC_data &0x0F; //в ADC_data_LBR лежит младший байт от АЦП //ADC_data = ADC_data>>8; //printf("ADC=%d\n\r",read_data); //UDR = SPDR; // записываем байт принятый по SPI из памяти в UART if((ctr_read == 0)|(ctr_read == 2)) //0 или 2-читаем LBR, 1 или 3-читаем HBR if((ctr_read % 2) == 0) //можно так, проверить остаток от деления на 2 { // четный/ read_data_LBR = SPDR; //записываем младший байт LBR в read_data(00000000LLLLLLLL) ctr_read++;//счётчк чтения памяти } else { // нечетный read_data_HBR = SPDR; //пишмем старший байт HBR в read_data(00000000HHHHHHHH) read_data = ((read_data_HBR<<8)+ read_data_LBR); //(HHHHHHHHLLLLLLLL) ctr_read=0; printf("%d,%d\n", alt, read_data); //printf("ADC=%d\n\r",read_data); //printf("====%d", read_data); // Adc1-первый датчик //printf(";%"); // Adc2-второй датчик //printf("AdcG=%d\n\r", Adc2); read_data_LBR = 0; read_data_HBR = 0; read_data = 0; } */ buffer_counter++; } FLASH_CS = 1; // disable DataFlash }