CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

так это так и будет байт пришел-прерывание.
для заполнения буфера

Код: Выделить всё

//прерывание  приема байта
static char k;
static char RX_bufer[RX_BUFFER_SIZE-1];
if (k<(RX_BUFFER_SIZE-1))RX_bufer[k++]=UDR;
else setFlagRX_full;
// основной цикл
  for (i=0,i <=(RX_BUFFER_SIZE-1),i++) //достаем побайтно можно сразу достать RX_bufer[14]
но будет ли это тот символ,что вы ожидаете.вообще там сложный алгоритм должен быть,чтобы обеспечить правильность данных.

 
Последний раз редактировалось vitalik_1984 Вс фев 26, 2012 19:42:13, всего редактировалось 1 раз.
В поисках истины человек развивается.
Контактная информация:
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 422
Зарегистрирован: Ср дек 26, 2007 18:33:00

Сообщение v000va »

так это так и будет байт пришел-прерывание.
Спасибо за ответ. Но зачем тогда буфер? По какому принципу он заполняется?

И еще вопрос. Процессор Мега8, испольщую ШИМ, выводится на пин PB3(Mosi/OC2), как только инициализирую SPI, модуляция ШИМ пропадает. SPI тоже использует РВ3 как MOSI, но мне он не нужен, я использую только MISO и SCK. РВ3 определен как выход с подтяжкой 5В. Я так понимаю, что перед использованием ШИМ, SPI процессора следует выключать?
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

буфер нужен для вашего удобства.буфер заполнился- отправили нак(nack) и передающей ждет следующий ак(ack) .

спи неактивно, насколько я понял,если не включен usart или usi.а так вы правильно сказали нужно выключить.
и порт нельзя внутренне настроить на выход С ПОДТЯЖКОЙ на пять вольт.
только при входе можно.
если у вас снаружи резистор,то при лог ноль на выходе будет тратиться энергия.
В поисках истины человек развивается.
Контактная информация:
Родился
Сообщения: 16
Зарегистрирован: Ср мар 04, 2009 06:57:47
Откуда: Москва

Сообщение Vatson4ik »

Здравствуйте! Подскажите, пожалуйста, каким образом можно выйти из прерывания не в точку его возникновения, а например в начало цикла основного кода. Пробую оператор goto, но он, находясь в программе обработки прерывания, не видит метку, находящуюся в основном коде.
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

Ну это, похоже, проще ассемблерской ставкой сделать.
Перед выходом из прерывания (на асме команда RETI) требуется:
1) Взять из стека адрес возврата и отправить его в \dev\null
2) Положить нужный адрес
Ну а потом уже выходить.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1116
Зарегистрирован: Чт окт 15, 2009 14:16:18
Откуда: Екб

Сообщение AI_Disable »

IfoR писал(а):Ну это, похоже, проще ассемблерской ставкой сделать.
Перед выходом из прерывания (на асме команда RETI) требуется:
1) Взять из стека адрес возврата и отправить его в \dev\null
2) Положить нужный адрес
Ну а потом уже выходить.
Ага. Утечки памяти обеспечены. Такой способ можно использовать только в крайнем случаи и если вы чётко понимаете логику работы. Иначе, лучше так:
Ставим в прерывании флаг.
В основной бесконечный цикл встраиваем ещё один цикл, опрашивающий флаг. Как только флаг появится - вылетаем в основной.

Код: Выделить всё

volatile char flag=0;

int main()
{
while(1) //основной
{
	//код
	while(!flag)
		{
		//код
		}
	flag=0;
}
}

ISR(вектор)
{
//код
flag=1;
}
Последний раз редактировалось AI_Disable Пн фев 27, 2012 18:50:04, всего редактировалось 1 раз.
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

Так а контроллер ведёт чтоли карту памяти с использует динамические переменные? Какие тут могут быть утечки если всё в памяти расположено более-менее статично?
Я не против данного решения, точнее за, но вопрос автора был в этом.

А если речь идёт про установку компилятором POP-ов перед выходом, то это сложнее. У GCC-AVR, например, можно отключить пре\пост-фиксный код в функциях прерываний и расставлять эту всю радость вручную. Как это сделать в CVAVR не знаю.
Последний раз редактировалось IfoR Пн фев 27, 2012 18:52:55, всего редактировалось 1 раз.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город

Сообщение Мастер Ломастер »

Vatson4ik писал(а):Здравствуйте! Подскажите, пожалуйста, каким образом можно выйти из прерывания не в точку его возникновения, а например в начало цикла основного кода. Пробую оператор goto, но он, находясь в программе обработки прерывания, не видит метку, находящуюся в основном коде.
вы можете меня не слушать, но я бы категорически настаивал бы на совете не делать такой глупости.

если все же не хотите послушать этого совета - курите про longjmp в setjmp.h
битва с дураками проиграна, победители торжествуют. слава победителям!
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1116
Зарегистрирован: Чт окт 15, 2009 14:16:18
Откуда: Екб

Сообщение AI_Disable »

IfoR, например, прерывание может произойти, когда выполняется какая-либо функция. При переходе в начало программы в стеке останется адрес возврата и все локальные переменные...
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

Ну тогда обнулять, нафиг, указатель стека и возвращаться на reset. :)
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Родился
Сообщения: 16
Зарегистрирован: Ср мар 04, 2009 06:57:47
Откуда: Москва

Сообщение Vatson4ik »

Спасибо за советы. Попробую задать вопрос конкретней.
#include <tiny2313.h>
#include <delay.h>

// Analog Comparator interrupt service routine
interrupt [ANA_COMP] void ana_comp_isr(void)
{
// Place your code here

}

// Declare your global variables here

void main(void)
PORTB=0x00;
DDRB=0x04;
ACSR=0x4B;
#asm("sei")
while (1)
{
// Place your code here
PORTB.2=0;
delay_ms(15000);
PORTB.2=1;
delay_ms(15000);
}
Прерывание может произойти во время задержки которая подчеркнута, и требуется сразу перейти на начало программы.
Может кто подскажет как это лучше реализовать?(а то вышесказанное мне не очень понятно)
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город

Сообщение Мастер Ломастер »

Vatson4ik писал(а):Прерывание может произойти во время задержки которая подчеркнута, и требуется сразу перейти на начало программы.
ЗАЧЕМ???
битва с дураками проиграна, победители торжествуют. слава победителям!
Контактная информация:
Родился
Сообщения: 16
Зарегистрирован: Ср мар 04, 2009 06:57:47
Откуда: Москва

Сообщение Vatson4ik »

задача такова:
1 час заряжается батарея, 1 час не заряжается(в тексте кода указано 15 секунд для ускорения эксперимента). Если во время простоя напряжение падает ниже заданного, то надо сразу начинать зарядку.
Я понимаю что есть вариант постоянной проверки бита ASCR.5 но получается очень громоздко. Поэтому и ищу вариант с выходом из прерывания
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город

Сообщение Мастер Ломастер »

Vatson4ik писал(а):надо сразу начинать зарядку.
то есть задержка в несколько микросекунд категорически недопустима?
битва с дураками проиграна, победители торжествуют. слава победителям!
Контактная информация:
Родился
Сообщения: 16
Зарегистрирован: Ср мар 04, 2009 06:57:47
Откуда: Москва

Сообщение Vatson4ik »

Допустима. Поясните, пожалуйста
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Код: Выделить всё

// Analog Comparator interrupt service routine
interrupt [ANA_COMP] void ana_comp_isr(void)
{
// Place your code here
asm("rjmp 0");
}
Docendo discimus
Контактная информация:
Встал на лапы
Сообщения: 148
Зарегистрирован: Ср дек 29, 2010 21:19:03

Сообщение c717411 »

if (flag_comparator) zaryadka();
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

Ну вот. Проблема решена радикальным путём. :)
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город

Сообщение Мастер Ломастер »

вам теоретически вообще прерывания ни к чему: тупейшим образом опрашиваете уровень на выходе компаратора и в нужный момент делаете то, что нужно...
битва с дураками проиграна, победители торжествуют. слава победителям!
Контактная информация:
Родился
Сообщения: 16
Зарегистрирован: Ср мар 04, 2009 06:57:47
Откуда: Москва

Сообщение Vatson4ik »

Спасибо всем за помощь :)
Ответить

Вернуться в «AVR»