Перейти к содержанию
    

esaulenka

Свой
  • Постов

    1 462
  • Зарегистрирован

  • Посещение

  • Победитель дней

    2

Сообщения, опубликованные esaulenka


  1. Неверно выразился. Сначала была комбинация из

    while (LPC_SSP0->SR & BIT(4));
    while(LPC_SSP0->SR & (1<<2))
       ucByteReadMem=LPC_SSP0->DR;

    А потом я второй цикл развернул, стало заметно быстрее.

     

    В итоге: было 7 мкс, стало 4,5. С одной стороны - неплохо. А с другой - я два дня страдал фигнёй, ускорив первичную инициализацию аж на 30 миллисекунд. Всё остальное время обмен небольшой, пользователь потерпит.

  2. Не взлетит :(

    Запихать в FIFO 5 байт получается быстрее, чем он их передаёт. Соответственно, переходим к циклу выгребания, и возвращаем какой-то неверный байт.

     

    Но за идею спасибо, в итоге закончилось следующим:

    uint8_t Mem_ReadByte( uint32_t aunMemAddr )
    {
        ACTIVE_SPI();
        LPC_SSP0->DR = 0x03;
        LPC_SSP0->DR = aunMemAddr >> 16;
        LPC_SSP0->DR = aunMemAddr >> 8;
        LPC_SSP0->DR = aunMemAddr;
        LPC_SSP0->DR = 0;
        while (LPC_SSP0->SR & BIT(4));
        DEACTIVE_SPI();    
        LPC_SSP0->DR;
        LPC_SSP0->DR;
        LPC_SSP0->DR;
        LPC_SSP0->DR;
        return     LPC_SSP0->DR;
    }

     

    При попытке свернуть чтение в цикл получаем неплохие тормоза...

  3. Уже второй день сижу, экспериментирую... Ну да ладно, пятница :)

     

    Закономерности выявить не удалось.

    При частоте ядра 48 и 36 МГц разница незначительная, а при снижении до 24 МГц задержка возрастает до 1,8 мкс.

     

    uint8_t замените на uint_fast8_t да заинлайньте SendByteSPI.

    Сделал так, получил 0,9 мкс задержки.

     

    Т.е. ждал бы прихода байта, а не IDLE состояния.

    И ещё одна десятая микросекунды в выигрыше. Почему, мне не ясно...

     

     

    При выкидывании проверки вообще получаем промежуток между клоками 80 наносекунд. Только, разумеется, ничего не работает ;-)

     

     

    А я бы проверял TNF и эту проверку на готовность к передаче поставил перед записью в DR.

    Идею не понял. А читаемые данные как достать? Там же FIFO, всё перепутается...

     

  4. Почему же, заглядывал. Надо было сразу написать, что там ничего интересного не найдено.

     

                      SendByteSPI PROC
    ;;;47     uint8_t SendByteSPI( uint8_t data)
    000000  4903              LDR      r1,|L2.16|
    ;;;48     {
    ;;;49         LPC_SSP0->DR = data;
    000002  6088              STR      r0,[r1,#8]
                      |L2.4|
    ;;;52         while( LPC_SSP0->SR & BIT(4) )
    000004  68c8              LDR      r0,[r1,#0xc]
    000006  06c0              LSLS     r0,r0,#27
    000008  d4fc              BMI      |L2.4|
    ;;;53         ;
    ;;;59         return LPC_SSP0->DR;
    00000a  6888              LDR      r0,[r1,#8]
    00000c  b2c0              UXTB     r0,r0
    ;;;60     }
    00000e  4770              BX       lr
                              ENDP
                      |L2.16|
                              DCD      0x40040000

     

                      Mem_ReadByte PROC
    ;;;171    // 
    ;;;172    uint8_t Mem_ReadByte( uint32_t aunMemAddr )
    000000  b5f8              PUSH     {r3-r7,lr}
    ;;;173    {
    ;;;174        uint8_t        ucByteReadMem;
    ;;;175        
    ;;;176        ACTIVE_SPI();
    000002  2405              MOVS     r4,#5
    000004  4e0d              LDR      r6,|L6.60|
    000006  0724              LSLS     r4,r4,#28
    000008  4605              MOV      r5,r0                ;173
    00000a  6126              STR      r6,[r4,#0x10]
    00000c  6126              STR      r6,[r4,#0x10]
    00000e  2700              MOVS     r7,#0
    000010  6127              STR      r7,[r4,#0x10]
    ;;;177    
    ;;;178        SPI_WriteByte( 0x03 );            // Read Data Bytes
    000012  2003              MOVS     r0,#3
    000014  f7fffffe          BL       SendByteSPI
    ;;;179        SPI_WriteByte( (uint8_t)(aunMemAddr >> 16 ) );
    000018  0228              LSLS     r0,r5,#8
    00001a  0e00              LSRS     r0,r0,#24
    00001c  f7fffffe          BL       SendByteSPI
    ;;;180        SPI_WriteByte( (uint8_t)(aunMemAddr >> 8 ) );
    000020  0428              LSLS     r0,r5,#16
    000022  0e00              LSRS     r0,r0,#24
    000024  f7fffffe          BL       SendByteSPI
    ;;;181        SPI_WriteByte( (uint8_t)(aunMemAddr ) );
    000028  b2e8              UXTB     r0,r5
    00002a  f7fffffe          BL       SendByteSPI
    ;;;182        ucByteReadMem    = SPI_ReadByte();
    00002e  2000              MOVS     r0,#0
    000030  f7fffffe          BL       SendByteSPI
    ;;;183    
    ;;;184        DEACTIVE_SPI();    
    000034  6127              STR      r7,[r4,#0x10]
    000036  6126              STR      r6,[r4,#0x10]
    ;;;185        
    ;;;186        return ucByteReadMem;
    ;;;187    }
    000038  bdf8              POP      {r3-r7,pc}
    ;;;188    
                              ENDP

  5. Копаюсь с модулем SSP0 на контроллере LPC1111.

     

     

    Частота камня - 48 МГц, частота SPI - 12 МГц, задержки между байтами 1,17 мкс.

    post-35877-1322754246_thumb.png

     

     

    Частота камня - 36 МГц, частота SPI - 18 МГц, задержки между байтами 1,23 мкс.

    post-35877-1322754251_thumb.png

     

     

     

    код простейший, никаких прерываний:

    uint8_t SendByteSPI( uint8_t data)
    {
        LPC_SSP0->DR = data;
        while( LPC_SSP0->SR & BIT(4) )    // SPI0 busy
        ;
        return LPC_SSP0->DR;
    }
    
    #define SPI_WriteByte(data)        SendByteSPI(data)
    #define SPI_ReadByte()            SendByteSPI(0x00)
    
    uint8_t Mem_ReadByte( uint32_t aunMemAddr )
    {
        uint8_t        ucByteReadMem;
        ACTIVE_SPI();
        SPI_WriteByte( 0x03 );            // Read Data Bytes
        SPI_WriteByte( (uint8_t)(aunMemAddr >> 16 ) );
        SPI_WriteByte( (uint8_t)(aunMemAddr >> 8 ) );
        SPI_WriteByte( (uint8_t)(aunMemAddr ) );
        ucByteReadMem    = SPI_ReadByte();
        DEACTIVE_SPI();    
        return ucByteReadMem;
    }

     

    Сталкивался кто-нибудь?..

  6. Хммм... Вот расскажите мне, как я всё починил? ;-)

     

    По результатам очередных расчётов впаял R3 = 51k, C2 = 0.01u (обозначения на схеме в первом посте, остальные номиналы - оттуда же) - получил дикие пульсации и скачущий коэф.заполнения.

     

    Попробовал собрать интегратор - добавил C1 = 0.01u, и получил образцово-показательные картинки: коэффициент заполнения строго равен расчётному 0.375, "иголки" пульсаций пропали...

     

    Что это было и не выйдет ли это каким-то боком?

  7. Вот, откопал тему:

    http://electronix.ru/forum/index.php?showtopic=77598

     

    очень рекомендую первую мысль defunct - получаются очень точные задержки. И думать не надо с подгоном пустых циклов. Таймер только тратится, но его же можно на прерывание пустить - главное, его не сбрасывать.

  8. Проблему отложил из-за более срочных дел - пришлось спешно приводить софтварную часть в более-менее работоспособное состояние. Возвращаемся...

     

     

    Коэффициент заполнения по-прежнему скачет. Что интересно, в теории получается 0,38, а на практике два значения - 0,23 и 0,85. В документации минимум 7%, максимум 84%, т.е. действительно срабатывает ограничение сверху.

     

    Посчитал ток через дроссель по следующей формуле: dI = 1/L * U * dt.

    Для "коротких" Ton получилось 0,35 А, для "длинных" - 1,3 А, для "коротких" Toff - 0,7 А.

    Т.е. при нагрузке в пару ампер попадаем точно в режим непрерывного тока.

     

    Пробовал крутить цепочку коррекции (уже просто наобум, расчётные значения не помогают) - никаких изменений не отмечено. Изменение выходного конденсатора (low ESR Nippon, безродный Chang, безродный Chang + керамика) также не влияет.

     

    Вход дросселя, нагрузка 1..2 А (разницы не замечено) в разных масштабах:

    post-35877-1322488005_thumb.png post-35877-1322488053_thumb.png

     

    На входе и выходе наблюдается "звон" от переключения. Что с этим делать, неясно, 20 мкФ керамики рядом с соответствующими электролитами не помогают... Вход и выход при нагрузке 1А, при уменьшении нагрузки пульсации снижаются:

    post-35877-1322488140_thumb.png post-35877-1322488177_thumb.png

    Наверное, надо будет землю цифровой части отрезать от этого безобразия - она питается от второго маленького преобразователя 9->3.3 на MC34063, а силовой части придётся потерпеть :)

     

    И вот ещё картинка на ноге обратной связи. При установке туда осциллографа (вроде б 1МОм и 11.5пФ сказываться не должны) коэффициенту заполнения совсем сносило крышу, и он начинал произвольно скакать...

    post-35877-1322493460_thumb.png

  9. У меня периодически (после обновлений) возникают танцы с бубном вокруг отладки ARM'а.

    Попробуйте через RDI подключить dll'ку от сеггера, у меня получалось.

     

    А вообще - возьмите кортекс, с его джитагом почему-то проблем не возникало ;-)

  10. Ещё раз: про биты забываем, работаем с байтами.

    Проверяем старший байт. Если там не ноль, значит, число ОЧЕНЬ большое, делаем, что нам надо.

    Проверяем младший байт. Сравниваем с 106 и с 145, делаем, что надо. В чём затруднения-то?

  11. Во-первых, старший байт проверять надо. Откуда уверенность, что там не появится единица? Помеха какая-то, например.

     

    А во-вторых, совершенно не понял идеи разделять младший байт пополам. Берём его целиком (не думая, что там аж целых 8 бит!) и сравниваем...

     

     

    upd: поправил опечатки

  12. ... PIC16F877...

    АЦП меряет все время напряжение и заносит результат в регистры (AdresL) и (AdresH), только я не пойму если АЦП 10-разрядное (десятичное число выглядит как 1023) то как записывается туда результат.

    Об этом вполне доступно написано в документации ( http://ww1.microchip.com/downloads/en/devicedoc/30292c.pdf ).

    Если в регистре ADCON1 7-й бит - единичка, результат выравнивается вправо:

    ADRESH ADRESL

    000000xx xxxxxxxx

    если наоборот, 7-й бит - ноль, результат выравнивается влево:

    ADRESH ADRESL

    xxxxxxxx xx000000

     

    ...если результат измерения меньше числа .106, то ...

    Есть много вариантов. Самый простой вариант - предположим, что АЦП 8-битное. Тогда и результат, и граничные значения влезают в регистр, с ними удобно работать. Для этого надо выровнять результат влево и пользоваться только ADRESH, игнорируя младшие биты в ADRESL.

     

    Второй вариант - рассматривать надо обе "половинки" числа. Ассембер пиков я тоже крайний раз видел в институте, поэтому только в общих словах:

    берём старшие части результата и границы; получаем три (в общем случае) варианта

    - старшая часть результата больше. Значит, весь результат тоже больше границы

    - старшая часть результата меньше. Соответственно, всё значение также меньше границы.

    - старшие части равны. Надо рассматривать младшие части, там тоже будет три варианта.

    Для этого алгоритма, мне кажется, удобнее выравнивать результат АЦП вправо.

     

    PS а самое удобное - доверить компилятору Си "склеить" эти результаты в одно 16-битное число ;-)

  13. Допустим, что мы будем обновлять весь дисплей (1024 байта) раз в 1 сек.

    В теории получается, что займёт это 1/1000 процессорного времени.

     

    На практике, конечно, всё гораздо хуже. Но неужели жалко пары процентов?

  14. Предлагаю посчитать, прежде чем городить "лишние AVR".

    Максимальная частота шины - 1 МГц. Сколько байт в секунду планируется выводить? У меня подозрение, что большая часть затрат будет не в формировании строба, а в растеризации буковок.

  15. На вскидку не понял, а SSEL там автоматом выставляется?

    Насколько я понимаю, там SSEL выставляется для каждого байта (или ворда) в отдельности.

    Куда такой режим может пригодится, я не знаю - всегда вручную чипселектом управлял.

  16. Еще возник такой вопрос. SPI в LPC2103 позволяет передавать как 8 так и 16 бит. Можно ли переключаться "на горячую" между этими режимами? S0SPCR = 0x0824;//8 bit и S0SPCR = 0x0020;//16 bit так правильно? Спасибо.

     

    У нас на 2138 так когда-то работало. Что будет в момент передачи, я не знаю, но в момент простоя SPI переключаться можно без проблем.

    Только, кажется мне, тут с третьим битом ошибка, должно быть наоборот.

     

     

    PS и если плата ещё не разведена, рекомендую посмотреть на SSP - тот же SPI, но пошустрее и с FIFO.

  17. Есть массив

    Используется он один раз при инициализации. Их таких одноразовых несколько. Нужно сделать так чтобы содержимое этих массивов не висело в ОЗУ и не занимало место бесцельно. Как это сделать?

    А что, разве по умолчанию оно в ОЗУ? map-файл покажите.

    У меня так получается, что линкер самостоятельно догадывается, что const надо во флеш класть...

     

     

    И еще нужно настроить printf на вывод через usart0 LPC2103. Собственно usart0 настроил, а как чтоб в него посредством printf ? Спасибо.

    C:\Keil\ARM\Examples\Hello\

  18. Рассказываю...

     

    NCP3020B как-то очень странно себя вела на всех двух опытных экземплярах - один день стабильно запускается, другой день - нет.

    В итоге поменял её на NCP3020A - всё то же самое, но частота преобразования вдвое меньше - 300 кГц. Запуск (вместе с увеличением токозадающего резистора) стал стабильный.

    Греется она тоже слегка поменьше.

     

    попробовать вместо нижнего ключа поставить 3-хамперный шоттки

    Поленился проверить, но теоретически - "не взлетит". Запитываться схема будет по-прежнему, через верхний транзистор, а что нижний управляющий выход будет болтаться в воздухе, разницы никакой...

    Эффект этот не должен наблюдаться в схеме с P-канальным ключом, но всё переделывать больно лень...

    Поставлю диод, они, оказывается, весьма дешёвые. Да и экономить энергию при наличии внешнего питания необязательно.

     

    Другой вопрос.

    Вот такой странный коэф. заполнения - это о чём свидетельствует?

    post-35877-1321020968_thumb.png - нагрузка 1 А

    post-35877-1321021384_thumb.png - нагрузка единицы мА.

  19. Из этого можно попробовать сделать за день то, что я хотел.

     

    Ну и на опечатки всё это добро оооочень желательно проверить.

     

    В старых версиях CMSIS было несколько ошибок в LPC17xx.h - пропущены поля в структурах, в итоге регистры находились по неверным адресам.

    Пока я догадался, что это не моя ошибка, прошло пол-дня...

  20. Но вот незадача, скорость UART 115200, а частота МК 9216кГц. В результате я имею запас всего 80 тактов

     

    Хочется заметить, что на приём байта (а не бита!) у Вас аж 800 тактов.

  21. Подключил system_stm32f10x.c, но появилась другая ошибка:

    D:\Keil\ARM\INC\ST\STM32F10x\stm32f10x.h(80): error: #35: #error directive: "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"

    Target not created

     

    Адский ад эти ваши STM32!

     

    Почитайте этот stm32f10x.h в районе 45-й строки, должно помочь.

     

     

    PS статья "STM32 для самых маленьких" :)

    http://we.easyelectronics.ru/STM32/stm32-v...ogo-starta.html

     

    PPS сам я с этим контроллером не работал. Нам NXP в лице МТ-систем более вкусные цены предоставил ;-)

  22. prj2.axf: Error: L6218E: Undefined symbol SystemInit (referred from startup_stm32f10x_md.o).

    Target not created

    Надо подключить ещё и C:\Keil\ARM\Startup\ST\STM32F10x\system_stm32f10x.c

    Желательно скопировать этот файл к себе в проект и подключать уже его - всё-таки это не библиотека, а некий черновик кода инициализации.

     

    Ну а вообще этот вопрос легко решается, например, поиском слова "SystemInit" по всем исходникам в каталоге кейла.

     

    Первая же ссылка в гугле: http://www.keil.com/forum/18804/

  23. А что не так с визардом? Это вы стартап "с галками" обсуждаете, или что-то другое?

    Вроде бы вполне достаточно для начала. Да и для неначала лично у меня ничего лучшего не придумалось :)

     

    Я, правда, с ST так и не работал, но стартап на первый взгляд там не сильно отличается от LPC.

  24. создать Си файл в котором создать немеренный массив

     

    Да нормально. У меня так в одну прошивку (стенда для программирования) вкомпилирована другая прошивка (собственно, изделия, для которого разработан стенд).

     

    "Немеренный массив" делал специальной программкой на Си - читаем бинарник и printf'ами выгоняем отформатированный текст.

    Также можно воспользоваться редактором HxD (у него есть экспорт в сишный файл) или утилитой SRecord.

     

    По двум последним пунктам можно обращаться к гуглю, он знает ;-)

×
×
  • Создать...