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

 
 
> как бы реализовать условие?
naskar
сообщение May 17 2011, 10:45
Сообщение #1





Группа: Новичок
Сообщений: 6
Регистрация: 14-01-11
Пользователь №: 62 219



Здравствуйте. Программа по запросу с Мастера должна передать по SPI данные другому МК, но разрешенное временя на ожидание передачи ограничено. О говности Подчиненного к передаче сигнализирует соотв.уровень на линии порта С.
1. Запускается 16 разр. счетчик
2. Выставляем сигнал готовности
3. Ожидается запрос на передачу
4. Если запрос не произошел в течение периода пока счетчик не насчитал допустим 100 -> Конец подпрограммы.
5. Если пришел запрос в разрешенном интервале -> передача 3 байта данных -> Конец подпрограммы.
В общем вопрос такой - как организовать такой условный переход? МК mega48.
привожу отрывок программы:

void SPI_Transmit(unsigned long data)
{
SPDR=(unsigned char)(data>>16);
while(!(SPSR&(1<<SPIF)));
SPDR=(unsigned char)(data>>8);
while(!(SPSR&(1<<SPIF)));
SPDR=(unsigned char)data;
while(!(SPSR&(1<<SPIF)));
};

...
Запуск таймера;
...
ClearBit(PORTC,PORTC1); // transmit ready
SPI_Transmit(narabotka);
SetBit(PORTC,PORTC1); // busy
return;
};
...

Прошу прощения, написал не совсем в тему, прошу переместить в AVR.

Сообщение отредактировал naskar - May 17 2011, 10:46
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
smalcom
сообщение May 18 2011, 14:25
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



эммм, есть конструкция с оператором if
Go to the top of the page
 
+Quote Post
naskar
сообщение May 18 2011, 16:27
Сообщение #3





Группа: Новичок
Сообщений: 6
Регистрация: 14-01-11
Пользователь №: 62 219



Цитата(smalcom @ May 18 2011, 18:25) *
эммм, есть конструкция с оператором if

И что? поставлю я if, выполнится это условие, начнет выполнятся п\п, вопрется в первый же while и будет ждать запрос на передачу. Счетчик пройдет допустимое значение, а цикл так и будет продолжать ждать, а нужно чтобы он в этот момент завершил выполнение подпрограммы и вернулся в главный цикл...

Поэтому я подумал, что если сделать так, чтобы в тот момент когда счетчик досчитал до допустимого значения, а запроса на передачу так и не произошло - происходит прерывание, а в теле обработчика прерывания записать в стек адрес возврата в гл. программу, и указатель после return минуя цикл передачи перейдет сразу в тело главного цикла main, так cработает?
например, очень упрощенно:


//-----------------------------SPI_transmit_func-------------------------------------//

void SPI_Transmit(unsigned long data)
{
SPDR=(unsigned char)(data>>16);
while(!(SPSR&(1<<SPIF))) // Ждем запроса на передачу
ClearBit(TIMSK1,OCIE1B); //Отключаем прерывание по В
SPDR=(unsigned char)(data>>8);
while(!(SPSR&(1<<SPIF)))
SPDR=(unsigned char)data;
return;
};

//---------------------------Timer_1_interrupt_B---------------------------------------//

#pragma vector = TIMER1_COMPB_vect // Счетчик досчитал до 100, передача не произошла, нам нужно вернуться обратно в main
__interrupt void timer_compb_isr(void)
{
SetBit(PORTC,PORTC1); // busy
ClearBit(TIMSK1,OCIE1B); // Отключаем прерывание по В
SP = adr; // Заполняем обратно в стек адрес возврата - так можно делать? вернемся ли мы в main?
return;
};

//---------------------------Timer_1_interrupt_A--------------------------------------//

#pragma vector = TIMER1_COMPA_vect
__interrupt void timer1_compa_isr(void) //таймер 1 переполнился
{
adr = SP; // Адрес возврата в main - так можно делать? заполнится ли в adr реальный адрес возврата???
.
.
SetBit(TIMSK1,OCIE1B); // Включаем прерывание по В
ClearBit(PORTC,PORTC1); // готов к передаче
SPI_Transmit(narabotka); // идем на пп передачи см.выше
SetBit(PORTC,PORTC1); // занят
return;
};

//------------------------------main-----------------------------------//

int main(void)
{
.
OCR1A = 32000;
OCR1B = 100;
SetBit(TCCR1B,CS11); // 0b00001010 T/C1 run in CTC mode f = Fclk/8.
.
.
while(1)
{
//ждем прерывание А, прерывание В пока отключено
};
}

Сообщение отредактировал naskar - May 18 2011, 16:30
Go to the top of the page
 
+Quote Post
smalcom
сообщение May 18 2011, 21:00
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



Цитата
И что? поставлю я if, выполнится это условие, начнет выполнятся п\п, вопрется в первый же while и будет ждать запрос на передачу. Счетчик пройдет допустимое значение, а цикл так и будет продолжать ждать, а нужно чтобы он в этот момент завершил выполнение подпрограммы и вернулся в главный цикл...

это что за высер, извиняюсь? каков вопрос, таков ответ.

Цитата
а в теле обработчика прерывания записать в стек адрес возврата в гл. программу

у японцев есть ежегодный конкурс на самое сложное воплощение самого простого процесса.

Для реализации и надо то, что цикл и флаг таймаута, всё
Go to the top of the page
 
+Quote Post
XVR
сообщение May 19 2011, 06:03
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Алгоритм:
1) Кладем первый байт передаваемых данных в SPDR
2) Выставляем бит готовности (1 бит в порту С) и запускаем таймер
3) Ждем бит SPIF в SPSR или таймаута от таймера
4) Дождались SPIF в SPSR - отправляем остаток данных, не дождались (таймер сработал) - не отправляем данные
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 19 2011, 06:12
Сообщение #6


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Это означает, что процесс монопольный?
Т.е. можно ждать тайм-аута без риска задержать обработку других событий?
Go to the top of the page
 
+Quote Post
zombi
сообщение May 19 2011, 06:50
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(_Pasha @ May 19 2011, 09:12) *
Это означает, что процесс монопольный?
Т.е. можно ждать тайм-аута без риска задержать обработку других событий?

Если я правильно понял, то TS именно об этом и пишет: ->Конец подпрограммы
Цитата(naskar @ May 17 2011, 13:45) *
4. Если запрос не произошел в течение периода пока счетчик не насчитал допустим 100 -> Конец подпрограммы.
5. Если пришел запрос в разрешенном интервале -> передача 3 байта данных -> Конец подпрограммы.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 19 2011, 06:59
Сообщение #8


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zombi @ May 19 2011, 09:50) *
Если я правильно понял, то TS именно об этом и пишет: ->Конец подпрограммы

Дык все равно, я бы лично на прерываниях делал
1. ПП организует старт обмена (инициализация таймера, SPI, их прерываний и выставление готовности)
2. По прер. от таймера - запрет таймера и SPI
3. По прер. SPI - прием запроса на передачу, если есть - запрет таймера. Ожидание пакета, прием его и выставление флага "принято"

Сообщение отредактировал _Pasha - May 19 2011, 07:00
Go to the top of the page
 
+Quote Post
DpInRock
сообщение May 19 2011, 10:18
Сообщение #9


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Есть такая штука - АВТОМАТ СОСТОЯНИЙ. Погуглите.
Можно реализовывать любое количество любых алгоритмов. Как НЕЗАВИСИМЫХ друг от друга, так и взаимозависимых. С любыми бесконечными циклами ожидания, которые никак не мешают другим процессам идти своим чередом.

И все это разумеется без всяких там прерываний и прочих вещей.
Как бэ классика жанра. Как бэ основа, на которой строятся ЛЮБЫЕ программы. И этим пользуется любой программист.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
naskar
сообщение May 19 2011, 11:09
Сообщение #10





Группа: Новичок
Сообщений: 6
Регистрация: 14-01-11
Пользователь №: 62 219



Всем спасибо за ответы. Вопрос решен. Тему можно закрыть. sm.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение May 19 2011, 12:09
Сообщение #11


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(naskar @ May 19 2011, 14:09) *
Всем спасибо за ответы. Вопрос решен. Тему можно закрыть. sm.gif

Делаете простой SPI драйвер 1 для всех проектов, который будет только заниматься тем что передавать данные из очереди которые ему дали (кольцевой буфер), в SPI. Есть в очереди данные - взводить флаг готовности, закончились в очереди данные - опускать флаг готовности. По прерыванию от SPI брать следующий байт из очереди и т.д. пока есть что передавать.

Далее когда устройство готово - даете драйверу 3 байта, и работаете себе дальше. Драйвер сам отправит когда мастер попросит. Если мастер не попросил за отведенный интервал - то следующей порцией данных просто перетираете предыдущую. Вот и всё.
Go to the top of the page
 
+Quote Post
naskar
сообщение May 20 2011, 14:33
Сообщение #12





Группа: Новичок
Сообщений: 6
Регистрация: 14-01-11
Пользователь №: 62 219



Почитал про автоматы состояний и кольцевые буферы. Хорошая идея. Пожалуй так и сделаю! так действительно удобней будет. спасибо!
Go to the top of the page
 
+Quote Post

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

 


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


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