|
От HELP MEGA8 к вопрос по IAR!, Переходим с проблемы на проблему! |
|
|
|
Jun 21 2005, 11:40
|
Местный
  
Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526

|
Я два дня назад создал тему HELP MEGA8. Спасибо всем, кто откликнулся. Однако, проблема оказалась совсем не в подключении кристалла, в совершенно в другом месте! Проблема оказалась в IAR 4.10B/W32 (4.10.2.5). Вот такой код на С: #include <iom8.h>
int main( void ) { long unsigned int i; DDRB|= (1<<1);
while(1) {
PORTB^=(1<<1); i=0xffff; while (i--); } } все догадались, что должно произойти. Диод на PB1 должен моргать. Однако, камень запускается раз на 4 - 5 включений питания. (Все подтянуто, все сглажено).
Меняем проект на: .include "m8def1.inc"
begin:
ldi r16,low(RAMEND) out spl,r16 ldi r16,high(RAMEND) out sph,r16
ldi r16,(1<<1) out DDRB,r16
; основной цикл программы loop: ldi r16,(1<<1) ; светится один светодиод out PORTB,r16 rcall delay ; задержка ldi r16,(0<<1) ; теперь гасим его out PORTB,r16 rcall delay ; задержка rjmp loop ; повторение цикла
; процедура задержки ; примерно полсекунды при частоте 7,37 МГц ; три пустых вложенных цикла соответственно delay: ldi r16,30 ; 30 delay1: ldi r17,200 ; 200 delay2: ldi r18,200 ; и еще 200 итераций delay3: dec r18 brne delay3 dec r17 brne delay2 dec r16 brne delay1 ret вот такая нехитрая замена, сгенеренная в AVRStudio 4. Все работает как часы!!!Вопросов нет!!! То есть есть, но уже к знатокам IAR!!! Компилю проект с опциями: оптимизация отключена кристалл - м8 модель Small Подскажите, ведь не может быть, что IAR не может работать с этим типом контроллеров!!! Понимаю, что сам дурак, но в чем???
|
|
|
|
|
Jun 21 2005, 12:14
|
Частый гость
 
Группа: Validating
Сообщений: 149
Регистрация: 11-02-05
Из: Рязань
Пользователь №: 2 574

|
Цитата(yung @ Jun 21 2005, 15:59) Только сейчас бросилось в глаза. А почему main описан как int, а не void? Не здесь ли собака зарыта? Я суда тоже сразу посмотрел но yung меня опередил хотя ведь программа то всеравно встает в цикл while(1) { PORTB^=(1<<1); i=0xffff; while (i--); } } и по идее никаких возвратов в никуда быть не должно может быть правда компилятор это как то не коректно интерпритирует у меня всегда было void main(void) {}
|
|
|
|
|
Jun 21 2005, 12:26
|
Местный
  
Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526

|
Цитата(Miron @ Jun 21 2005, 15:14) Цитата(yung @ Jun 21 2005, 15:59) Только сейчас бросилось в глаза. А почему main описан как int, а не void? Не здесь ли собака зарыта? Я суда тоже сразу посмотрел но yung меня опередил хотя ведь программа то всеравно встает в цикл while(1) { PORTB^=(1<<1); i=0xffff; while (i--); } } и по идее никаких возвратов в никуда быть не должно может быть правда компилятор это как то не коректно интерпритирует у меня всегда было void main(void) {} Да, эта ошибочка вкралась, т.к. это была тестовая функция, самафорящая, что программа дошла до определенной точки. Вот int и осталось в наследство. Это решило проблему локально в этой коротенькой программке, но не решило в проекте. Там main объявлена как void. А весь сыр - бор проистекает именно от того, что не пускается проект... Хотя, наверное, у меня на что-тот еще глаз замылился. Ведь чудес не бывает... Посмотрим... Отпишу что и как...
|
|
|
|
|
Jun 21 2005, 12:49
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 3-03-05
Из: Санкт-Петербург
Пользователь №: 3 037

|
Цитата(yung @ Jun 21 2005, 14:59) Только сейчас бросилось в глаза. А почему main описан как int, а не void? Не здесь ли собака зарыта? main надо описывать как int в случае, если в опциях проекта указан режим C++, а как void, если просто C.
|
|
|
|
|
Jun 21 2005, 13:09
|
Местный
  
Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526

|
Цитата(NickB @ Jun 21 2005, 15:39) Напишите вместо while (i--); таким образом while (--i); и будет вам счастье (Проверил в версии 3.20.С) Не, не будет счастья... Потому, что хрен редьки не толще... ничего не поменялось... Микросхема запускается через раз, моргает диодом почему-то в четверть накала, иногда в полный накал... Не понимаю, чтот происходит. Микросхема запрограммирована, один раз запускаю - работаеет в четверть накала, другой раз - нормально. На асме таких проблем нет!
|
|
|
|
|
Jun 21 2005, 13:23
|
Местный
  
Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526

|
Цитата(NickB @ Jun 21 2005, 15:28) Надобно посмотреть что за код генерирует компилятор Ну и настройки стека Вот код на С: void main( void ){ unsigned int pause; DDRB|= (1<<PB1); for(;;) { PORTB^=(1<<PB1); pause = 0xffff; while(--pause); } } вот перевод на асм: // 19 DDRB|= (1<<PB1); SBI 0x17, 0x01 // 20 // 21 for(;;) // 22 { // 23 PORTB^=(1<<PB1); ??main_0: LDI R16, 2 IN R17, 0x18 EOR R17, R16 OUT 0x18, R17 // 24 // 25 pause = 0xffff; LDI R24, 255 LDI R25, 255 // 26 while(--pause); ??main_1: SBIW R25:R24, 1 MOVW R31:R30, R25:R24 MOVW R25:R24, R31:R30 OR R30, R31 BRNE ??main_1 RJMP ??main_0 ничего крамольного... вроде, все логично... но камень запускается через раз, и не всегда ярко моргает диод.
|
|
|
|
|
Jun 21 2005, 13:36
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Sergio66 @ Jun 21 2005, 17:40) Я два дня назад создал тему HELP MEGA8. Спасибо всем, кто откликнулся. Однако, проблема оказалась совсем не в подключении кристалла, в совершенно в другом месте! Проблема оказалась в IAR 4.10B/W32 (4.10.2.5). Вот такой код на С: #include <iom8.h> int main( void ) { long unsigned int i; DDRB|= (1<<1); while(1) { PORTB^=(1<<1); i=0xffff; while (i--); } } все догадались, что должно произойти. Диод на PB1 должен моргать. Однако, камень запускается раз на 4 - 5 включений питания. (Все подтянуто, все сглажено). Этот код (в цикле который) порождает: Код while(1) {
PORTB^=(1<<1); ??main_0: E002 LDI R16, 2 B318 IN R17, 0x18 2710 EOR R17, R16 BB18 OUT 0x18, R17 i=0xffff; while (i--); CFFB RJMP ??main_0 } Т.е. реально задержки, как видно, никаой нет. Просто компилятор посмотрел тут, что ничего содержательного в цикле while (i--); не делается, поэтому решил, что этот цикл надо заоптимизировать, с чем он успешно справился.  А вот если объявить i как volatile, то тогда он (компилятор) уже не будет иметь права делать какие-либо оптимизации на ее счет и получится реальный цикл: Код int main( void ) { volatile unsigned int i; DDRB|= (1<<1);
while(1) { PORTB^=(1<<1); i=0xffff; while (i--); } }
РЕЗУЛЬТАТ:
while(1) {
PORTB^=(1<<1); ??main_0: E002 LDI R16, 2 B318 IN R17, 0x18 2710 EOR R17, R16 BB18 OUT 0x18, R17 i=0xffff; EF0F LDI R16, 255 8308 ST Y, R16 8309 STD Y+1, R16 while (i--); ??main_1: 8108 LD R16, Y 8119 LDD R17, Y+1 01C8 MOVW R25:R24, R17:R16 9701 SBIW R25:R24, 1 8388 ST Y, R24 8399 STD Y+1, R25 2B01 OR R16, R17 F7C1 BRNE ??main_1 CFF0 RJMP ??main_0 } Как видно, цикл тут получился не в две инструкции. Т.е. если цель была сформировать задержку, то тут придется конкретно подбирать количество циклов. Сие не есть гуд и для оной цели у IAR'а есть специальная функция __delay_cycles(unsigned long), которая заставляет компилятор корректно сгенерировать задержку из указанного количества циклов. Кстати, что за тип такой странный - long unsigned int i;? И еще не понял, почему то запускалось, то нет. Не вижу связи с кодом. По логике оно просто должно было маслать в цикле без задержки, т.е. на ноге должны были быть переключения с периодом цикла инверсии состояния пина. Что-то там еще есть, что не попало в наше поле зрения.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|