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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Циклический буфер на AVR, (Примеры применения)
mse
сообщение Sep 1 2007, 09:23
Сообщение #31


Знающий
****

Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693



Цитата(prottoss @ Sep 1 2007, 13:02) *
Ну Вы прям как Бил Гейтс и Ко smile.gif

ИМХО разарботчик обязан сделать так, чтобы его программа не вешалась от добавления пары строк кода где угодно и когда угодна. А взять глубину буфера какую вздумается можно на пне4 и ижесними

Ну и каким местом ваш поток сознания к теме? А уж, тем более, к цытируемому?
Где я написал "взять глубину буфера какую вздумается". Здесь, что-ли "...обязан оценить эту загрузку и взять глубину буфера, чтобы...". Т.е. оценить и ПОСЧИТАТЬ, это "какое вздумается"? Толково!
Цитата
...обязан сделать так, чтобы его программа не вешалась от добавления пары строк...
Ага, обязан сказать:" по счучьему велению, не вешайся, программа, от добавления пары строк!"
Добавил пару строк - посчитай, добавь глубины, если надо. Потому как за твоих "пару строк" вполне может из линии насыпаться в два раза больше байтиков, чем без них.
Go to the top of the page
 
+Quote Post
alcosar
сообщение Sep 2 2007, 18:55
Сообщение #32


Участник
*

Группа: Участник
Сообщений: 44
Регистрация: 30-03-06
Пользователь №: 15 598



[quote name='=GM=' date='Aug 31 2007, 18:12' post='289675']
Здесь логическая ошибка, вы всё время читаете из одной и той же ячейки памяти. Идея сделать отдельный счётчик на заполнение буфера мне кажется здравой, надо обдумать на досуге.
[quote]

Спасибо за поправку. Вроде бы теперь правильно.

Код
;------------------------------------------------
read_buf:
;------------------------------------------------
; возвращает байт в r16
; используются регисты r16, r17, r26, r27, r28, r29

; в Y адрес структуры, задающей буфер    
    ldi    YL, LOW(buf)
    ldi    YH, HIGH(buf)

    mov    XL, YL
    mov    XL, YL
        
    clr      r17
    ld     r16, Y+1
    add    XL, r16
    adc    XH, r17

; c = buf[rindex]
    ldd    r16, X

    cli

; count--
    ld    r17, Y
    dec    r17
    st    Y, r17
    
; rindex = (rindex + 1) & BUF_SIZE - 1
    ldd    r17, Y+1
    dec    r17
    andi    r17, BUF_SIZE-1
    std    Y+1, r16
    sei
    ret


Сообщение отредактировал alcosar - Sep 2 2007, 19:17
Go to the top of the page
 
+Quote Post
=GM=
сообщение Sep 3 2007, 11:54
Сообщение #33


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



To alcosar

1) Здесь: std Y+1,r16 у вас ошибка, надо было r17 написать.
2) Счётчик занятых ячеек вполне может заменить статус буфера: 0-пустой, BUF_SIZE-полный.
3) Недостаток, что очень много регистров используется, аж 6 штук. Уже показывал более простое решение (см. пост #14). Вот адаптированная под ваш вариант программа. В три раза короче и в три раза быстрее. Использует три регистра.

;чтение байта из циклического буфера buffer в регистр data
Код
rdbyte: lds   xl,tail        ;указатель
        ldi   xh,high(buffer);на чтение
        ld    data,x+        ;прочитаем байт
        andi  xl,bufsize-1   ;держим указатель
        sts   tail,xl        ;в рамках
        ret

3) Кстати, что будет выдавать ваша программа, если буфер пуст? Предыдущие значения, поскольку count пойдёт в минус(:-)? Как сказал =mse=, и он 100% прав, пустой буфер-нередкая штатная ситуация.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Sep 3 2007, 14:31
Сообщение #34


Гуру
******

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



Цитата(prottoss @ Aug 31 2007, 21:57) *
В полезности циклических буферов я нисколько не сомневаюсь smile.gif и сам оччень часто их применяю. НО, очень мало, это сколько? smile.gif допустим применительно к АВР и его USART. Просто не вижу большого смысла тщательно рассказывать, как забивать гвозди...

Для реализации достаточно самого буфера + два указателя.
1. Размер буфера оцениваю исходя из из того что быстрее работает. Например IBM накачивает быстрее чем AVR разгребает. В этом случае размер приёмного буфера для AVR при 485 интерфейсе составляет два размера пакета + 5-6 байт. Для 232 интерфейса приблизительно 1к. Дальнейшее увеличение размера буфера даёт незначительный рост производительности.
2. Размер указателей зависит от размера буфера. Если буфер менее 256 байт, то указатели - байтовые, если больше то 2.
3. Если использую пакетную передачу, то, как я и описывал вводится ещё один указатель (недостоверных данных)
4. Если используется конвертер из одного интерфейса в другой, то некоторые указатели совмещаются размер буфера увеличивается.
Цитата
Почему нет ни единого примера на Си?
А когда хвост догнал голову, а он важнее (ибо прерывание) получается баальшой булик lol.gif

Честно говоря не понял шутки. Если буфер обнулён, то просто прекращается передача. Если заполнен ПОЧТИ полностью, то выполняется приостановка канала любым способом "управления потоком" - либо установкой сигнала CTS (HARD) либо передачей символа XOFF(SOFT). Буфер должен быть расчитан на приём 16 байт с момента выдачи остановки приёма. При работе с 485, очевидно, что вы сами должны следить за заполнением буфера. Но при чём здесь кольцевой буфер??? Если вы не справляетесь с приёмом, то управление потоком должно быть реализовано в любом случае.
Цитата
Кроме анальгина

Вы просто не работали с большими потоками данных например в четыре стороны. Иначе, простите за эмоции, вы бы бред не писали.

Кольцевой буфер это один из очень красивых алгоритмов. И, при правильной реализации, даёт разработчику возможность скрыть все тонкости приёма/передачи внутри драйвера. Поэтому, возможно, мало примеров. Так как придётся вычищать некоторые мелкие моменты.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 3 2007, 15:03
Сообщение #35


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
2. Размер указателей зависит от размера буфера. Если буфер менее 256 байт, то указатели - байтовые, если больше то 2.

Простите, но непонятно, как Вы меняете размер указателя или что подразумеваете под "размер указателя"


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Sep 3 2007, 15:14
Сообщение #36


Гуру
******

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



Цитата(sensor_ua @ Sep 3 2007, 18:03) *
Простите, но непонятно, как Вы меняете размер указателя или что подразумеваете под "размер указателя"

Естественно на стадии написания программы. Просто prottoss спрашивал размер потребляемой памяти, вот я и написал.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 3 2007, 17:51
Сообщение #37


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
Естественно на стадии написания программы

Рация на танке(С)
Указатели обычно имеют размерность шины адресаwink.gif или чуть более - для AVR это 16 бит и несколько больше в случае использования __generic в компиляторе IAR.
Похоже имелись в виду не указатели, а индексы. Тогда оптимально будет короткие (до 256 байт) буферы размещать по адресам, кратным 256 (о примерно таком говорил =GM= в начале топика), тогда можно получить выигрыш и в объёме кода, и в скорости выполнения.


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
=GM=
сообщение Sep 3 2007, 19:25
Сообщение #38


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(sensor_ua @ Sep 3 2007, 17:51) *
Указатели обычно имеют размерность шины адресаwink.gif или чуть более - для AVR это 16 бит и несколько больше в случае использования __generic в компиляторе IAR.
Похоже имелись в виду не указатели, а индексы. Тогда оптимально будет короткие (до 256 байт) буферы размещать по адресам, кратным 256 (о примерно таком говорил =GM= в начале топика), тогда можно получить выигрыш и в объёме кода, и в скорости выполнения.

Именно указатели, хотя памяти в АВРках - кот наплакал 0.5-1.0-2.0 Кбайта, редко больше. Но тем не менее, указатель 16-битный и занимает парные регистры x, y или z. В части приведённых программ старшая часть адреса присутствует как бы за кадром, поскольку она не меняется, установили её один раз в программе и забыли.

Обратите внимание на завершенную подпрограмму чтения байта из кольцевого буфера в посте #33. В паре регистров (xh,xl) находится честный 16-битный указатель на чтение, младшая часть которого хранится в ячейке tail.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Sep 3 2007, 19:33
Сообщение #39


Гуру
******

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



Цитата(sensor_ua @ Sep 3 2007, 20:51) *
Рация на танке(С)
Указатели обычно имеют размерность шины адресаwink.gif или чуть более - для AVR это 16 бит и несколько больше в случае использования __generic в компиляторе IAR.
Похоже имелись в виду не указатели, а индексы. Тогда оптимально будет короткие (до 256 байт) буферы размещать по адресам, кратным 256 (о примерно таком говорил =GM= в начале топика), тогда можно получить выигрыш и в объёме кода, и в скорости выполнения.

Имелись в виду указатели. Что вас смущает. Хранятся младшие байты указателей. Старшие - фиксированы. Где танк?
Посмотрите топик 6. В условиях экономии памяти вполне применимо.
Go to the top of the page
 
+Quote Post
alcosar
сообщение Sep 3 2007, 19:33
Сообщение #40


Участник
*

Группа: Участник
Сообщений: 44
Регистрация: 30-03-06
Пользователь №: 15 598



Цитата(=GM= @ Sep 3 2007, 14:54) *
To alcosar

1) Здесь: std Y+1,r16 у вас ошибка, надо было r17 написать.
2) Счётчик занятых ячеек вполне может заменить статус буфера: 0-пустой, BUF_SIZE-полный.
3) Недостаток, что очень много регистров используется, аж 6 штук. Уже показывал более простое решение (см. пост #14). Вот адаптированная под ваш вариант программа. В три раза короче и в три раза быстрее. Использует три регистра.

;чтение байта из циклического буфера buffer в регистр data
Код
rdbyte: lds   xl,tail    ;указатель
        ldi   xh,high(buffer);на чтение
        ld    data,x+    ;прочитаем байт
        andi  xl,bufsize-1  ;держим указатель
        sts   tail,xl    ;в рамках
        ret


3) Кстати, что будет выдавать ваша программа, если буфер пуст? Предыдущие значения, поскольку count пойдёт в минус(:-)? Как сказал =mse=, и он 100% прав, пустой буфер-нередкая штатная ситуация.

1. Эх. Разгилдяй я.
2. Полный еще не значит переполненный.
3. Перед обращением к чтению нужно смотреть сколько байт в буфере.
Код
rdbyte: lds   xl,tail    ;указатель
        ldi   xh,high(buffer);на чтение

здесь мне непонятно как сформирован указатель чтения.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 3 2007, 19:50
Сообщение #41


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
Что вас смущает.

Цитата
2. Размер указателей зависит от размера буфера.

Ну и? Вы о чём-то думаете, а пишете вещи, которые по меньшей мере вызывают вопросы (а не глупость ли это написана?) из-за отсутствия логической связи с конкретными постами. Для меня указатель есть принаддлежность языка Си, соответственно вольное обращение с предметом режет слух. Попробуйте прочитать сами место, где оно появилось http://electronix.ru/forum/index.php?showt...amp;st=33&#
Суть, о чём говорили, теперь понятна.


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
=GM=
сообщение Sep 3 2007, 20:45
Сообщение #42


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(alcosar @ Sep 3 2007, 19:33) *
2. Полный еще не значит переполненный.
3. Перед обращением к чтению нужно смотреть сколько байт в буфере.
Код
rdbyte: lds   xl,tail        ;указатель
        ldi   xh,high(buffer);на чтение

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

Ну как же, в переменной tail хранится младшая часть указателя, она загружается в xl. Для буфера объёмом меньшего или равного 256 байт, старшая часть указателя неизменна, это просто старшая часть начального адреса буфера, поэтому нет смысла её хранить, поэтому просто загружается константа в xh.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Sep 4 2007, 17:07
Сообщение #43


Гуру
******

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



Цитата(sensor_ua @ Sep 3 2007, 22:50) *
Ну и? Вы о чём-то думаете, а пишете вещи, которые по меньшей мере вызывают вопросы (а не глупость ли это написана?) из-за отсутствия логической связи с конкретными постами. Для меня указатель есть принаддлежность языка Си, соответственно вольное обращение с предметом режет слух.

smile.gif
Я говорил в общепринятых терминах в привязке к теме вопроса "кольцевой буфер". Про Си не думал, а думал про "указатель на голову" и "указатель на хвост", как обычно пишут. Реализация, естественно, может быть разной. Если исходить из начальных постов данной темы, где приводилось упрощённое использование коротких указателей (***) с маскированием и привязкой буферов к началу сегмента (в Си не требуется), то при реализации на Си более правильно назвать это индексом. По типу:
Код
  UDR0 = OutBuf[HeadOutBuf++];                            // Передаём    символ ответа
  HeadOutBuf &=0xf;                                        // Переход по кольцу


Если ввёл кого в заблуждение - прошу прощения. smile.gif
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 4 2007, 17:46
Сообщение #44


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
Если ввёл кого в заблуждение

Да всё путём. Просто "в наше время нельзя доверять никому"(С)wink.gif))

Кстати, вопрос общего плана - а как можно использовать количество данных в буфере (типа семафор или как) при приёме? Не могу найти практического примененияwink.gif


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Sep 4 2007, 18:06
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Люди, а как Вы синхронизируете скорости заполнения буфера и отправки от него?
Может что такое новое придумали? smile.gif

Поясняю. У меня циклический буфер для мониторинга процессов в терминале или PDA.
Есть моменты, когда буфер переполняется, так как идет интенсивная отправка данных. Буфер размером около 80 символов, больше выделить не могу. Я тупо ставлю Delay() после посылки каждой строки, чтобы в этих местах буфер не переполнился. Висеть в ожидании, пока там не освободится места, мне запрещает какая-то религия, не пойму какая 07.gif

Вы то как делаете?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post

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

 


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


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