реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Работа с прерываниями в WinAVR, Глобальные переменные в main и прерываниях
studert
сообщение Oct 17 2008, 11:07
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 76
Регистрация: 6-03-05
Из: Новосибирск
Пользователь №: 3 121



Задаю благозвучное название прерывания
#define PacketReceiveComplete INT5_vect

Объявлена глобальная переменная, значение которой
uint64t_t DestMAC;

Обработчик прерывания, функция getDestMAC записывает в переменную DestMAC нужные данные
ISR(PacketReceiveComplete){
cli();
getDestMAC(&DestMAC);
sei();
}
int main(void){
...
printf("%lx",DestMAC);
}
Это не работает, печатает мусор,причем попытки изменить DestMAC main тоже неудачны, она не меняется. Что я делаю не так?
Go to the top of the page
 
+Quote Post
_dem
сообщение Oct 17 2008, 11:12
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Код
#define PacketReceiveComplete INT5_vect

volatile uint64t_t DestMAC;

ISR(PacketReceiveComplete){
getDestMAC(&DestMAC);
}

int main(void){
...
printf("%lx",DestMAC);
}


ps. мое личное IMHO, использование int такого размера на 8-мибитнике для хранения MAC адреса - не лучшая идея.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 17 2008, 11:14
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(studert @ Oct 17 2008, 14:07) *
Что я делаю не так?
Попробуйте так

int main(void){
uint64t_t temp;
...
cli();
temp= DestMAC;
sei();
printf("%lx",temp);
}
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 17 2008, 11:27
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



volatile забыли. Иначе оптимизатор может выкинуть чтение перед выдачей.

Непонятно зачем cli в прерывании. Хотя смотря как вы вектор объявляли.
Go to the top of the page
 
+Quote Post
studert
сообщение Oct 17 2008, 11:28
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 76
Регистрация: 6-03-05
Из: Новосибирск
Пользователь №: 3 121



Цитата(Палыч @ Oct 17 2008, 18:14) *
Попробуйте так

int main(void){
uint64t_t temp;
...
cli();
temp= DestMAC;
sei();
printf("%lx",temp);
}

Так тоже не работает, если при попытке отправить в порт DestMAC выводится мусор, то как присвоив мусор другой переменной от него избавиться? Где и как нужно объявлять глобальные переменные, чтобы они были доступны всем подпрограммам?
Go to the top of the page
 
+Quote Post
aesok
сообщение Oct 17 2008, 11:33
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(studert @ Oct 17 2008, 15:07) *
Объявлена глобальная переменная, значение которой
uint64t_t DestMAC;


avr-libc-user-manual FAQ#1

Цитата(studert @ Oct 17 2008, 15:07) *
printf("%lx",DestMAC);


Уточните в avr-libc-user-manual поддерживает ли printf 64-битные типы.

Цитата(studert @ Oct 17 2008, 15:07) *
ISR(PacketReceiveComplete){
cli();
getDestMAC(&DestMAC);
sei();
}


Нельзя разрешать прерывания перед выходом из прерывания, они сами разрештся при выполнении инструкции RETI.

Анатолий.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 17 2008, 11:36
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Вы уверены, что функция printf выполняется после того, как в DestMAC будет что-то положено?
Go to the top of the page
 
+Quote Post
studert
сообщение Oct 17 2008, 11:45
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 76
Регистрация: 6-03-05
Из: Новосибирск
Пользователь №: 3 121



Цитата(SasaVitebsk @ Oct 17 2008, 18:27) *
volatile забыли. Иначе оптимизатор может выкинуть чтение перед выдачей.

Непонятно зачем cli в прерывании. Хотя смотря как вы вектор объявляли.

Ну cli это я от незнания поставил, первый раз с прерываниями работаю в этом компиляторе, до этого на асме только использовал. Я правильно понял, что компилятор сам поставит cli/sei? А volatile что-то тоже не помог. Может есть у кого пример, в котором по внешнему прерыванию изменяется какая-нибудь переменная, которая потом выводится в main?

Сообщение отредактировал studert - Oct 17 2008, 11:53
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 17 2008, 11:46
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(studert @ Oct 17 2008, 14:28) *
Так тоже не работает, если при попытке отправить в порт DestMAC выводится мусор, то как присвоив мусор другой переменной от него избавиться?
Переменная DestMAC занимает 8 байт. Чтобы 8-мибитному контроллеру переложить её значение из одной области памяти в другую (например, в стек при выполнении printf("%lx",DestMAC)) потребуется минимум 16 команд. Если при их выполнении произайдёт прерывание и изменится значение DestMAC, то получите значение: часть байтов - новые, часть - старые, т.е. что-то похожее на "мусор".
Go to the top of the page
 
+Quote Post
studert
сообщение Oct 17 2008, 11:55
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 76
Регистрация: 6-03-05
Из: Новосибирск
Пользователь №: 3 121



Цитата(aesok @ Oct 17 2008, 18:33) *
avr-libc-user-manual FAQ#1
Уточните в avr-libc-user-manual поддерживает ли printf 64-битные типы.
Нельзя разрешать прерывания перед выходом из прерывания, они сами разрештся при выполнении инструкции RETI.

Анатолий.

Спасибо за ответ. Действительно принтф не поддерживает 64 бит.
Go to the top of the page
 
+Quote Post
Kernigan
сообщение Oct 17 2008, 12:04
Сообщение #11





Группа: Новичок
Сообщений: 11
Регистрация: 17-10-08
Пользователь №: 41 018



Цитата(aesok @ Oct 17 2008, 14:33) *
Нельзя разрешать прерывания перед выходом из прерывания, они сами разрештся при выполнении инструкции RETI.

Можно конечно. Не запрещено.
Go to the top of the page
 
+Quote Post
mandrew
сообщение Oct 17 2008, 12:05
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 28-09-05
Пользователь №: 9 021



Цитата(studert @ Oct 17 2008, 15:07) *
Задаю благозвучное название прерывания
#define PacketReceiveComplete INT5_vect

Объявлена глобальная переменная, значение которой
uint64t_t DestMAC;

Обработчик прерывания, функция getDestMAC записывает в переменную DestMAC нужные данные
ISR(PacketReceiveComplete){
cli();
getDestMAC(&DestMAC);
sei();
}
int main(void){
...
printf("%lx",DestMAC);
}
Это не работает, печатает мусор,причем попытки изменить DestMAC main тоже неудачны, она не меняется. Что я делаю не так?


1) А просто printf у вас работает, если не использовать обработчиков прерываний по приему, по окончании передачи, по свободному регистру UDRn?
Go to the top of the page
 
+Quote Post
studert
сообщение Oct 17 2008, 12:27
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 76
Регистрация: 6-03-05
Из: Новосибирск
Пользователь №: 3 121



Цитата(mandrew @ Oct 17 2008, 19:05) *
1) А просто printf у вас работает, если не использовать обработчиков прерываний по приему, по окончании передачи, по свободному регистру UDRn?

Принтф работает, выводит все как положено, если 64 битные данные не кормить.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 17 2008, 12:48
Сообщение #14


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(studert @ Oct 17 2008, 16:27) *
Принтф работает, выводит все как положено, если 64 битные данные не кормить.

Ну так может тогда вместо uint64 сделать char[8] и кормить как строку символов?

Не, погорячился. Тогда точно мусор будет.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 17 2008, 13:31
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Никто не мешает разбить 64 бита на несколько ulong, uint или даже uchar (например, через union) и в printf использовать уже их. Тем более, что автору нужно шестнадцатиричное значение (не забыть, только, что выводить нужно с лидирующими нулями - поставить в формате соответствующие числа).
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th June 2025 - 07:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01475 секунд с 7
ELECTRONIX ©2004-2016