-
Постов
1 462 -
Зарегистрирован
-
Посещение
-
Победитель дней
2
Сообщения, опубликованные esaulenka
-
-
Не взлетит :(
Запихать в 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; }
При попытке свернуть чтение в цикл получаем неплохие тормоза...
-
Уже второй день сижу, экспериментирую... Ну да ладно, пятница :)
Закономерности выявить не удалось.
При частоте ядра 48 и 36 МГц разница незначительная, а при снижении до 24 МГц задержка возрастает до 1,8 мкс.
uint8_t замените на uint_fast8_t да заинлайньте SendByteSPI.Сделал так, получил 0,9 мкс задержки.
Т.е. ждал бы прихода байта, а не IDLE состояния.И ещё одна десятая микросекунды в выигрыше. Почему, мне не ясно...
При выкидывании проверки вообще получаем промежуток между клоками 80 наносекунд. Только, разумеется, ничего не работает ;-)
А я бы проверял TNF и эту проверку на готовность к передаче поставил перед записью в DR.Идею не понял. А читаемые данные как достать? Там же FIFO, всё перепутается...
-
Почему же, заглядывал. Надо было сразу написать, что там ничего интересного не найдено.
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
-
Копаюсь с модулем SSP0 на контроллере LPC1111.
Частота камня - 48 МГц, частота SPI - 12 МГц, задержки между байтами 1,17 мкс.
Частота камня - 36 МГц, частота SPI - 18 МГц, задержки между байтами 1,23 мкс.
код простейший, никаких прерываний:
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; }
Сталкивался кто-нибудь?..
-
Хммм... Вот расскажите мне, как я всё починил? ;-)
По результатам очередных расчётов впаял R3 = 51k, C2 = 0.01u (обозначения на схеме в первом посте, остальные номиналы - оттуда же) - получил дикие пульсации и скачущий коэф.заполнения.
Попробовал собрать интегратор - добавил C1 = 0.01u, и получил образцово-показательные картинки: коэффициент заполнения строго равен расчётному 0.375, "иголки" пульсаций пропали...
Что это было и не выйдет ли это каким-то боком?
-
Вот, откопал тему:
http://electronix.ru/forum/index.php?showtopic=77598
очень рекомендую первую мысль defunct - получаются очень точные задержки. И думать не надо с подгоном пустых циклов. Таймер только тратится, но его же можно на прерывание пустить - главное, его не сбрасывать.
-
Как-то так:
C:\Program Files\SEGGER\JLinkARM_V426a\Doc\Manuals\UM08004_JLinkRDI.pdf
В четвёртом кейле этих RDI'ев стало несколько. Какой из них "правильный", я не знаю - старые проекты с третьего кейла мы не переносили.
-
Опубликовано · Изменено пользователем esaulenka · Пожаловаться
Проблему отложил из-за более срочных дел - пришлось спешно приводить софтварную часть в более-менее работоспособное состояние. Возвращаемся...
Коэффициент заполнения по-прежнему скачет. Что интересно, в теории получается 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 А (разницы не замечено) в разных масштабах:
На входе и выходе наблюдается "звон" от переключения. Что с этим делать, неясно, 20 мкФ керамики рядом с соответствующими электролитами не помогают... Вход и выход при нагрузке 1А, при уменьшении нагрузки пульсации снижаются:
Наверное, надо будет землю цифровой части отрезать от этого безобразия - она питается от второго маленького преобразователя 9->3.3 на MC34063, а силовой части придётся потерпеть :)
И вот ещё картинка на ноге обратной связи. При установке туда осциллографа (вроде б 1МОм и 11.5пФ сказываться не должны) коэффициенту заполнения совсем сносило крышу, и он начинал произвольно скакать...
-
У меня периодически (после обновлений) возникают танцы с бубном вокруг отладки ARM'а.
Попробуйте через RDI подключить dll'ку от сеггера, у меня получалось.
А вообще - возьмите кортекс, с его джитагом почему-то проблем не возникало ;-)
-
Ещё раз: про биты забываем, работаем с байтами.
Проверяем старший байт. Если там не ноль, значит, число ОЧЕНЬ большое, делаем, что нам надо.
Проверяем младший байт. Сравниваем с 106 и с 145, делаем, что надо. В чём затруднения-то?
-
Во-первых, старший байт проверять надо. Откуда уверенность, что там не появится единица? Помеха какая-то, например.
А во-вторых, совершенно не понял идеи разделять младший байт пополам. Берём его целиком (не думая, что там аж целых 8 бит!) и сравниваем...
upd: поправил опечатки
-
... 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-битное число ;-)
-
Допустим, что мы будем обновлять весь дисплей (1024 байта) раз в 1 сек.
В теории получается, что займёт это 1/1000 процессорного времени.
На практике, конечно, всё гораздо хуже. Но неужели жалко пары процентов?
-
Предлагаю посчитать, прежде чем городить "лишние AVR".
Максимальная частота шины - 1 МГц. Сколько байт в секунду планируется выводить? У меня подозрение, что большая часть затрат будет не в формировании строба, а в растеризации буковок.
-
На вскидку не понял, а SSEL там автоматом выставляется?
Насколько я понимаю, там SSEL выставляется для каждого байта (или ворда) в отдельности.
Куда такой режим может пригодится, я не знаю - всегда вручную чипселектом управлял.
-
Еще возник такой вопрос. SPI в LPC2103 позволяет передавать как 8 так и 16 бит. Можно ли переключаться "на горячую" между этими режимами? S0SPCR = 0x0824;//8 bit и S0SPCR = 0x0020;//16 bit так правильно? Спасибо.
У нас на 2138 так когда-то работало. Что будет в момент передачи, я не знаю, но в момент простоя SPI переключаться можно без проблем.
Только, кажется мне, тут с третьим битом ошибка, должно быть наоборот.
PS и если плата ещё не разведена, рекомендую посмотреть на SSP - тот же SPI, но пошустрее и с FIFO.
-
Есть массив
Используется он один раз при инициализации. Их таких одноразовых несколько. Нужно сделать так чтобы содержимое этих массивов не висело в ОЗУ и не занимало место бесцельно. Как это сделать?
А что, разве по умолчанию оно в ОЗУ? map-файл покажите.
У меня так получается, что линкер самостоятельно догадывается, что const надо во флеш класть...
И еще нужно настроить printf на вывод через usart0 LPC2103. Собственно usart0 настроил, а как чтоб в него посредством printf ? Спасибо.C:\Keil\ARM\Examples\Hello\
-
Рассказываю...
NCP3020B как-то очень странно себя вела на всех двух опытных экземплярах - один день стабильно запускается, другой день - нет.
В итоге поменял её на NCP3020A - всё то же самое, но частота преобразования вдвое меньше - 300 кГц. Запуск (вместе с увеличением токозадающего резистора) стал стабильный.
Греется она тоже слегка поменьше.
попробовать вместо нижнего ключа поставить 3-хамперный шотткиПоленился проверить, но теоретически - "не взлетит". Запитываться схема будет по-прежнему, через верхний транзистор, а что нижний управляющий выход будет болтаться в воздухе, разницы никакой...
Эффект этот не должен наблюдаться в схеме с P-канальным ключом, но всё переделывать больно лень...
Поставлю диод, они, оказывается, весьма дешёвые. Да и экономить энергию при наличии внешнего питания необязательно.
Другой вопрос.
Вот такой странный коэф. заполнения - это о чём свидетельствует?
-
Из этого можно попробовать сделать за день то, что я хотел.
Ну и на опечатки всё это добро оооочень желательно проверить.
В старых версиях CMSIS было несколько ошибок в LPC17xx.h - пропущены поля в структурах, в итоге регистры находились по неверным адресам.
Пока я догадался, что это не моя ошибка, прошло пол-дня...
-
Но вот незадача, скорость UART 115200, а частота МК 9216кГц. В результате я имею запас всего 80 тактов
Хочется заметить, что на приём байта (а не бита!) у Вас аж 800 тактов.
-
Подключил 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 в лице МТ-систем более вкусные цены предоставил ;-)
-
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/
-
А что не так с визардом? Это вы стартап "с галками" обсуждаете, или что-то другое?
Вроде бы вполне достаточно для начала. Да и для неначала лично у меня ничего лучшего не придумалось :)
Я, правда, с ST так и не работал, но стартап на первый взгляд там не сильно отличается от LPC.
-
создать Си файл в котором создать немеренный массив
Да нормально. У меня так в одну прошивку (стенда для программирования) вкомпилирована другая прошивка (собственно, изделия, для которого разработан стенд).
"Немеренный массив" делал специальной программкой на Си - читаем бинарник и printf'ами выгоняем отформатированный текст.
Также можно воспользоваться редактором HxD (у него есть экспорт в сишный файл) или утилитой SRecord.
По двум последним пунктам можно обращаться к гуглю, он знает ;-)
LPC1111, тормоза SPI
в ARM
Опубликовано · Пожаловаться
Неверно выразился. Сначала была комбинация из
А потом я второй цикл развернул, стало заметно быстрее.
В итоге: было 7 мкс, стало 4,5. С одной стороны - неплохо. А с другой - я два дня страдал фигнёй, ускорив первичную инициализацию аж на 30 миллисекунд. Всё остальное время обмен небольшой, пользователь потерпит.