Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите моргнуть лампочкой
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Slev
Эта супер-программа должна моргать лампочкой со скважностью ~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;
    }
  }
}
//--------------------------------------------------------

Проект также прилагается.
МП41
А разве можно прямо в проверке условия делать инкремент переменной t?
И, кстати, есть в ИАРе встроенная функция для реализации задержек __delay_cycles(кол. тактов)
MrYuran
Цитата(МП41 @ Oct 20 2009, 14:53) *
А разве можно прямо в проверке условия делать инкремент переменной t?

А почему бы и нет?
zltigo
Цитата(Slev @ Oct 20 2009, 11:53) *
Эта супер-программа

Moderator:
Суперпрограммы публикуются исключительно в разделе для начинающих. Исходные тексты оформляются тэгами. Перенес и отредактировал на первый раз.
virtual9900
Цитата(МП41 @ Oct 20 2009, 13:53) *
А разве можно прямо в проверке условия делать инкремент переменной t?

Да, действительно..
Код
while(1){
if(t > 100000)
t++;
{
PORTG ^= 0x08;

так? (не помню.. надо точку с запятой?)
Xenia
Обращаю внимание присутствующих (и особливо суперпривередливого супермодератора), что этот топик не так прост, как можно заключить из его названия. Дело тут не в примитивном ногодрыганьи, а в том, что код, нормально работающий в нижних адресах памяти, не работает в верхних.
На новичка Slev мало похож, новички xor-ом не моргают smile.gif. Данный пример программы, несомненно тестовый. И будь на месте человека, столкнувшегося с проблемой верхних адресов, профессионал, то он точно так же попытался бы запустить в этих адресах что-то моргающее светодиодиком.
Я, к сожалению, не могу ответить на вопрос автора топика, т.к. сама не работала на mega с объемом flash выше 64К и EWB не использую. Однако подозреваю, что здесь что-то не ладно с фузами. Что-то типа того, что стоит защита, запрещающая обращаться к верхним адресам памяти. Такое бывает сплошь и рядом из-за требований обезопасить загрузчик (верхнюю часть памяти от попыток его протестировать через нижную загружаемую часть). Возможно и то, что таблица векторов прерываний оказалась по недосмотру поднята вверх, а старт остался снизу. Тогда тоже может случиться, что main() не получает управления. А вот заниматься поиском ляпов в программе не стоит, поскольку на нижних адресах памяти она работает.
В любом случае, заданный вопрос достаточно серьезен, чтобы не вызывать раздражение модератора. Куда большие сомнения в отсутствии профессионализма следовало бы отнести к авторам реплик, не знающих механизма постинкрементации. Программа написана свершенно верно. Проблема же только в том, отчего она не работает в верхних 4К адресного пространства.
Палыч
Цитата(Xenia @ Oct 20 2009, 14:27) *
...поскольку на нижних адресах памяти она работает... Проблема же только в том, отчего она не работает в верхних 4К адресного пространства.
Автор топика не сообщил: работает ли его программа в "нижних" адресах памяти... А не работать она может, например, потому, что используется порт G и установлен (заводская установка) fuse совместимости с m103...
SSerge
Точно!
По умолчанию в Меге128 прошит fuse M103C (режим совместимости с Мегой 103), его нужно стереть, т.е. установить в 1.
Сергей Борщ
Цитата(virtual9900 @ Oct 20 2009, 13:59) *
Да, действительно..
(не помню.. надо точку с запятой?)
Ну и зачем писать, если не помните? "Действительно" таки нет. Можно. Постинкремент - обычное выражение, результат которого четко документирован, и этот результат, как и результат любого другого выражения, может использоваться как один из операндов опертатора ">", результат которого уже используется в проверке условия.
mempfis_
Проверте настройки линкера - начало области загрузчика и размер секции векторов (там 35 векторов по 4 байта).
Ещё проверте фус-биты настройки размера секции загрузчика, фус-бит старта из секции загрузчика. И выключите режим совместимости.
Снизу фрагмент файла линкера на котором я осваивал бут-секцию атмеги 128.
Выделе фрагмент где описано расположение сегментов во флеш - посмотрите может чемто поможет smile.gif

CODE


-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)

Slev
Спасибо всем, кто откликнулся (особенно Ксении - за пониманиеsmile.gif.
В нижних адресах всё работает. При сборке в верхние адреса, ставлю только две галки BOOTRST и BOOTSZ1. Остальные фузы не трогаю.
Галочка с М103С снята.
В прилагаемом проекте находится правленный xcl-файл (boot_m128.xcl) и в папке Release\List лежат листинги и map-файл (boot_m128.map).

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

2 memphis_: завтра попробую собрать с твоим фрагментом.
Dog Pawlowa
Цитата(Slev @ Oct 21 2009, 01:01) *
Посмотрите на них, плиз, свежим взглядом, может чего я пропустил...

В 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, вроде в порядке, команда установки сегмента есть.
Палыч
Цитата(Slev @ Oct 21 2009, 01:01) *
При сборке в верхние адреса, ставлю только две галки BOOTRST и BOOTSZ1. Остальные фузы не трогаю.
Что значит: "не трогаю"? Оставляете заводские установки? Огласите, тогда уж, весь список... Например, BOOTSZ0 - осталася в заводской установке (т.е. 0 - галка в пони стоит)? Тогда BOOTSZ10 = 00; длина (4096 слов = 8192 байт) и адрес загрузчика (F000 в словах = 1Е000 в байтах)...

Цитата(Dog Pawlowa @ Oct 21 2009, 06:51) *
Сам я не пользовался, но это про инверсию галок в пони всегда пишут?
В пони: есть галка = 0; нет галки = 1
Slev
Вложил картинку про фузы.
BOOTSZ=01 - 2048 words - 4096 bytes - F800*2=1F000

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

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

Наверное, есть какие-то нюансы для >64K...
mempfis_
Цитата(Slev @ Oct 21 2009, 11:01) *
Вложил картинку про фузы.
BOOTSZ=01 - 2048 words - 4096 bytes - F800*2=1F000

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


В данный момент пишу загрузчик на основе настроек линкера что дал выше - светодиод моргает smile.gif
Для моргания светодиода ньюансов нет.
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//размер секции загрузчика


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


CODE
#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;
}
}

}
//--------------------------------------------------------
Slev
memphis, твоя прошивка работает !

А в чём ты собираешь? Можно посмотреть получившийся листинг и map-файл?

Может это у меня из-за старого иара...

Или в настройках проекта я что-то не то делаю...
Сергей Борщ
Цитата(Slev @ Oct 21 2009, 12:39) *
Может это у меня из-за старого иара...

Или в настройках проекта я что-то не то делаю...
Так загрузите ваш HEX в студию, поставьте галочку "стартовать из бут-области", укажите адрес начала этой области и пройдите в дизассемблере по шагам. Сразу все и увидите.
mempfis_
Цитата(Slev @ Oct 21 2009, 12:39) *
memphis, твоя прошивка работает !


IAR AVR 5.10A/W32 (5.10.1.5)
Уже больше года как пользуюсь им.

К сожалению скинуть фйлы не могу (создавал их путём коментирования кусков основного проекта).
Могу скинуть полный файл настройки линкера и советую обновить иар (если обновите до версии ewavr-ev-web-510A могу помочь сделать его здоровым).
Также можно покопаться в настройках вашего линкера или проекта вцелом - разгадка гдето там....
Slev
И ещё, самый первый вектор у нас разный: у меня 0С 94 70 F8, у тебя 00 0С 94 78 F8!

Самое интересное: просто изменил в своей прошивке 70 на 78 и ... лампочка заморгала!!!

По адресу F870 (1F0E0) у меня лежит C_STARTUP, по адресу F878 (1F0F0) - cstartup_call_main

Может со стартапом чего-то не то?

Цитата(mempfis_ @ Oct 21 2009, 13:57) *
К сожалению скинуть фйлы не могу (создавал их путём коментирования кусков основного проекта).


Я ж листинги компилера и линкера прошу, а не исходники.

Кстати, а какую библиотеку используешь? Может у меня библиотека не правильная (dl3s-ec.r90)?
SysRq
В нерабочем коде (дизасм ja tools\reavr):
Код
    ldi    r16,kA5
    out    p3D,r16 // SPL
    ldi    r16,k00
    out    p3E,r16 // SPH


Куда-то в Extended IO оно ведет вместо оперативки..
mempfis_
ОК. map и lst в архиве.
По поводу библиотек - особо не вникал в этот вопрос.
Slev
Нашёл!
Проблема была не с CODE, а с DATA! Сегменты начинались не со 100, а с 60 (издержки ручной правки xcl-файла от mega32)...

Всем спасибо!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.