- Vote on answer
- posted
19 years ago
AVR vs PIC
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
AK>>> Не, два стека это такая фича для компилятора. С ними удобнее работать. AK>>> Причем AK>>> практически на любом чипе где такое возможно. GCC просто наследует AK>>> подход для х86-го. OR>> В общем да. В смысле gcc тоже не прав в некоторой мере, так как OR>> раздельные стеки данных и управления дают возможность делать OR>> некоторые вещи оптимальнее.
HZ> Ты имеешь в виду AVR или вообще? Если вообще, то не уточнишь, какие HZ> "некоторые вещи"? Вообще. Тот же IAR по -s9 очень эффективно делает глобальное по файлу выдёргивание похожих кусков в сгенерированные компилятором подпрограммы так лихо у меня как-то из нескольких функций, у которых были похожие локальные переменные и вызовы разных функций (read/write/verify) но с одинаковым в скобках - он всё формирование "кадра вызова" (запихивание в стек не влазящего в РОН аргумента в том числе) - оформил в виде отдельной процедурки. так вот так лихо -- в том числе благодаря отдельному стеку данных. Если бы call/ret дёргало стек данных, то у него бы это так хорошо не вышло
Что-то вызвать, не тронув вообще стек данных - это довольно удобно. И не только в форте :-)
wbr, p.s. другое дело, что два стека требуют двойного думанья про то, сколько выделить под стек... А переключение контекста -- одинаковое, для AVR хоть так, хоть так, а R29:R28 сохранять/восстанавливать.
- Vote on answer
- posted
19 years ago
AVM>> Hа AVR, даже на 8-ми битном таймере никаких потерь нет и быть не может. AVM>> Любые задержки (на вход в прерывание и выполнение команд) вычисляются AVM>> после пуска таймера/счетчика внешних событий путем выполнения некоторого AVM>> кол-ва команд с нужным кол-вом тактов и чтения таймера.
AG> Каким образом можно вычислить задержку на вход прерывание, когда прерываться AG> могут 1...4 тактовые команды?
Неизвестная в общем случае задержка будет. Но связанная не с задержкой входа в прерывание. В данной задаче эта задержка и до лампочки. Важна не она (лишь бы инкрементировался старший байт, а мискросекундой раньше, микросекундой позже - неважно), а влияние самого прерывания - "сворованные" такты у основной программы.
Задача ведь стоит как - сделать частотомер на предельно дешёвом микроконтроллере. Для этого достаточно одного 16-битного аппаратного счётчика, временной интервал накопления импульсов отсекаем программно, 16-битный таймер считает сам, "всё путём".
Если таймер 8-битный+расширение в прерывании, то заранее неизвестно, сколько раз прерывание нарушит программное отсечение интервала (это зависит от входной частоты) и будет ошибка в отработке опорного временного интервала.
AVR с 16-битным таймером за $1 нет. Есть за не больше $3 (mega8 сейчас в Виакоме штучно уже вроде дешевле, tiny2313 и mega48 не считаю, я лично её ещё не видел, а меги8 валом).
Итого получаем удорожание частотомера на $2 + "лишний" прескалер (доводящий частоту счёта до 50-70MHz) не больше $0.4 + небольшое увеличение размера (и цены) платы (что там того SOIC-а), + за пайку придётся больше заплатить (лишние ноги меги+счётчик). В сумме удорожание не больше $3. На какой цене? Это серийный прибор?
Однако можно и поисхитряться :-) Потом можно ведь по значению софтового расширения можно посчитать сколько раз мы "удлиннили" время (длительность обработчика прерывания фиксирована) и пересчитать частоту.
Это "лобовой" метод.
Однако можно и подумать. Никаких вообще прерываний. Зачем они в *этой* задаче?
ldi r16, 1<<TOV0 ; заносим маску с 1 в бите переполнения timer0 clr r17 ; расширение счётчика out TCCR0,r17 ; останавливаем счётчик out TCNT0,r17 ; обнуляем счётчик. out TIFR0,r16 ; очищаем флаг переполнения счётчика, мало ли что ; там было ldi r24,low(count_time) ; count_time - время в микросекундах ldi r25,high(count_time) ldi r18,6 ; счётчик считает по фронтам clr r19 ; этим будем останавливать счётчик
out TCCR0,r18 ; запустили счётчик
loop: in r18,TIFR0 ; 1 sbrc r18,TOV0 ; 1/2 ; переполнился - out TIFR0,r16 ; 1/0 ; сбросили флаг sbrc r18,TOV0 ; 1/2 inc r17 ; 1/0 ; и увеличили старшую часть nop ; 1 ; подравниваем до 10 тактов sbiw r24,1 ; 2 brne loop ; 2 ; 1мкс цикл @ 10MHz
out TCCR0,r19 ; остановили счётчик
in r18,TIFR0 ; переполнение могло случится между последним sbrc r18,TOV0 ; in r18,... в цикле и остановкой счётчика inc r17
in r16,TCNT0 ; r17:r16 - число импульсов внешней частоты.
Всё. Задача посчитать в 16-битном счётчике число импульсов внешней частоты за программно отсечённый временной интервал при наличии всего лишь 8-битного аппаратного счётчика решена. Если надо не 16 бит, а 24 - добавляем ещё байт программного расширения и подравниваем ветви, хоть бы и так: sbrc r18,TOV0 ; 1/2 adiw r26,1 ; 2/0 sbrs r18,TOV0 ; 2/1 rjmp $+2 ; 0/2 Придётся ещё время цикла довести до удобного и count_time пересчитать.
Берём самый дешёвый устраивающий AVR и делаем частотомер. Если на 50MHz, то будет дороже pic-овского фактически на дополнительный
74ac161 (при 10MHz AVR) или 74ac4040 (при более медленном) и его площадь платы/пайку. Ну может ещё сам tiny12 будет дороже pic12f629. В сумме $1 может наберётся, может и нет.WBR,
- Vote on answer
- posted
19 years ago
OR>> Даёшь *((volatile unsigned short*)0177700) = 0; !
AD> Искуситель!!! :-)
OR>> равно не будет кусков программы, где надо сразу со всей периферией OR>> работать.
AD> Дык не хочется отдавать Y под это. И медленней будет - с косвенной-то AD> адресацией. Взамен я полагаю - выйдет сделать *четыре* регистровых пары. Т.е. заняв одну из них намертво - получим то, что сейчас.
AD> Не соглашусь. Придётся всё время играть базовым регистром, хочешь ты AD> этого или нет. Да и Y'ка жа-алко :-). Если быстродействия хватает, то В мелких программах (когда рабта почти столько с портами) - не жалко отдать указатель на постоянку. В мелких контроллерах -- всё влезет в одно окно. Потерать немножко быстродействия в работе с IO я не считаю страшным. Быстро ножками махать должна аппаратура.
AD> Да ладно с этими окнами! Зато можно будет написать class Timer и AD> передавать ему this ! :-))) И это в том числе. Если таймеры ещё сделать "однотипно" (ну я там говорил про размещение битов флагов и разрешений прерываний - вот у всех таймеров то, что у них одинаково -- должно быть на одинаоквых смещениях от базы и в одинаковых битах!) -- так это будет одно удовольствие. Сосбтвенно, биты IE и IF *всех* периферийных устройств должны в их CSR стоять на одинаковых местах :-)
wbr,
- Vote on answer
- posted
19 years ago
Добрый день.
А что, если возникает прерывание, то команда до конца не выполняется и прерывается на середине? Или в конце, после запрета прерываний трудно подсчитать их (прерываний) кол-во и скорректировать конечный результат? Или надо точно знать кол-во тактов до возникновения прерывания? Ответ лежит в стеке.
Или я вопрос не понял? Уж больно он простой... 8-)
- Vote on answer
- posted
19 years ago
Здравствуйте.
AK>>>> Чего ??? Ты хоть знаешь о чем говоришь ? GS>>> Значительно лучше тебя! GS>>> Изобрази выдачу двух противофазных меандров на ножках порта. GS>>> Вот соответствующий код для PIC. AK>> - Мальчик, как тебя зовут? AK>> - ... AK>> - Ты что, тормоз? AK>> - Меня зовут Эдик. AK>> - А фамилия? AK>> - Hет, не тормоз. GS> Понимаешь, я-ж не виноват, что ты тормоз...
Понимаешь, я привык аргументированно отвечать за свои слова. Ты же видимо не обучен.
GS>>> MOVLW 01b GS>>> MOVWF PORTx ; инициализация порта "противофазными" битами GS>>> MOVLW 11b ; модифицируемые биты GS>>> loop1: GS>>> XORWF PORTx,1 ; модификация с прямым доступом к порту GS>>> ; 1 цикл GS>>> GOTO loop1 ; 2 цикла AK>> А теперь давай по существу. GS> Даже не попытаешься сделать это-же на AVR? Такой ведь хороший GS> процессор, а не может сделать простенькую задачку...
Понятия не имею, что ты хочешь получить и зачем это нужно. Причем здесь "противофазные биты" ? Я всего лишь задал вопрос: почему область SRAM напрямую недоступна ?
AK>> Так бОльшая часть чего в AVR недоступна ? GS> Абсолютно все порты напрямую недоступны.
Смотри команды lds/sts. _Все_ порты отображены в адресную область внутренней SRAM. Все линейно и без дебильного переключения страниц.
GS> Область SRAM напрямую недоступна. GS> Работать с ними приходится через "игольное ушко" РОH.
В пике это ушко конечно же шире ? Давай, скажи это.
GS> Это давным-давно поняли все, кроме законченных тормозов. AK>> Что касается меандров - мне они абсолютно без надобности. GS> Любимый сюжет AVR-манов - "лиса и виноград" ;-)
Объясни, как это относится к предмету обсуждения ? Или у тебя автобредогенератор опять включился
- Vote on answer
- posted
19 years ago
RA>>>> У меня на 2х ножках и 2х таймерах получилось. GS>>> Ужас какой! 1 таймер, 1 ножка. Прекрасно формируется на 16F874. GS>>> При желании сэкономить берётся дешёвый 16F818. RA>> Угу. Покажи, как сделал? Особенно момент суммирования 2х частот ;-)
GS> А до этого места всё понятно? Очень хорошо, вот тебе с момента суммирования, GS> и до выдачи в регистры PWM. Только программка на макросах, впрочем,
Я так и думал. На ШИМе любой сделает. Только что делать, если он уже занят? Ты попробуй именно на 1й ноге и на 1м таймере ;-)
RA>>>> Я что-то подобное твоей задаче вначале сделал на 877м. Потом RA>>>> перешел RA>>>> на 18е - и вздохнул с облегчением. Попробуй - понравится ;-) GS>>> Мне _вполне_ хватает 16-го семейства. Опыт ;) RA>> Иди дальше.
GS> Hе раньше, чем у меня появятся задачи, нерешаемые на 16-м семействе. GS> За это время как раз окончательно "вылижут" глюки, встречавшиеся в первых GS> флэшевых контроллерах 18-го семейства...
Да их давно вылизали. Чего ждать? Поверь - переход с 16х на 18е произойдет очень быстро - у тебя весь код сильно упростится. Не недо щелкать банками/страницами, есть команды прямой адресации (movff), табличные операции и пр. Тем более ты на асме прогаешь. По ценам - мне просто непонятно, как на стоимости изделия в 100-200$ (продажной) сыграет разница в стоимости проца на 3-5$? Как вообще можно работать с уровнем рентабельности порядка процентов, чтобы при этом любое незначительное увеличение стоимости переводило рентабельность этого изделия в убыток? Еще надо учесть, что применение более совершенного проца в большинстве случаев упрощает схемотехнику - вот здесь и отыграть на разнице в цене проца можно. Ну а если изделие конкурентноспособно, т.е. заведомо более покупабельно, чем от других производителей, ну увеличь стоимость на 5$ - все равно будут брать - при нормальном маркетинге покупатель с радостью это воспримет - если правильно подать ("светодиод ярче стал светиться и пр ;-)")
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago