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

 
 
> Циклический буфер на AVR, (Примеры применения)
=GM=
сообщение Aug 24 2007, 15:16
Сообщение #1


Ambidexter
*****

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



Тема открыта по горячим следам недавней острой дискуссии.

В ней одним из участников (defunct) была приведена программа, в которой использовался циклический буфер для работы с последовательным портом МК AT90S2313. На взгляд автора программа написана достаточно грамотно, но как-то слишком размашисто, без учёта мизерности ресурсов данного МК. Предлагаю участникам поделиться примерами и приёмами использования циклического буфера в программных разработках.

Для затравки предлагаю следующие фрагменты.

А. Запись байта из регистра AL в циклический буфер
Код
      mov     xl,qhead    ;указатель на запись
      st      x+,al       ;запишем байт
      cp      xl,qend     ;конец буфера?
      brne    .+2         ;нет, обходим
      ldi     xl,buffer   ;да, установим начало

Б. Чтение байта из циклического буфера в регистр AL
Код
      mov     xl,qtail    ;указатель на чтение
      ld      al,x+       ;прочитаем байт
      cp      xl,qend     ;конец буфера?
      brne    .+2         ;нет, обходим
      ldi     xl,buffer   ;да, установим начало

Если использовать буфер не произвольной длины, а кратный степени 2, и размещать его в памяти не произвольно, а начиная с адресов, кратных длине буфера, то размер кода можно немного сократить. Например.

В. Запись байта из регистра AL в циклический буфер длиной 32
Код
      mov     xl,qhead    ;указатель на запись
      st      x+,al       ;запишем байт
      cbr     xl,0xE0     ;держим указатель в предписанных рамках

Г. Чтение байта из циклического буфера длиной 32 в регистр AL
Код
      mov     xl,qtail    ;указатель на чтение
      ld      al,x+       ;прочитаем байт
      cbr     xl,0xE0     ;держим указатель в предписанных рамках

Здесь qhead, qtail, qend – регистровые переменные, содержащие адреса-указатели ячеек в озу для записи, чтения и конца буфера соответственно.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Guest_=AVR=_*
сообщение Aug 25 2007, 05:42
Сообщение #2





Guests






Такой метод (посредством урезания операцией "AND") организации кольцевых буферов с длиной и начальным адресом, кратными 2^N, весьма удобен и эффективен - недаром он широко применяется аж с 80-х годов. Эффективнее него - только аппаратные кольцевые буфера, реализованные в некоторых DSP, а также в dsPIC.

=GM= молодец - очень полезно время от времени напоминать широким массам о том, что Волга впадает именно в Каспийское море, а не в Северное smile.gif

Сообщение отредактировал =AVR= - Aug 25 2007, 06:01
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Aug 26 2007, 10:50
Сообщение #3


Гуру
******

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



Цитата(=AVR= @ Aug 25 2007, 08:42) *
Такой метод (посредством урезания операцией "AND") организации кольцевых буферов с длиной и начальным адресом, кратными 2^N, весьма удобен и эффективен - недаром он широко применяется аж с 80-х годов. Эффективнее него - только аппаратные кольцевые буфера, реализованные в некоторых DSP, а также в dsPIC.

=GM= молодец - очень полезно время от времени напоминать широким массам о том, что Волга впадает именно в Каспийское море, а не в Северное smile.gif


1) К сожалению не всегда применимо.
2) При написании программы - реализация кольцевого буфера - единицы %. Поэтому я за написание данного участка "размашисто". Зато нет необходимости лично контролировать размещение самого буфера.

Я тоже применял сначала такой метод. Кстати возможно автоматическое размещение буфера на границу по типу применяемой мной привязки таблицы данных

Код
    .cseg
    .org    (pc & $ff80)+$80


Приведу пример буфера несколько сложнее организованного

Код
;****************************************************************
;*   Вывод символа (wl) в буфер вывода. При выводе контроли-    *
;* руется заполнение буфера. При переполнении буфера вывод тор-    *
;* мозится, и подпрограмма не завершится, пока он не закончится.*
;*   Две точки входа: outwl и outwlsZ;                *
;*   Портятся tmph, Z.    (для outwl)                *
;*   Портятся tmph.    (для outwlsZ)                *
;****************************************************************

outwl:
    mov    tmph,    TBH
    sub    tmph,    TBE
    brcc    outw1
    subi    tmph,    -lBuf
outw1:    cpi    tmph,    2
    breq    outwl
    mov    Zl,    TBE
    ldi    ZH,    high(TxBuf)
    st    Z+,    wl
    cpi    Zl,    lBuf
    brne    outw2
    clr    Zl
outw2:    mov    TBE,    Zl
    ret


Приём

Код
;****************************************************************
;*         Прерывание на приём данных.            *
;*                                *
;*   Принятый байт размещается в кольцевом буфере RxBuf. Размер *
;* кольцевого буфера lBuf байт. В случае когда до заполнения     *
;* буфера осталось 16 байт снимается готовность модема. (Аппа-    *
;* ратным или програмным способом. При освобождении буфера на     *
;* половину готовность опять включается в голове.        *
;*   Используются регистры RBH и RBE как мл. байт адреса указа-    *
;* телей на голову и хвост буфера соответственно. Портятся ре-    *
;* гистр wp и регистровая пара X.                *
;* Максимальное время выполнения: 31 такт.            *
;****************************************************************

RxUART:
    in    tmpsreg,    sreg
    mov    Xl,    RBE; Поместить его в регистровую пару X
    clr    Xh
    in    wp,    udr; Прочитать принятый байт и
    st    X+,    wp; поместить его в буфер
    cpi    Xl,    RxBuf+lBuf; Конец буфера?
    brne    RxU1    ; если нет, то дальше
    ldi    Xl,    RxBuf; а иначе в начало буфера
RxU1:    mov    RBE,    Xl; и сохранить
    mov    Xl,    RBH; Определить объём свободного места
    sub    Xl,    RBE; в буфере
    brcc    RxU2
    subi    Xl,    -lBuf; Откорректировать при перехлёсте
RxU2:    cpi    Xl,    16; Осталось меньше 16 байт?
    brsh    RxUE    ; если нет, то выйти

    sbi    portd,    CTS; Сбросить готовность модема

RxUE:    lds    Xl,    s2
    cp    wp,    Xl
    brne    plclr
    tst    nplusC
    brne    plinc
    tst    ms20
    breq    plinc
plclr:    clr    nplusC
        rjmp    plset
plinc:    inc    nplusC
plset:    lds    ms20,    s12; сбросить задержку
    out    sreg,    tmpsreg
    reti


Это реализация старая 2003 года последние изменения. Сейчас вообще буфер большой. В байт не влазит. На мелочи не обращать внимание просто по живому вырезалось.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Aug 28 2007, 16:02
Сообщение #4


Ambidexter
*****

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



Привет всем! Отъезжал ненадолго, тут праздник местный был (summer bank holiday), теперь будем смотреть ответы и отвечать по мере сил-возможностей(:-)

1) To SasaVitebsk. Как всегда, приведен добротный код. Есть только мелкие вопросики. Фрагмент ниже непонятен, вроде бы надо буфер разместить в озу, а у вас стоит пзу.
Цитата(SasaVitebsk @ Aug 26 2007, 09:50) *
Кстати возможно автоматическое размещение буфера на границу по типу применяемой мной привязки таблицы данных
Код
    .cseg
    .org    (pc & $ff80)+$80

Трудно разобраться с передачей, метка outwl указана дважды, а метки outwlsZ нет вовсе.
Цитата(SasaVitebsk @ Aug 26 2007, 09:50) *
Код
;*   Две точки входа: outwl и outwlsZ;                *
;*   Портятся tmph, Z.    (для outwl)                *
;*   Портятся tmph.    (для outwlsZ)                *
;****************************************************************
outwl:    mov    tmph,    TBH
    sub    tmph,    TBE
    brcc    outw1
    subi    tmph,    -lBuf
outw1:    cpi    tmph,    2
    breq    outwl
    ret

2) Как обычно ничем не удивил и не порадовал широкоизвестный в узких кругах эникейщик =AVR=, вроде бы и похвалил, вроде бы и пожурил в одно и то же время, но что такое "аппаратные кольцевые буфера" и чем они отличаются от address mode осталось тайной(:-).


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


Гуру
******

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



Цитата(=GM= @ Aug 28 2007, 19:02) *
1) To SasaVitebsk. Как всегда, приведен добротный код. Есть только мелкие вопросики. Фрагмент ниже непонятен, вроде бы надо буфер разместить в озу, а у вас стоит пзу.

Да. Я так и написал. Просто вырвал кусочек использованный для объявления таблицы автоматически выровненной на границу. Что-нибудь подобное можно и для озу придумать. Чтобы вместо ORG. smile.gif
Цитата
Трудно разобраться с передачей, метка outwl указана дважды, а метки outwlsZ нет вовсе.

Метка outwl указана 1 раз и является вызываемой. Второй раз использована метка outw1. Просто на том шрифте этого не видно. Если текст перенесёте, то увидите. Написано это где-то в 1994-95 примерно. Я тогда так принял локальные метки изменять для себя 1,2,3... Короче что-то по типу символа "_" у defunct. Кстати применение символа "_" используется некоторыми компиляторами для организации локальных меток. Иногда при макросах также делается. Так что наезд на defunct некорректен. smile.gif Считаю его подход правильным. Просто когда я писал ещё не сложилось ничего (у меня). Да и вообще человек постоянно меняется оставаясь самим собой. Наверное было бы любопытно поболтать с собой самим лет 20 тому назад. Ну, безусловно избегая фраз типа: "придурок правее бери". biggrin.gif

А что не хватает, - так ведь выхвачено было по живому. Оно же там всё повязано. smile.gif Там нет ничего любопытного.

Код
;****************************************************************
;*   Вспомогательная. Выводит в буфер вывода цифру согласно би-    *
;* ту Т. Потом выводит "пробел".                *
;*   Портится tmph,wl и Z.                    *
;****************************************************************

outwlt:    clr    wl
    bld    wl,    0


;****************************************************************
;*   Вспомогательная. Выводит в буфер вывода цифру согласно ре-    *
;* гистра wl. Потом выводит "пробел".                *
;*   Портится tmph,wl и Z.                    *
;****************************************************************

outwlr:    andi    wl,    3
    ori    wl,    $30
    rcall    outwl
    ldi    wl,    $20


;****************************************************************
;*   Вывод символа (wl) в буфер вывода. При выводе контроли-    *
;* руется заполнение буфера. При переполнении буфера вывод тор-    *
;* мозится, и подпрограмма не завершится, пока он не закончится.*
;*   Две точки входа: outwl и outwlsZ;                *
;*   Портятся tmph, Z.    (для outwl)                *
;*   Портятся tmph.    (для outwlsZ)                *
;****************************************************************

outwl:
    mov    tmph,    TBH
    sub    tmph,    TBE
    brcc    outw1
    subi    tmph,    -lBuf
outw1:    cpi    tmph,    2
    breq    outwl
    mov    Zl,    TBE
    ldi    ZH,    high(TxBuf)
    st    Z+,    wl
    cpi    Zl,    lBuf
    brne    outw2
    clr    Zl
outw2:    mov    TBE,    Zl
    ret


outwlsZ:
    push    Zl
    push    Zh
    rcall    outwl
    pop    Zh
    pop    Zl
    ret
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- =GM=   Циклический буфер на AVR   Aug 24 2007, 15:16
- - defunct   Цитата(=GM= @ Aug 24 2007, 18:16) Если ис...   Aug 24 2007, 22:12
|- - WHALE   Цитата(=GM= @ Aug 28 2007, 20:02) Привет ...   Aug 28 2007, 18:33
||- - =GM=   Цитата(WHALE @ Aug 28 2007, 18:33) Господ...   Aug 28 2007, 22:33
|- - =AVR=   Аппаратные буфера отличаются от address mode тем ж...   Aug 28 2007, 20:21
- - sensor_ua   IMHO, обсуждение циклических буферов в привязке к ...   Aug 25 2007, 07:11
- - mse   Цитата(=GM= @ Aug 24 2007, 19:16) Код m...   Aug 25 2007, 07:48
- - adnega   Доброго дня! Мне вот очень интересно применен...   Aug 27 2007, 06:45
- - zltigo   Moderator: Так, оба двое и присоединившийся к ним ...   Aug 28 2007, 22:41
|- - =GM=   Цитата(zltigo @ Aug 28 2007, 22:41) Если ...   Aug 29 2007, 00:07
- - SasaVitebsk   2 AVR спасибо. До вашего варианта не додумался. Пр...   Aug 29 2007, 11:05
|- - =GM=   Цитата(SasaVitebsk @ Aug 29 2007, 10:05) ...   Aug 29 2007, 12:13
- - alcosar   Вот одна из возможных реализаций. Имеется индекс ...   Aug 31 2007, 12:37
|- - =GM=   Цитата(alcosar @ Aug 31 2007, 11:37) Код;...   Aug 31 2007, 15:12
|- - prottoss   Цитата(=GM= @ Aug 31 2007, 23:12) Пара...   Aug 31 2007, 16:53
||- - SasaVitebsk   Цитата(prottoss @ Aug 31 2007, 19:53) Пар...   Aug 31 2007, 18:37
||- - prottoss   Цитата(SasaVitebsk @ Sep 1 2007, 02:37) 1...   Aug 31 2007, 18:57
||- - SasaVitebsk   Цитата(prottoss @ Aug 31 2007, 21:57) В п...   Sep 3 2007, 14:31
|- - alcosar   [quote name='=GM=' date='Aug 31 2007, ...   Sep 2 2007, 18:55
- - sensor_ua   ЦитатаЦиклический буфер позволяет работать с макси...   Aug 31 2007, 19:56
|- - mse   Цитата(sensor_ua @ Aug 31 2007, 23:56) Вс...   Sep 1 2007, 07:03
|- - prottoss   Цитата(mse @ Sep 1 2007, 15:03) Практика ...   Sep 1 2007, 07:15
|- - mse   Цитата(prottoss @ Sep 1 2007, 11:15) Прак...   Sep 1 2007, 08:57
|- - prottoss   Цитата(mse @ Sep 1 2007, 16:57) Если загр...   Sep 1 2007, 09:02
|- - mse   Цитата(prottoss @ Sep 1 2007, 13:02) Ну В...   Sep 1 2007, 09:23
|- - =GM=   To alcosar 1) Здесь: std Y+1,r16 у вас ошибка, на...   Sep 3 2007, 11:54
|- - alcosar   Цитата(=GM= @ Sep 3 2007, 14:54) To alcos...   Sep 3 2007, 19:33
|- - =GM=   Цитата(alcosar @ Sep 3 2007, 19:33) 2. По...   Sep 3 2007, 20:45
- - sensor_ua   ЦитатаПочему нет ни единого примера на Си? Файл пр...   Sep 1 2007, 07:45
|- - zltigo   Цитата(sensor_ua @ Sep 1 2007, 10:45) Код...   Sep 1 2007, 08:36
- - prottoss   Выложу и я свое здесь, хоть уже и выкладывал в тем...   Sep 1 2007, 08:43
- - sensor_ua   ЦитатаНу хоть тэгами пользуйтесь для выделения исх...   Sep 1 2007, 09:03
- - sensor_ua   Цитата2. Размер указателей зависит от размера буфе...   Sep 3 2007, 15:03
|- - SasaVitebsk   Цитата(sensor_ua @ Sep 3 2007, 18:03) Про...   Sep 3 2007, 15:14
- - sensor_ua   ЦитатаЕстественно на стадии написания программы Ра...   Sep 3 2007, 17:51
|- - =GM=   Цитата(sensor_ua @ Sep 3 2007, 17:51) Ука...   Sep 3 2007, 19:25
|- - SasaVitebsk   Цитата(sensor_ua @ Sep 3 2007, 20:51) Рац...   Sep 3 2007, 19:33
- - sensor_ua   ЦитатаЧто вас смущает. Цитата2. Размер указателей ...   Sep 3 2007, 19:50
|- - SasaVitebsk   Цитата(sensor_ua @ Sep 3 2007, 22:50) Ну ...   Sep 4 2007, 17:07
- - sensor_ua   ЦитатаЕсли ввёл кого в заблуждение Да всё путём. П...   Sep 4 2007, 17:46
|- - Dog Pawlowa   Люди, а как Вы синхронизируете скорости заполнения...   Sep 4 2007, 18:06
|- - mse   Цитата(Dog Pawlowa @ Sep 4 2007, 22:06) Л...   Sep 4 2007, 18:39
|- - bodja74   Цитата(Dog Pawlowa @ Sep 4 2007, 21:06) Л...   Sep 4 2007, 20:46
|- - defunct   Цитата(Dog Pawlowa @ Sep 4 2007, 21:06) Л...   Sep 8 2007, 22:21
- - sensor_ua   ЦитатаВисеть в ожидании, пока там не освободится м...   Sep 4 2007, 18:44
- - Dog Pawlowa   Цитата(sensor_ua @ Sep 4 2007, 21:44) Дык...   Sep 5 2007, 05:03
- - sensor_ua   Цитата(Dog Pawlowa @ Sep 5 2007, 08:03) У...   Sep 5 2007, 06:33
- - Dog Pawlowa   Цитата(sensor_ua @ Sep 5 2007, 09:33) Исп...   Sep 5 2007, 07:19


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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 08:12
Рейтинг@Mail.ru


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