Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: перенос программы с IAR на AVR-GCC, нужна помощь...
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
PrSt
Нужно произвести операцию: (именно под linux-AVR-GCC)
перенос программы с IAR на GCC, помогите пожалуйста решить возникшую проблемку...
вероятно все проблеммы по не знанию тонкостей или ньюансов...
сам с AVR не работал до этого толком....
возникли проблеммы в частности с с прерыванием...

программа была написанная на IAR, какойто там версии под контроллер ATMEGA161 (хотя камень впаян 162)...
Но все это работает с HEX от IAR

а нужно перенести под GCC и довольствоваться результатом...

я программу эту портировал под GCC...
Местати что надо подправил под специфику компилятора, полазив по инету и подсмотрев как...
например кое что тут - http://www.avrfreaks.net/wiki/index.php/Do...GCC/IarToAvrgcc

Получил HEX
патаюсь его прошить - прошиваю, даже загорается на платке светодиод...
...но светодиод должен сменить свой цвет при возникновении прерывания и остаться с этим значением...
Однако этого не происходит...

вот как было под IAR
#pragma vector=INT1_vect
__interrupt void INT1_(void) // INT1 interrupt service routine
{
.....
while(1){LED_RED;}
}

вот как теперь стало под GCC
#pragma vector=INT1_vect
//__interrupt void INT1_(void) // INT1 interrupt service routine
ISR (INT1_vect) // INT1 interrupt service routine // veter
{
....
while(1){LED_RED;}
}

и не работает...
в интернете на многих сайтах говорится что делать так и оно обязанно работать...
почему у меня не работает? Может какието гдето регистры?


заранее Большое-Человеческое спасибо ответевшим!
defunct
Вроде все ок, #pragma - лишняя, но поидее GCC ее просто проигнорирует.

Может вы пропустили:
__enable_interrupt() --> sei()

?
PrSt
Цитата(defunct @ May 4 2007, 02:50) *
Вроде все ок, #pragma - лишняя, но поидее GCC ее просто проигнорирует.
Может вы пропустили:
__enable_interrupt() --> sei()
?

Да, Вы правы игнорирует, причем тихонько, без варнингов...
#pragma не привела ни к каким результатам - по этому я ее просто оставил...

на счет sei и cli - Использовались _SEI и _CLI я на всякий случай и в нижний регист переводил...
но позже нашел в хиделе что _CLI и _SEI задефайнены на sei и cli соответственно...

.
PrSt
Цитата(defunct @ May 4 2007, 02:50) *
Вроде все ок, #pragma - лишняя, но поидее GCC ее просто проигнорирует.
Может вы пропустили:
__enable_interrupt() --> sei()
?

о! наткнулся на подобное чтото
именно после вызова sei() программа не выходит из процедуры sei
// _SEI();
sei(); // veter
LED_RED;
так вот светодиод LED_RED - не загорается....

.
aesok
Версия avr-libc, все сообщения компилятора, больше кода....
Kuzmi4
Вообще то советовал бы поменять ISR на
SIGNAL (INT1_vect)
{
....
}
Далее посмотерть есть ли аддр этого кода с векторном пространстве.И если всё сошлось тогда просто посмотреть осцилографом - есть ли сигналы на входной лапке..
Да.. ещё, мож вы где просто отключаете прерывания - если программа у вас большая, потому если не сработает всё выше приведённое - попробуйте просто с голым мэйном и интеруптом.
PrSt
Цитата(aesok @ May 4 2007, 12:17) *
Версия avr-libc, все сообщения компилятора, больше кода....

а что именно из куда нужно?
...
status = 0x00;
status_minute = 0x00;
status_hour = 0x00;
status_month = rd_char(STATUS); //status_month = eeprom_status;
LED_RED; - вот здесь загорается светодиод... как и положено

// _SEI();
sei(); // veter
LED_RED; - вот здесь не загорается, такое впечятление что не выходит из прерывания...

delay_ms(1000);
....

avr-libc - тот что идет стандартный с debian etch
veter@server:~/for_gcc$ apt-cache showpkg avr-libc
Package: avr-libc
Versions:
1:1.4.5-2(/var/lib/apt/lists/_mnt_cd2_dists_stable_main_binary-i386_Packages)(/var/lib/apt/lists/Debian%20GNU_Linux%204.0%20r0%20%5fEtch%5f%20-%20Official%20i386%20DVD%20Binary-2%2020070407-11:40_dists_etch_main_binary-i386_Packages)(/var/lib/dpkg/status)

Reverse Depends:
avr-libc,avr-libc
gcc-avr,avr-libc 1:1.2.3-3
Dependencies:
1:1.4.5-2 - avr-libc (0 (null)) avr-gcc (1 1:3.4.3-2)
Provides:
1:1.4.5-2 -
Reverse Provides:
Igor26
Может попробовать заменить sei(); на ASM-вставку типа
asm("sei");?
Hz!
А вы разрешаете калие-либо другие прерывания?
Не может получиться так, что у вас постоянно вызывается прерывание от какой-ть другой переферии?
Или WDT?
aesok
Цитата(PrSt @ May 4 2007, 16:36) *
а что именно из куда нужно?


Какие заголочные файлы включены?

Цитата
// _SEI();
sei(); // veter
LED_RED; - вот здесь не загорается, такое впечятление что не выходит из прерывания...


Очень похоже что не правильно описаны обработчики прерываний, или не все.

Цитата
delay_ms(1000);


покажите код 'delay_ms' - тоже возможны ошибки.

При компиляции точно нет ни одного предупреждения?

Анатолий.
PrSt
Цитата(Hz! @ May 4 2007, 12:53) *
А вы разрешаете калие-либо другие прерывания?
Не может получиться так, что у вас постоянно вызывается прерывание от какой-ть другой переферии?
Или WDT?

WDT - отключен в конфиге...
по программе используется для профилактики сброс вачдога...

>Какие заголочные файлы включены?
//#include "iom161.h"
#include <avr/io.h>
#include <compat/ina90.h>

...
#include <avr/interrupt.h>
//#include <avr/signal.h>

>Очень похоже что не правильно описаны обработчики прерываний, или не все.
я нашел по ходу ошибку в ASM файле
было
;PORTA var 0x1b
;PINA var 0x19
;DDRA var 0x1a
;PORTC var 0x15
;PINC var 0x13

стало
#define PORTA 0x1B
#define PINA 0x19
#define DDRA 0x1A
#define PORTC 0x15
#define PINC 0x13

но ведь это не правильно...
;PORTA var 0x1b - это же заявляется адресс для PORTA
а #define PORTA 0x1B это было сделано временно...
так вот - еще вопросик...
как правильно в GCC в ASM файле корректно написать это?
(имеюю ввиду - аналог написанному в IAR - PORTA var 0x1b )

я подозреваю что проблемма именно тут а не в прерыванеии...
хотя и там может тоже...

>покажите код 'delay_ms' - тоже возможны ошибки.
void delay_ms(unsigned int t)
{ __watchdog_reset();
while(t--){
DelayUS(250);
DelayUS(250);
DelayUS(250);
// CLRWDT();
DelayUS(250);
}
__watchdog_reset();
}

>При компиляции точно нет ни одного предупреждения?
точно - При компиляции нет ни одного предупреждения...
Dog Pawlowa
Цитата(PrSt @ May 4 2007, 15:36) *
// _SEI();
sei(); // veter
LED_RED; - вот здесь не загорается, такое впечятление что не выходит из прерывания...

Вы строку из исходника вставили?
Может, правильнее записать LED_GREEN; wink.gif
defunct
Цитата(PrSt @ May 4 2007, 14:36) *
sei(); // veter
LED_RED; - вот здесь не загорается, такое впечятление что не выходит из прерывания...


Если у вас обработчик прерывания до сих пор такой:

..... (INT1_vect) // INT1 interrupt service routine // veter
{
....
while(1){LED_RED;}
}

То выхода из прерывания и не должно быть, т.к. там бесконечный цикл.
mdmitry
>Вообще то советовал бы поменять ISR на
>SIGNAL (INT1_vect)
>{
>....
>}
Запись обработчика прерывания зависит от версии компилятора. Указанная версия для старых версий AVR-GCC. В новых требуется ISR. Это описано в документации к компилятору и библиотекам.
defunct прав. Из этого обработчика нет выхода, кроме сторожевого таймера, а он отключен.
LED_RED - это что такое? Если запись в порт, то хотелось бы увидеть макро.
//#include "iom161.h" !!!!!! указан ли правильно тип процессора в makefile?
#include <avr/io.h>
#include <compat/ina90.h> это зачем, если код полностью переделан под GCC?
forever failure
Цитата
я нашел по ходу ошибку в ASM файле
было
;PORTA var 0x1b
/* ... */

стало
#define PORTA 0x1B


Коренное отличие GCC-ишного асма AVR от IAR-овского состоит в том, в GCC обращение к порту in/out делается через макроподстановку _SFR_IO_ADDR, т. е. Вам придётся в асмовском файле заменить все
in r**, PORT** на in r**, _SFR_IO_ADDR(PORT**).
Ну и проделать тоже с out, cbi, sbi. Тогда заработает.
ReAl
Цитата(forever failure @ May 5 2007, 06:07) *
Коренное отличие GCC-ишного асма AVR от IAR-овского состоит в том, в GCC обращение к порту in/out делается через макроподстановку _SFR_IO_ADDR, т. е. Вам придётся в асмовском файле заменить все
in r**, PORT** на in r**, _SFR_IO_ADDR(PORT**).
Ну и проделать тоже с out, cbi, sbi. Тогда заработает.


Не обязательно.
Можно сделать так:

Код
#define __SFR_OFFSET 0
.nolist
#include <avr/io.h>
.list

           .section .text
           .global main
main:
    ; запис в OSCCAL - перша операція, щоб не змінювалася адреса
    ; команди LDI
    ldi temp, 0x80    $ out OSCCAL, temp
    ldi temp, (1<<ACD) $ out ACSR, temp
    ; Вихід NO_VIDEO вмикається відразу як активний.
    ldi temp, 0x19 $ out PORTB, temp
    ldi temp, 0x0B $ out DDRB, temp


и не морочить себе голову этим _SFR_IO_ADDR
Да, они сами пишут, что лучше морочить :-), но я ленюсь писать многа букафф. Даже если вдруг они переделают sfr_defs.h так, что #define __SFR_OFFSET 0 перестанет работать - напущу SED на те из старіх исходников, которіе надо поддерживать.

Ну а если адреса портов заданы вручную через #define PORTB и т.п., то тогда _SFR_IO_ADDR противопоказан, так как адрес задан уже правильно.
mdmitry
В Си доступ к портам прост. Например, запись в порт А значения 0x5A:
POTRA = 0x5A;
Это описано в документации к библиотеке и FAQ.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.