Перейти к содержанию
    

Помогите моргнуть лампочкой

Эта супер-программа должна моргать лампочкой со скважностью ~0,5 сек.

Собираю всё в EWB 3.21, шью - PonyProg2000.

Не получается заставить её работать в верхних 4 кб mega128.

Во фьюзах ставлю галочки у BOOTRST и BOOTSZ1.

Подправил адреса в xcl-файле (с 1F000 ).

 

Подскажите где я промахнулся...

 

#include <iom128.h>
#include <ina90.h>
//-------------------------------------------------------
void main(void)
{
long t=0;
  
  __disable_interrupt();
  
   MCUCR=(1<<IVCE);MCUCR=(1<<IVSEL);

  PORTG = 0xff;
  DDRG |= 0x08;

  __enable_interrupt();
           
  while(1){    
    if(t++ > 100000){ 
      PORTG ^= 0x08; 
      t=0;
    }
  }
}
//--------------------------------------------------------

Проект также прилагается.

Micro.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разве можно прямо в проверке условия делать инкремент переменной t?

И, кстати, есть в ИАРе встроенная функция для реализации задержек __delay_cycles(кол. тактов)

Изменено пользователем МП41

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разве можно прямо в проверке условия делать инкремент переменной t?

А почему бы и нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эта супер-программа

Moderator:

Суперпрограммы публикуются исключительно в разделе для начинающих. Исходные тексты оформляются тэгами. Перенес и отредактировал на первый раз.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разве можно прямо в проверке условия делать инкремент переменной t?

Да, действительно..

while(1){
if(t > 100000)
t++;
{
PORTG ^= 0x08;

так? (не помню.. надо точку с запятой?)

Изменено пользователем zltigo
Бездумное цитирование и многоэтажные подписи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обращаю внимание присутствующих (и особливо суперпривередливого супермодератора), что этот топик не так прост, как можно заключить из его названия. Дело тут не в примитивном ногодрыганьи, а в том, что код, нормально работающий в нижних адресах памяти, не работает в верхних.

На новичка Slev мало похож, новички xor-ом не моргают :). Данный пример программы, несомненно тестовый. И будь на месте человека, столкнувшегося с проблемой верхних адресов, профессионал, то он точно так же попытался бы запустить в этих адресах что-то моргающее светодиодиком.

Я, к сожалению, не могу ответить на вопрос автора топика, т.к. сама не работала на mega с объемом flash выше 64К и EWB не использую. Однако подозреваю, что здесь что-то не ладно с фузами. Что-то типа того, что стоит защита, запрещающая обращаться к верхним адресам памяти. Такое бывает сплошь и рядом из-за требований обезопасить загрузчик (верхнюю часть памяти от попыток его протестировать через нижную загружаемую часть). Возможно и то, что таблица векторов прерываний оказалась по недосмотру поднята вверх, а старт остался снизу. Тогда тоже может случиться, что main() не получает управления. А вот заниматься поиском ляпов в программе не стоит, поскольку на нижних адресах памяти она работает.

В любом случае, заданный вопрос достаточно серьезен, чтобы не вызывать раздражение модератора. Куда большие сомнения в отсутствии профессионализма следовало бы отнести к авторам реплик, не знающих механизма постинкрементации. Программа написана свершенно верно. Проблема же только в том, отчего она не работает в верхних 4К адресного пространства.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...поскольку на нижних адресах памяти она работает... Проблема же только в том, отчего она не работает в верхних 4К адресного пространства.
Автор топика не сообщил: работает ли его программа в "нижних" адресах памяти... А не работать она может, например, потому, что используется порт G и установлен (заводская установка) fuse совместимости с m103...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно!

По умолчанию в Меге128 прошит fuse M103C (режим совместимости с Мегой 103), его нужно стереть, т.е. установить в 1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, действительно..

(не помню.. надо точку с запятой?)

Ну и зачем писать, если не помните? "Действительно" таки нет. Можно. Постинкремент - обычное выражение, результат которого четко документирован, и этот результат, как и результат любого другого выражения, может использоваться как один из операндов опертатора ">", результат которого уже используется в проверке условия.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проверте настройки линкера - начало области загрузчика и размер секции векторов (там 35 векторов по 4 байта).

Ещё проверте фус-биты настройки размера секции загрузчика, фус-бит старта из секции загрузчика. И выключите режим совместимости.

Снизу фрагмент файла линкера на котором я осваивал бут-секцию атмеги 128.

Выделе фрагмент где описано расположение сегментов во флеш - посмотрите может чемто поможет :)

 


-DBOOT_START_512=1FC00 //константа адрес начала секции загрузчика 512 байт
-DBOOT_START_1024=1F800 //константа адрес начала секции загрузчика 1024 байт
-DBOOT_START_2048=1F000 //константа адрес начала секции загрузчика 2048 байт
-DBOOT_START_4096=1E000 //константа адрес начала секции загрузчика 4096 байт

-DBOOT_START=BOOT_START_4096 /*начало секции загрузчика*/


-DBOOT_SIZE_512=200
-DBOOT_SIZE_1024=400
-DBOOT_SIZE_2048=800
-DBOOT_SIZE_4096=1000
-DBOOT_SIZE=BOOT_SIZE_4096 //размер секции загрузчика

/* Code (flash) segments */
-D_..X_INTVEC_SIZE=8C   /* 4 bytes * 35 vectors */
-D_..X_FLASH_TEND=FF    /* End of tiny flash memory */
-D_..X_FLASH_NEND=FFFE  /* End of near flash memory */
-D_..X_FLASH_END=(1FFFF-2)  /* End of flash memory */ //тут указывается конечный адрес памяти минус 2 байта на crc
-D_..X_CRC_FLASH_END=(1FFFF) /*указываем что crc16 будет размещаться в конце памяти отведённой для программы*/




/* Code memory */
-Z(CODE)INTVEC=BOOT_START-(BOOT_START+_..X_INTVEC_SIZE-1) 

/* Fill unused interrupt vector's with RETI */
-H1895
-h(CODE)BOOT_START-(BOOT_START+_..X_INTVEC_SIZE)

-Z(CODE)TINY_F=(BOOT_START+_..X_INTVEC_SIZE)-(BOOT_START+_..X_FLASH_TEND)
-Z(CODE)NEAR_F,SWITCH,DIFUNCT=(BOOT_START+_..X_INTVEC_SIZE)-(BOOT_START+_..X_FLASH_NEND)
-Z(CODE)CODE=(BOOT_START+_..X_INTVEC_SIZE)-_..X_FLASH_END
-Z(FARCODE)FAR_F=(BOOT_START+_..X_INTVEC_SIZE)-_..X_FLASH_END
-Z(CODE)HUGE_F,INITTAB=(BOOT_START+_..X_INTVEC_SIZE)-_..X_FLASH_END
-Z(CODE)TINY_ID,NEAR_ID=(BOOT_START+_..X_INTVEC_SIZE)-_..X_FLASH_END
-Z(CODE)CHECKSUM=(_..X_CRC_FLASH_END-1)-_..X_CRC_FLASH_END //тут располагается сегмент crc16 - 2 последних байта памяти

//а это ключ линкера для вычисления crc16 по области (CODE)0-(_..X_CRC_FLASH_END-2)
//-J2,crc16,1,=(CODE)0-(_..X_CRC_FLASH_END-2) 
-J2,crc16,1//=(CODE)1E004-1E00b  //  BOOT_START-(BOOT_START+2)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем, кто откликнулся (особенно Ксении - за понимание:).

В нижних адресах всё работает. При сборке в верхние адреса, ставлю только две галки BOOTRST и BOOTSZ1. Остальные фузы не трогаю.

Галочка с М103С снята.

В прилагаемом проекте находится правленный xcl-файл (boot_m128.xcl) и в папке Release\List лежат листинги и map-файл (boot_m128.map).

 

Посмотрите на них, плиз, свежим взглядом, может чего я пропустил...

 

2 memphis_: завтра попробую собрать с твоим фрагментом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрите на них, плиз, свежим взглядом, может чего я пропустил...

В AppNote AVR231 (AES Bootloader) есть пример универсального xcl - файла для старших адресов.

Типа

-Z(CODE)INTVEC=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-BOOT_SIZE+IVT_SIZE-1)

-Z(CODE)NEAR_F,HUGE_F,SWITCH,INITTAB,DIFUNCT,CODE=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-1)

 

Несколько удобнее, не так ли?

 

По теме - возможны две причины

1) Естественно, несовпадение размеров бут-области с xcl-файлом. Сам я не пользовался, но это про инверсию галок в пони всегда пишут?

2) не обеспечивается программирование старших адресов. Но смотрим файл HEX, вроде в порядке, команда установки сегмента есть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При сборке в верхние адреса, ставлю только две галки BOOTRST и BOOTSZ1. Остальные фузы не трогаю.
Что значит: "не трогаю"? Оставляете заводские установки? Огласите, тогда уж, весь список... Например, BOOTSZ0 - осталася в заводской установке (т.е. 0 - галка в пони стоит)? Тогда BOOTSZ10 = 00; длина (4096 слов = 8192 байт) и адрес загрузчика (F000 в словах = 1Е000 в байтах)...

 

Сам я не пользовался, но это про инверсию галок в пони всегда пишут?
В пони: есть галка = 0; нет галки = 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вложил картинку про фузы.

BOOTSZ=01 - 2048 words - 4096 bytes - F800*2=1F000

 

2 memphis_: твой фрагмент ничего не изменил, адреса получились такие же.

 

Раньше делал загрузчик для mega16, mega32. Сейчас хотел тупо собрать его для mega128 - не заработал. Всё повыкидовал оттуда, оставил только лампочку - всё равно не хочет работать...

 

Наверное, есть какие-то нюансы для >64K...

post-52449-1256108041_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вложил картинку про фузы.

BOOTSZ=01 - 2048 words - 4096 bytes - F800*2=1F000

 

2 memphis_: твой фрагмент ничего не изменил, адреса получились такие же.

 

В данный момент пишу загрузчик на основе настроек линкера что дал выше - светодиод моргает :)

Для моргания светодиода ньюансов нет.

1. BOOTSTART у вас выставлен правильно - по ресету прыгаем в секцию загрузчика.

2. Если фусы BOOTSZ10 = 01 то размер секции загрузчика 2048 слов и адрес с которого надо располагать программу 1F000

 

В моём файле линкера это выглядит так:

 

-DBOOT_START_512=1FC00 //константа адрес начала секции загрузчика 512 байт
-DBOOT_START_1024=1F800 //константа адрес начала секции загрузчика 1024 байт
-DBOOT_START_2048=1F000 //константа адрес начала секции загрузчика 2048 байт
-DBOOT_START_4096=1E000 //константа адрес начала секции загрузчика 4096 байт

-DBOOT_START=BOOT_START_2048 /*начало секции загрузчика*/

-DBOOT_SIZE_512=200
-DBOOT_SIZE_1024=400
-DBOOT_SIZE_2048=800
-DBOOT_SIZE_4096=1000
-DBOOT_SIZE=BOOT_SIZE_2048 //размер секции загрузчика

 

Проверил - у меня всё работает.

Не работает только в одном случае - если неправильно выставлены биты BOOTSZ10.

В вашех hex-файле видно что программа располагается с правильно адреса. Ищите косяки в установке бит BOOTSZ10.

 

 

Откомпилировал вашу программу у себя слегка изменив с параметрами

-DBOOT_START_2048=1F000 //константа адрес начала секции загрузчика 2048 байт
-DBOOT_START=BOOT_START_2048 /*начало секции загрузчика*/

-DBOOT_SIZE_2048=800
-DBOOT_SIZE=BOOT_SIZE_2048//размер секции загрузчика

 

Попробуйте прошить.

 

 

#include <iom128.h>
#include <ina90.h>
//-------------------------------------------------------
void main(void)
{
long t=1000000;

 __disable_interrupt();

  MCUCR=(1<<IVCE);MCUCR=(1<<IVSEL);

 PORTG = 0xff;
 DDRG |= 0x08;

 __enable_interrupt();

 while(1){    
   if(t > 0) t--;
   else
   { 
     PORTG ^= 0x08; 
     t=1000000;
   }
 }

}
//--------------------------------------------------------

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...